From 45feb605f2f15615011d0e8aaa8a464308305b1d Mon Sep 17 00:00:00 2001 From: William Escande Date: Fri, 31 May 2024 11:54:27 -0700 Subject: [PATCH 1/3] Reformat java file in android/leaudio Bug: 311772251 Flag: Exempt refactor Test: None Change-Id: Ie7fe7f0a1b626045770d7de875036f5a64008b6e --- .../bluetooth/leaudio/BluetoothProxy.java | 1399 +++++---- .../leaudio/BroadcastItemsAdapter.java | 35 +- .../leaudio/BroadcastScanActivity.java | 281 +- .../leaudio/BroadcastScanViewModel.java | 118 +- .../leaudio/BroadcasterActivity.java | 123 +- .../leaudio/BroadcasterViewModel.java | 9 +- .../leaudio/LeAudioDeviceStateWrapper.java | 154 +- .../leaudio/LeAudioRecycleViewAdapter.java | 2537 ++++++++++------- .../bluetooth/leaudio/LeAudioViewModel.java | 15 +- .../bluetooth/leaudio/MainActivity.java | 387 ++- .../ehima/leaudio/ExampleUnitTest.java | 2 +- 11 files changed, 2926 insertions(+), 2134 deletions(-) diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BluetoothProxy.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BluetoothProxy.java index 13ed9ad41e2..9d73979c5a8 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BluetoothProxy.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BluetoothProxy.java @@ -76,214 +76,271 @@ public class BluetoothProxy { private boolean mLeAudioCallbackRegistered = false; private BluetoothLeAudio.Callback mLeAudioCallbacks = - new BluetoothLeAudio.Callback() { - @Override - public void onCodecConfigChanged(int groupId, BluetoothLeAudioCodecStatus status) {} - @Override - public void onGroupStatusChanged(int groupId, int groupStatus) { - List valid_devices = null; - valid_devices = allLeAudioDevicesMutable.getValue().stream().filter( - state -> state.leAudioData.nodeStatusMutable.getValue() != null - && state.leAudioData.nodeStatusMutable.getValue().first - .equals(groupId)) - .collect(Collectors.toList()); - for (LeAudioDeviceStateWrapper dev : valid_devices) { - dev.leAudioData.groupStatusMutable.postValue( - new Pair<>(groupId, new Pair<>(groupStatus, 0))); - } - } - @Override - public void onGroupNodeAdded(BluetoothDevice device, int groupId) { - Log.d("LeCB:", device + " group added " + groupId); - if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { - Log.d("LeCB:", "invalid parameter"); - return; - } - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); + new BluetoothLeAudio.Callback() { + @Override + public void onCodecConfigChanged(int groupId, BluetoothLeAudioCodecStatus status) {} - if (!valid_device_opt.isPresent()) { - Log.d("LeCB:", "Device not present"); - return; - } + @Override + public void onGroupStatusChanged(int groupId, int groupStatus) { + List valid_devices = null; + valid_devices = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.leAudioData.nodeStatusMutable.getValue() + != null + && state.leAudioData + .nodeStatusMutable + .getValue() + .first + .equals(groupId)) + .collect(Collectors.toList()); + for (LeAudioDeviceStateWrapper dev : valid_devices) { + dev.leAudioData.groupStatusMutable.postValue( + new Pair<>(groupId, new Pair<>(groupStatus, 0))); + } + } - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.LeAudioData svc_data = valid_device.leAudioData; + @Override + public void onGroupNodeAdded(BluetoothDevice device, int groupId) { + Log.d("LeCB:", device + " group added " + groupId); + if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { + Log.d("LeCB:", "invalid parameter"); + return; + } + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); + + if (!valid_device_opt.isPresent()) { + Log.d("LeCB:", "Device not present"); + return; + } - svc_data.nodeStatusMutable.postValue(new Pair<>(groupId, GROUP_NODE_ADDED)); - svc_data.groupStatusMutable.postValue(new Pair<>(groupId, new Pair<>(-1, -1))); - } - @Override - public void onGroupNodeRemoved(BluetoothDevice device, int groupId) { - if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { - Log.d("LeCB:", "invalid parameter"); - return; - } + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.LeAudioData svc_data = valid_device.leAudioData; - Log.d("LeCB:", device + " group added " + groupId); - if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { - Log.d("LeCB:", "invalid parameter"); - return; - } + svc_data.nodeStatusMutable.postValue(new Pair<>(groupId, GROUP_NODE_ADDED)); + svc_data.groupStatusMutable.postValue(new Pair<>(groupId, new Pair<>(-1, -1))); + } - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); + @Override + public void onGroupNodeRemoved(BluetoothDevice device, int groupId) { + if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { + Log.d("LeCB:", "invalid parameter"); + return; + } - if (!valid_device_opt.isPresent()) { - Log.d("LeCB:", "Device not present"); - return; - } + Log.d("LeCB:", device + " group added " + groupId); + if (device == null || groupId == BluetoothLeAudio.GROUP_ID_INVALID) { + Log.d("LeCB:", "invalid parameter"); + return; + } - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.LeAudioData svc_data = valid_device.leAudioData; + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); + + if (!valid_device_opt.isPresent()) { + Log.d("LeCB:", "Device not present"); + return; + } - svc_data.nodeStatusMutable.postValue(new Pair<>(groupId, GROUP_NODE_REMOVED)); - svc_data.groupStatusMutable.postValue(new Pair<>(groupId, new Pair<>(-1, -1))); - } - }; + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.LeAudioData svc_data = valid_device.leAudioData; + + svc_data.nodeStatusMutable.postValue(new Pair<>(groupId, GROUP_NODE_REMOVED)); + svc_data.groupStatusMutable.postValue(new Pair<>(groupId, new Pair<>(-1, -1))); + } + }; private final MutableLiveData enabledBluetoothMutable; - private final BroadcastReceiver adapterIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { - int toState = - intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); - if (toState == BluetoothAdapter.STATE_ON) { - enabledBluetoothMutable.postValue(true); - } else if (toState == BluetoothAdapter.STATE_OFF) { - enabledBluetoothMutable.postValue(false); + private final BroadcastReceiver adapterIntentReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { + int toState = + intent.getIntExtra( + BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); + if (toState == BluetoothAdapter.STATE_ON) { + enabledBluetoothMutable.postValue(true); + } else if (toState == BluetoothAdapter.STATE_OFF) { + enabledBluetoothMutable.postValue(false); + } + } } - } - } - }; + }; private final MutableLiveData> allLeAudioDevicesMutable; - private final BroadcastReceiver leAudioIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - if (allLeAudioDevicesMutable.getValue() != null) { - if (device != null) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); - - if (valid_device_opt.isPresent()) { - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.LeAudioData svc_data = valid_device.leAudioData; - int group_id; - - // Handle Le Audio actions - switch (action) { - case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED: { - final int toState = - intent.getIntExtra(BluetoothLeAudio.EXTRA_STATE, -1); - if (toState == BluetoothLeAudio.STATE_CONNECTED - || toState == BluetoothLeAudio.STATE_DISCONNECTED) - svc_data.isConnectedMutable - .postValue(toState == BluetoothLeAudio.STATE_CONNECTED); - - group_id = bluetoothLeAudio.getGroupId(device); - svc_data.nodeStatusMutable.postValue( - new Pair<>(group_id, GROUP_NODE_ADDED)); - svc_data.groupStatusMutable - .postValue(new Pair<>(group_id, new Pair<>(-1, -1))); - break; + private final BroadcastReceiver leAudioIntentReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + final BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + if (allLeAudioDevicesMutable.getValue() != null) { + if (device != null) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); + + if (valid_device_opt.isPresent()) { + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.LeAudioData svc_data = + valid_device.leAudioData; + int group_id; + + // Handle Le Audio actions + switch (action) { + case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED: + { + final int toState = + intent.getIntExtra( + BluetoothLeAudio.EXTRA_STATE, -1); + if (toState == BluetoothLeAudio.STATE_CONNECTED + || toState + == BluetoothLeAudio.STATE_DISCONNECTED) + svc_data.isConnectedMutable.postValue( + toState + == BluetoothLeAudio + .STATE_CONNECTED); + + group_id = bluetoothLeAudio.getGroupId(device); + svc_data.nodeStatusMutable.postValue( + new Pair<>(group_id, GROUP_NODE_ADDED)); + svc_data.groupStatusMutable.postValue( + new Pair<>(group_id, new Pair<>(-1, -1))); + break; + } + } } } } } - } - } - }; - - private final BroadcastReceiver hapClientIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - if (allLeAudioDevicesMutable.getValue() != null) { - if (device != null) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); - - if (valid_device_opt.isPresent()) { - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; + }; - switch (action) { - case BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED: { - final int toState = - intent.getIntExtra(BluetoothHapClient.EXTRA_STATE, -1); - svc_data.hapStateMutable.postValue(toState); - break; - } - // Hidden API - case "android.bluetooth.action.HAP_DEVICE_AVAILABLE": { - final int features = intent - .getIntExtra("android.bluetooth.extra.HAP_FEATURES", -1); - svc_data.hapFeaturesMutable.postValue(features); - break; + private final BroadcastReceiver hapClientIntentReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + final BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + if (allLeAudioDevicesMutable.getValue() != null) { + if (device != null) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); + + if (valid_device_opt.isPresent()) { + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; + + switch (action) { + case BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED: + { + final int toState = + intent.getIntExtra( + BluetoothHapClient.EXTRA_STATE, -1); + svc_data.hapStateMutable.postValue(toState); + break; + } + // Hidden API + case "android.bluetooth.action.HAP_DEVICE_AVAILABLE": + { + final int features = + intent.getIntExtra( + "android.bluetooth.extra.HAP_FEATURES", + -1); + svc_data.hapFeaturesMutable.postValue(features); + break; + } + default: + // Do nothing + break; + } } - default: - // Do nothing - break; } } } - } - } - }; - - private final BroadcastReceiver volumeControlIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - if (allLeAudioDevicesMutable.getValue() != null) { - if (device != null) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); - - if (valid_device_opt.isPresent()) { - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.VolumeControlData svc_data = - valid_device.volumeControlData; - - switch (action) { - case BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED: - final int toState = - intent.getIntExtra(BluetoothVolumeControl.EXTRA_STATE, -1); - if (toState == BluetoothVolumeControl.STATE_CONNECTED - || toState == BluetoothVolumeControl.STATE_DISCONNECTED) - svc_data.isConnectedMutable.postValue( - toState == BluetoothVolumeControl.STATE_CONNECTED); - break; + }; + + private final BroadcastReceiver volumeControlIntentReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + final BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + if (allLeAudioDevicesMutable.getValue() != null) { + if (device != null) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); + + if (valid_device_opt.isPresent()) { + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.VolumeControlData svc_data = + valid_device.volumeControlData; + + switch (action) { + case BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED: + final int toState = + intent.getIntExtra( + BluetoothVolumeControl.EXTRA_STATE, -1); + if (toState == BluetoothVolumeControl.STATE_CONNECTED + || toState + == BluetoothVolumeControl + .STATE_DISCONNECTED) + svc_data.isConnectedMutable.postValue( + toState + == BluetoothVolumeControl + .STATE_CONNECTED); + break; + } + } } } } - } - } - }; + }; private final MutableLiveData mBroadcastUpdateMutableLive; - private final MutableLiveData> mBroadcastPlaybackStartedMutableLive; - private final MutableLiveData> mBroadcastPlaybackStoppedMutableLive; + private final MutableLiveData> + mBroadcastPlaybackStartedMutableLive; + private final MutableLiveData> + mBroadcastPlaybackStoppedMutableLive; private final MutableLiveData mBroadcastAddedMutableLive; - private final MutableLiveData> mBroadcastRemovedMutableLive; + private final MutableLiveData> + mBroadcastRemovedMutableLive; private final MutableLiveData mBroadcastStatusMutableLive; private final BluetoothLeBroadcast.Callback mBroadcasterCallback = new BluetoothLeBroadcast.Callback() { @@ -291,8 +348,11 @@ public class BluetoothProxy { public void onBroadcastStarted(int reason, int broadcastId) { if ((reason != BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST) && (reason != BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST)) { - mBroadcastStatusMutableLive.postValue("Unable to create broadcast: " - + broadcastId + ", reason: " + reason); + mBroadcastStatusMutableLive.postValue( + "Unable to create broadcast: " + + broadcastId + + ", reason: " + + reason); } mBroadcastAddedMutableLive.postValue(broadcastId); @@ -303,8 +363,8 @@ public class BluetoothProxy { @Override public void onBroadcastStartFailed(int reason) { - mBroadcastStatusMutableLive - .postValue("Unable to START broadcast due to reason: " + reason); + mBroadcastStatusMutableLive.postValue( + "Unable to START broadcast due to reason: " + reason); } @Override @@ -317,8 +377,8 @@ public class BluetoothProxy { @Override public void onBroadcastStopFailed(int reason) { - mBroadcastStatusMutableLive - .postValue("Unable to STOP broadcast due to reason: " + reason); + mBroadcastStatusMutableLive.postValue( + "Unable to STOP broadcast due to reason: " + reason); } @Override @@ -333,8 +393,11 @@ public class BluetoothProxy { @Override public void onBroadcastUpdated(int reason, int broadcastId) { - mBroadcastStatusMutableLive.postValue("Broadcast " + broadcastId - + "has been updated due to reason: " + reason); + mBroadcastStatusMutableLive.postValue( + "Broadcast " + + broadcastId + + "has been updated due to reason: " + + reason); if (mLocalBroadcastEventListener != null) { mLocalBroadcastEventListener.onBroadcastUpdated(broadcastId); } @@ -342,13 +405,16 @@ public class BluetoothProxy { @Override public void onBroadcastUpdateFailed(int reason, int broadcastId) { - mBroadcastStatusMutableLive.postValue("Unable to UPDATE broadcast " - + broadcastId + " due to reason: " + reason); + mBroadcastStatusMutableLive.postValue( + "Unable to UPDATE broadcast " + + broadcastId + + " due to reason: " + + reason); } @Override - public void onBroadcastMetadataChanged(int broadcastId, - BluetoothLeBroadcastMetadata metadata) { + public void onBroadcastMetadataChanged( + int broadcastId, BluetoothLeBroadcastMetadata metadata) { mBroadcastUpdateMutableLive.postValue(metadata); if (mLocalBroadcastEventListener != null) { mLocalBroadcastEventListener.onBroadcastMetadataChanged( @@ -360,134 +426,144 @@ public class BluetoothProxy { // TODO: Add behaviors in empty methods if necessary. private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new BluetoothLeBroadcastAssistant.Callback() { - @Override - public void onSearchStarted(int reason) {} - - @Override - public void onSearchStartFailed(int reason) {} + @Override + public void onSearchStarted(int reason) {} - @Override - public void onSearchStopped(int reason) {} + @Override + public void onSearchStartFailed(int reason) {} - @Override - public void onSearchStopFailed(int reason) {} + @Override + public void onSearchStopped(int reason) {} - @Override - public void onSourceFound(BluetoothLeBroadcastMetadata source) { - Log.d("BluetoothProxy", "onSourceFound"); - if (mBassEventListener != null) { - mBassEventListener.onSourceFound(source); - } - } + @Override + public void onSearchStopFailed(int reason) {} - @Override - public void onSourceAdded(BluetoothDevice sink, int sourceId, int reason) {} + @Override + public void onSourceFound(BluetoothLeBroadcastMetadata source) { + Log.d("BluetoothProxy", "onSourceFound"); + if (mBassEventListener != null) { + mBassEventListener.onSourceFound(source); + } + } - @Override - public void onSourceAddFailed(BluetoothDevice sink, - BluetoothLeBroadcastMetadata source, int reason) {} + @Override + public void onSourceAdded(BluetoothDevice sink, int sourceId, int reason) {} - @Override - public void onSourceModified(BluetoothDevice sink, int sourceId, int reason) {} + @Override + public void onSourceAddFailed( + BluetoothDevice sink, BluetoothLeBroadcastMetadata source, int reason) {} - @Override - public void onSourceModifyFailed(BluetoothDevice sink, int sourceId, int reason) {} + @Override + public void onSourceModified(BluetoothDevice sink, int sourceId, int reason) {} - @Override - public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {} + @Override + public void onSourceModifyFailed(BluetoothDevice sink, int sourceId, int reason) {} - @Override - public void onSourceRemoveFailed(BluetoothDevice sink, int sourceId, int reason) {} + @Override + public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {} - @Override - public void onReceiveStateChanged(BluetoothDevice sink, int sourceId, - BluetoothLeBroadcastReceiveState state) { - Log.d("BluetoothProxy", "onReceiveStateChanged"); - if (allLeAudioDevicesMutable.getValue() != null) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(stateWrapper -> stateWrapper.device.getAddress().equals( - sink.getAddress())) - .findAny(); + @Override + public void onSourceRemoveFailed(BluetoothDevice sink, int sourceId, int reason) {} - if (!valid_device_opt.isPresent()) - return; - - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.BassData svc_data = valid_device.bassData; - - /** - * From "Introducing-Bluetooth-LE-Audio-book" 8.6.3.1: - * - * The Source_ID is an Acceptor generated number which is used to identify a - * specific set of - * broadcast device and BIG information. It is local to an Acceptor and used as a - * reference for - * a Broadcast Assistant. In the case of a Coordinated Set of Acceptors, such as - * a left and right - * earbud, the Source_IDs are not related and may be different, even if both are - * receiving the - * same BIS, as each Acceptor independently creates their own Source ID values - */ - - /** - * Broadcast receiver's endpoint identifier. - */ - synchronized(this) { - HashMap states = - svc_data.receiverStatesMutable.getValue(); - if (states == null) - states = new HashMap<>(); - states.put(state.getSourceId(), state); - - // Use SetValue instead of PostValue() since we want to make it - // synchronous due to getValue() we do here as well - // Otherwise we could miss the update and store only the last - // receiver ID -// svc_data.receiverStatesMutable.setValue(states); - svc_data.receiverStatesMutable.postValue(states); - } - } - } - }; - - private final BroadcastReceiver bassIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED)) { - final BluetoothDevice device = intent.getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class); - - if (allLeAudioDevicesMutable.getValue() != null) { - if (device != null) { + @Override + public void onReceiveStateChanged( + BluetoothDevice sink, + int sourceId, + BluetoothLeBroadcastReceiveState state) { + Log.d("BluetoothProxy", "onReceiveStateChanged"); + if (allLeAudioDevicesMutable.getValue() != null) { Optional valid_device_opt = - allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals( - device.getAddress())) + allLeAudioDevicesMutable.getValue().stream() + .filter( + stateWrapper -> + stateWrapper + .device + .getAddress() + .equals(sink.getAddress())) .findAny(); - if (valid_device_opt.isPresent()) { - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.BassData svc_data = valid_device.bassData; + if (!valid_device_opt.isPresent()) return; - final int toState = intent - .getIntExtra(BluetoothProfile.EXTRA_STATE, -1); - if (toState == BluetoothProfile.STATE_CONNECTED - || toState == BluetoothProfile.STATE_DISCONNECTED) - svc_data.isConnectedMutable.postValue( - toState == BluetoothProfile.STATE_CONNECTED); + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.BassData svc_data = valid_device.bassData; + + /** + * From "Introducing-Bluetooth-LE-Audio-book" 8.6.3.1: + * + *

The Source_ID is an Acceptor generated number which is used to + * identify a specific set of broadcast device and BIG information. It is + * local to an Acceptor and used as a reference for a Broadcast Assistant. + * In the case of a Coordinated Set of Acceptors, such as a left and right + * earbud, the Source_IDs are not related and may be different, even if both + * are receiving the same BIS, as each Acceptor independently creates their + * own Source ID values + */ + + /** Broadcast receiver's endpoint identifier. */ + synchronized (this) { + HashMap states = + svc_data.receiverStatesMutable.getValue(); + if (states == null) states = new HashMap<>(); + states.put(state.getSourceId(), state); + + // Use SetValue instead of PostValue() since we want to make it + // synchronous due to getValue() we do here as well + // Otherwise we could miss the update and store only the last + // receiver ID + // svc_data.receiverStatesMutable.setValue(states); + svc_data.receiverStatesMutable.postValue(states); } } } - } - // TODO: Remove this if unnecessary. -// case BluetoothBroadcastAudioScan.ACTION_BASS_BROADCAST_ANNONCEMENT_AVAILABLE: -// // FIXME: Never happen since there is no valid device with this intent -// break; - } - }; + }; + + private final BroadcastReceiver bassIntentReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals( + BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED)) { + final BluetoothDevice device = + intent.getParcelableExtra( + BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class); + + if (allLeAudioDevicesMutable.getValue() != null) { + if (device != null) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals( + device + .getAddress())) + .findAny(); + + if (valid_device_opt.isPresent()) { + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.BassData svc_data = + valid_device.bassData; + + final int toState = + intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); + if (toState == BluetoothProfile.STATE_CONNECTED + || toState == BluetoothProfile.STATE_DISCONNECTED) + svc_data.isConnectedMutable.postValue( + toState == BluetoothProfile.STATE_CONNECTED); + } + } + } + } + // TODO: Remove this if unnecessary. + // case + // BluetoothBroadcastAudioScan.ACTION_BASS_BROADCAST_ANNONCEMENT_AVAILABLE: + // // FIXME: Never happen since there is no valid device with this + // intent + // break; + } + }; private BluetoothProxy(Application application) { this.application = application; @@ -511,14 +587,14 @@ public class BluetoothProxy { adapterIntentFilter = new IntentFilter(); adapterIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); adapterIntentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - application.registerReceiver(adapterIntentReceiver, adapterIntentFilter, - Context.RECEIVER_EXPORTED); + application.registerReceiver( + adapterIntentReceiver, adapterIntentFilter, Context.RECEIVER_EXPORTED); bassIntentFilter = new IntentFilter(); bassIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); bassIntentFilter.addAction(BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED); - application.registerReceiver(bassIntentReceiver, bassIntentFilter, - Context.RECEIVER_EXPORTED); + application.registerReceiver( + bassIntentReceiver, bassIntentFilter, Context.RECEIVER_EXPORTED); } // Lazy constructing Singleton acquire method @@ -532,173 +608,220 @@ public class BluetoothProxy { public void initProfiles() { if (profileListener != null) return; - hapCallback = new BluetoothHapClient.Callback() { - @Override - public void onPresetSelected(BluetoothDevice device, int presetIndex, int statusCode) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); - - if (!valid_device_opt.isPresent()) - return; + hapCallback = + new BluetoothHapClient.Callback() { + @Override + public void onPresetSelected( + BluetoothDevice device, int presetIndex, int statusCode) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; + if (!valid_device_opt.isPresent()) return; - svc_data.hapActivePresetIndexMutable.postValue(presetIndex); + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; - svc_data.hapStatusMutable - .postValue("Preset changed to " + presetIndex + ", reason: " + statusCode); - } + svc_data.hapActivePresetIndexMutable.postValue(presetIndex); - @Override - public void onPresetSelectionFailed(BluetoothDevice device, int statusCode) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); + svc_data.hapStatusMutable.postValue( + "Preset changed to " + presetIndex + ", reason: " + statusCode); + } - if (!valid_device_opt.isPresent()) - return; + @Override + public void onPresetSelectionFailed(BluetoothDevice device, int statusCode) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; + if (!valid_device_opt.isPresent()) return; - svc_data.hapStatusMutable - .postValue("Select preset failed with status " + statusCode); - } + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; - @Override - public void onPresetSelectionForGroupFailed(int hapGroupId, int statusCode) { - List valid_devices = null; - if (hapGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) - valid_devices = allLeAudioDevicesMutable.getValue().stream() - .filter(state -> state.leAudioData.nodeStatusMutable.getValue() != null - && state.leAudioData.nodeStatusMutable.getValue().first - .equals(hapGroupId)) - .collect(Collectors.toList()); - - if (valid_devices != null) { - for (LeAudioDeviceStateWrapper device : valid_devices) { - device.hapData.hapStatusMutable.postValue("Select preset for group " - + hapGroupId + " failed with status " + statusCode); + svc_data.hapStatusMutable.postValue( + "Select preset failed with status " + statusCode); } - } - } - @Override - public void onPresetInfoChanged(BluetoothDevice device, - List presetInfoList, int statusCode) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); + @Override + public void onPresetSelectionForGroupFailed(int hapGroupId, int statusCode) { + List valid_devices = null; + if (hapGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) + valid_devices = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.leAudioData.nodeStatusMutable + .getValue() + != null + && state.leAudioData + .nodeStatusMutable + .getValue() + .first + .equals(hapGroupId)) + .collect(Collectors.toList()); + + if (valid_devices != null) { + for (LeAudioDeviceStateWrapper device : valid_devices) { + device.hapData.hapStatusMutable.postValue( + "Select preset for group " + + hapGroupId + + " failed with status " + + statusCode); + } + } + } - if (!valid_device_opt.isPresent()) - return; + @Override + public void onPresetInfoChanged( + BluetoothDevice device, + List presetInfoList, + int statusCode) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; + if (!valid_device_opt.isPresent()) return; - svc_data.hapStatusMutable - .postValue("Preset list changed due to status " + statusCode); - svc_data.hapPresetsMutable.postValue(presetInfoList); - } + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; - @Override - public void onSetPresetNameFailed(BluetoothDevice device, int status) { - Optional valid_device_opt = allLeAudioDevicesMutable - .getValue().stream() - .filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); + svc_data.hapStatusMutable.postValue( + "Preset list changed due to status " + statusCode); + svc_data.hapPresetsMutable.postValue(presetInfoList); + } - if (!valid_device_opt.isPresent()) - return; + @Override + public void onSetPresetNameFailed(BluetoothDevice device, int status) { + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.device + .getAddress() + .equals(device.getAddress())) + .findAny(); - LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); - LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; + if (!valid_device_opt.isPresent()) return; - svc_data.hapStatusMutable.postValue("Name set error: " + status); - } + LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); + LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; - @Override - public void onSetPresetNameForGroupFailed(int hapGroupId, int status) { - List valid_devices = null; - if (hapGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) - valid_devices = allLeAudioDevicesMutable.getValue().stream() - .filter(state -> state.leAudioData.nodeStatusMutable.getValue() != null - && state.leAudioData.nodeStatusMutable.getValue().first - .equals(hapGroupId)) - .collect(Collectors.toList()); - - if (valid_devices != null) { - for (LeAudioDeviceStateWrapper device : valid_devices) { - device.hapData.hapStatusMutable - .postValue("Group Name set error: " + status); + svc_data.hapStatusMutable.postValue("Name set error: " + status); } - } - } - }; - - profileListener = new BluetoothProfile.ServiceListener() { - @Override - public void onServiceConnected(int i, BluetoothProfile bluetoothProfile) { - Log.d("BluetoothProxy", "onServiceConnected(): i = " + i + " bluetoothProfile = " + - bluetoothProfile); - switch (i) { - case BluetoothProfile.CSIP_SET_COORDINATOR: - bluetoothCsis = (BluetoothCsipSetCoordinator) bluetoothProfile; - break; - case BluetoothProfile.LE_AUDIO: - bluetoothLeAudio = (BluetoothLeAudio) bluetoothProfile; - if (!mLeAudioCallbackRegistered) { - try { - bluetoothLeAudio.registerCallback(mExecutor, mLeAudioCallbacks); - mLeAudioCallbackRegistered = true; - } catch (Exception e){ - Log.e("Unicast:" , - " Probably not supported: Exception on registering callbacks: " + e); + + @Override + public void onSetPresetNameForGroupFailed(int hapGroupId, int status) { + List valid_devices = null; + if (hapGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) + valid_devices = + allLeAudioDevicesMutable.getValue().stream() + .filter( + state -> + state.leAudioData.nodeStatusMutable + .getValue() + != null + && state.leAudioData + .nodeStatusMutable + .getValue() + .first + .equals(hapGroupId)) + .collect(Collectors.toList()); + + if (valid_devices != null) { + for (LeAudioDeviceStateWrapper device : valid_devices) { + device.hapData.hapStatusMutable.postValue( + "Group Name set error: " + status); } } - break; - case BluetoothProfile.VOLUME_CONTROL: - bluetoothVolumeControl = (BluetoothVolumeControl) bluetoothProfile; - break; - case BluetoothProfile.HAP_CLIENT: - bluetoothHapClient = (BluetoothHapClient) bluetoothProfile; - try { - bluetoothHapClient.registerCallback(mExecutor, hapCallback); - } catch (IllegalArgumentException e) { - Log.e("HAP", "Application callback already registered."); - } - break; - case BluetoothProfile.LE_AUDIO_BROADCAST: - mBluetoothLeBroadcast = (BluetoothLeBroadcast) bluetoothProfile; - try { - mBluetoothLeBroadcast.registerCallback(mExecutor, mBroadcasterCallback); - } catch (IllegalArgumentException e) { - Log.e("Broadcast", "Application callback already registered."); - } - break; - case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT: - Log.d("BluetoothProxy", "LE_AUDIO_BROADCAST_ASSISTANT Service connected"); - mBluetoothLeBroadcastAssistant = (BluetoothLeBroadcastAssistant) - bluetoothProfile; - try { - mBluetoothLeBroadcastAssistant.registerCallback(mExecutor, - mBroadcastAssistantCallback); - } catch (IllegalArgumentException e) { - Log.e("BASS", "Application callback already registered."); + } + }; + + profileListener = + new BluetoothProfile.ServiceListener() { + @Override + public void onServiceConnected(int i, BluetoothProfile bluetoothProfile) { + Log.d( + "BluetoothProxy", + "onServiceConnected(): i = " + + i + + " bluetoothProfile = " + + bluetoothProfile); + switch (i) { + case BluetoothProfile.CSIP_SET_COORDINATOR: + bluetoothCsis = (BluetoothCsipSetCoordinator) bluetoothProfile; + break; + case BluetoothProfile.LE_AUDIO: + bluetoothLeAudio = (BluetoothLeAudio) bluetoothProfile; + if (!mLeAudioCallbackRegistered) { + try { + bluetoothLeAudio.registerCallback( + mExecutor, mLeAudioCallbacks); + mLeAudioCallbackRegistered = true; + } catch (Exception e) { + Log.e( + "Unicast:", + " Probably not supported: Exception on registering" + + " callbacks: " + + e); + } + } + break; + case BluetoothProfile.VOLUME_CONTROL: + bluetoothVolumeControl = (BluetoothVolumeControl) bluetoothProfile; + break; + case BluetoothProfile.HAP_CLIENT: + bluetoothHapClient = (BluetoothHapClient) bluetoothProfile; + try { + bluetoothHapClient.registerCallback(mExecutor, hapCallback); + } catch (IllegalArgumentException e) { + Log.e("HAP", "Application callback already registered."); + } + break; + case BluetoothProfile.LE_AUDIO_BROADCAST: + mBluetoothLeBroadcast = (BluetoothLeBroadcast) bluetoothProfile; + try { + mBluetoothLeBroadcast.registerCallback( + mExecutor, mBroadcasterCallback); + } catch (IllegalArgumentException e) { + Log.e("Broadcast", "Application callback already registered."); + } + break; + case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT: + Log.d( + "BluetoothProxy", + "LE_AUDIO_BROADCAST_ASSISTANT Service connected"); + mBluetoothLeBroadcastAssistant = + (BluetoothLeBroadcastAssistant) bluetoothProfile; + try { + mBluetoothLeBroadcastAssistant.registerCallback( + mExecutor, mBroadcastAssistantCallback); + } catch (IllegalArgumentException e) { + Log.e("BASS", "Application callback already registered."); + } + break; } - break; - } - queryLeAudioDevices(); - } + queryLeAudioDevices(); + } - @Override - public void onServiceDisconnected(int i) {} - }; + @Override + public void onServiceDisconnected(int i) {} + }; initCsisProxy(); initLeAudioProxy(); @@ -724,8 +847,8 @@ public class BluetoothProxy { private void initCsisProxy() { if (!isCoordinatedSetProfileSupported()) return; if (bluetoothCsis == null) { - bluetoothAdapter.getProfileProxy(this.application, profileListener, - BluetoothProfile.CSIP_SET_COORDINATOR); + bluetoothAdapter.getProfileProxy( + this.application, profileListener, BluetoothProfile.CSIP_SET_COORDINATOR); } } @@ -739,15 +862,15 @@ public class BluetoothProxy { private void initLeAudioProxy() { if (!isLeAudioUnicastSupported()) return; if (bluetoothLeAudio == null) { - bluetoothAdapter.getProfileProxy(this.application, profileListener, - BluetoothProfile.LE_AUDIO); + bluetoothAdapter.getProfileProxy( + this.application, profileListener, BluetoothProfile.LE_AUDIO); } intentFilter = new IntentFilter(); intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); intentFilter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); - application.registerReceiver(leAudioIntentReceiver, intentFilter, - Context.RECEIVER_EXPORTED); + application.registerReceiver( + leAudioIntentReceiver, intentFilter, Context.RECEIVER_EXPORTED); } private void cleanupLeAudioProxy() { @@ -760,36 +883,36 @@ public class BluetoothProxy { private void initVolumeControlProxy() { if (!isVolumeControlClientSupported()) return; - bluetoothAdapter.getProfileProxy(this.application, profileListener, - BluetoothProfile.VOLUME_CONTROL); + bluetoothAdapter.getProfileProxy( + this.application, profileListener, BluetoothProfile.VOLUME_CONTROL); intentFilter = new IntentFilter(); intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); intentFilter.addAction(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED); - application.registerReceiver(volumeControlIntentReceiver, intentFilter, - Context.RECEIVER_EXPORTED); + application.registerReceiver( + volumeControlIntentReceiver, intentFilter, Context.RECEIVER_EXPORTED); } private void cleanupVolumeControlProxy() { if (!isVolumeControlClientSupported()) return; if (bluetoothVolumeControl != null) { - bluetoothAdapter.closeProfileProxy(BluetoothProfile.VOLUME_CONTROL, - bluetoothVolumeControl); + bluetoothAdapter.closeProfileProxy( + BluetoothProfile.VOLUME_CONTROL, bluetoothVolumeControl); application.unregisterReceiver(volumeControlIntentReceiver); } } private void initHapProxy() { if (!isLeAudioHearingAccessClientSupported()) return; - bluetoothAdapter.getProfileProxy(this.application, profileListener, - BluetoothProfile.HAP_CLIENT); + bluetoothAdapter.getProfileProxy( + this.application, profileListener, BluetoothProfile.HAP_CLIENT); intentFilter = new IntentFilter(); intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); intentFilter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intentFilter.addAction("android.bluetooth.action.HAP_DEVICE_AVAILABLE"); - application.registerReceiver(hapClientIntentReceiver, intentFilter, - Context.RECEIVER_EXPORTED); + application.registerReceiver( + hapClientIntentReceiver, intentFilter, Context.RECEIVER_EXPORTED); } private void cleanupHapProxy() { @@ -803,16 +926,16 @@ public class BluetoothProxy { private void initBassProxy() { if (!isLeAudioBroadcastScanAssistanSupported()) return; - bluetoothAdapter.getProfileProxy(this.application, profileListener, - BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + bluetoothAdapter.getProfileProxy( + this.application, profileListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); } private void cleanupBassProxy() { if (!isLeAudioBroadcastScanAssistanSupported()) return; if (mBluetoothLeBroadcastAssistant != null) { mBluetoothLeBroadcastAssistant.unregisterCallback(mBroadcastAssistantCallback); - bluetoothAdapter.closeProfileProxy(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, - mBluetoothLeBroadcastAssistant); + bluetoothAdapter.closeProfileProxy( + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, mBluetoothLeBroadcastAssistant); } } @@ -835,100 +958,111 @@ public class BluetoothProxy { Boolean valid_device = false; if (Arrays.asList(dev.getUuids() != null ? dev.getUuids() : new ParcelUuid[0]) - .contains(ParcelUuid - .fromString(application.getString(R.string.svc_uuid_le_audio)))) { + .contains( + ParcelUuid.fromString( + application.getString(R.string.svc_uuid_le_audio)))) { if (state_wrapper.leAudioData == null) state_wrapper.leAudioData = new LeAudioDeviceStateWrapper.LeAudioData(); valid_device = true; if (bluetoothLeAudio != null) { - state_wrapper.leAudioData.isConnectedMutable.postValue(bluetoothLeAudio - .getConnectionState(dev) == BluetoothLeAudio.STATE_CONNECTED); + state_wrapper.leAudioData.isConnectedMutable.postValue( + bluetoothLeAudio.getConnectionState(dev) + == BluetoothLeAudio.STATE_CONNECTED); int group_id = bluetoothLeAudio.getGroupId(dev); - state_wrapper.leAudioData.nodeStatusMutable - .setValue(new Pair<>(group_id, GROUP_NODE_ADDED)); - state_wrapper.leAudioData.groupStatusMutable - .setValue(new Pair<>(group_id, new Pair<>(-1, -1))); + state_wrapper.leAudioData.nodeStatusMutable.setValue( + new Pair<>(group_id, GROUP_NODE_ADDED)); + state_wrapper.leAudioData.groupStatusMutable.setValue( + new Pair<>(group_id, new Pair<>(-1, -1))); } } if (Arrays.asList(dev.getUuids() != null ? dev.getUuids() : new ParcelUuid[0]) - .contains(ParcelUuid.fromString( - application.getString(R.string.svc_uuid_volume_control)))) { + .contains( + ParcelUuid.fromString( + application.getString(R.string.svc_uuid_volume_control)))) { if (state_wrapper.volumeControlData == null) state_wrapper.volumeControlData = new LeAudioDeviceStateWrapper.VolumeControlData(); valid_device = true; if (bluetoothVolumeControl != null) { - state_wrapper.volumeControlData.isConnectedMutable - .postValue(bluetoothVolumeControl.getConnectionState( - dev) == BluetoothVolumeControl.STATE_CONNECTED); + state_wrapper.volumeControlData.isConnectedMutable.postValue( + bluetoothVolumeControl.getConnectionState(dev) + == BluetoothVolumeControl.STATE_CONNECTED); // FIXME: We don't have the api to get the volume and mute states? :( } } if (Arrays.asList(dev.getUuids() != null ? dev.getUuids() : new ParcelUuid[0]) - .contains(ParcelUuid - .fromString(application.getString(R.string.svc_uuid_has)))) { + .contains( + ParcelUuid.fromString( + application.getString(R.string.svc_uuid_has)))) { if (state_wrapper.hapData == null) state_wrapper.hapData = new LeAudioDeviceStateWrapper.HapData(); valid_device = true; if (bluetoothHapClient != null) { - state_wrapper.hapData.hapStateMutable - .postValue(bluetoothHapClient.getConnectionState(dev)); - boolean is_connected = bluetoothHapClient - .getConnectionState(dev) == BluetoothHapClient.STATE_CONNECTED; + state_wrapper.hapData.hapStateMutable.postValue( + bluetoothHapClient.getConnectionState(dev)); + boolean is_connected = + bluetoothHapClient.getConnectionState(dev) + == BluetoothHapClient.STATE_CONNECTED; if (is_connected) { // Use hidden API try { - Method getFeaturesMethod = BluetoothHapClient.class - .getDeclaredMethod("getFeatures", BluetoothDevice.class); + Method getFeaturesMethod = + BluetoothHapClient.class.getDeclaredMethod( + "getFeatures", BluetoothDevice.class); getFeaturesMethod.setAccessible(true); - state_wrapper.hapData.hapFeaturesMutable - .postValue((Integer) getFeaturesMethod - .invoke(bluetoothHapClient, dev)); - } catch (NoSuchMethodException | IllegalAccessException + state_wrapper.hapData.hapFeaturesMutable.postValue( + (Integer) + getFeaturesMethod.invoke(bluetoothHapClient, dev)); + } catch (NoSuchMethodException + | IllegalAccessException | InvocationTargetException e) { - state_wrapper.hapData.hapStatusMutable - .postValue("Hidden API for getFeatures not accessible."); + state_wrapper.hapData.hapStatusMutable.postValue( + "Hidden API for getFeatures not accessible."); } - state_wrapper.hapData.hapPresetsMutable - .postValue(bluetoothHapClient.getAllPresetInfo(dev)); + state_wrapper.hapData.hapPresetsMutable.postValue( + bluetoothHapClient.getAllPresetInfo(dev)); try { Method getActivePresetIndexMethod = BluetoothHapClient.class.getDeclaredMethod( "getActivePresetIndex", BluetoothDevice.class); getActivePresetIndexMethod.setAccessible(true); - state_wrapper.hapData.hapActivePresetIndexMutable - .postValue((Integer) getActivePresetIndexMethod - .invoke(bluetoothHapClient, dev)); - } catch (NoSuchMethodException | IllegalAccessException + state_wrapper.hapData.hapActivePresetIndexMutable.postValue( + (Integer) + getActivePresetIndexMethod.invoke( + bluetoothHapClient, dev)); + } catch (NoSuchMethodException + | IllegalAccessException | InvocationTargetException e) { - state_wrapper.hapData.hapStatusMutable - .postValue("Hidden API for getFeatures not accessible."); + state_wrapper.hapData.hapStatusMutable.postValue( + "Hidden API for getFeatures not accessible."); } } } } if (Arrays.asList(dev.getUuids() != null ? dev.getUuids() : new ParcelUuid[0]) - .contains(ParcelUuid.fromString( - application.getString(R.string.svc_uuid_broadcast_audio)))) { + .contains( + ParcelUuid.fromString( + application.getString( + R.string.svc_uuid_broadcast_audio)))) { if (state_wrapper.bassData == null) state_wrapper.bassData = new LeAudioDeviceStateWrapper.BassData(); valid_device = true; if (mBluetoothLeBroadcastAssistant != null) { - boolean is_connected = mBluetoothLeBroadcastAssistant - .getConnectionState(dev) == BluetoothProfile.STATE_CONNECTED; + boolean is_connected = + mBluetoothLeBroadcastAssistant.getConnectionState(dev) + == BluetoothProfile.STATE_CONNECTED; state_wrapper.bassData.isConnectedMutable.setValue(is_connected); } } - if (valid_device) validDevices.add(state_wrapper); } @@ -941,21 +1075,25 @@ public class BluetoothProxy { if (bluetoothLeAudio != null) { if (connect) { try { - Method connectMethod = BluetoothLeAudio.class.getDeclaredMethod("connect", - BluetoothDevice.class); + Method connectMethod = + BluetoothLeAudio.class.getDeclaredMethod( + "connect", BluetoothDevice.class); connectMethod.setAccessible(true); connectMethod.invoke(bluetoothLeAudio, device); - } catch (NoSuchMethodException | IllegalAccessException + } catch (NoSuchMethodException + | IllegalAccessException | InvocationTargetException e) { // Do nothing } } else { try { - Method disconnectMethod = BluetoothLeAudio.class.getDeclaredMethod("disconnect", - BluetoothDevice.class); + Method disconnectMethod = + BluetoothLeAudio.class.getDeclaredMethod( + "disconnect", BluetoothDevice.class); disconnectMethod.setAccessible(true); disconnectMethod.invoke(bluetoothLeAudio, device); - } catch (NoSuchMethodException | IllegalAccessException + } catch (NoSuchMethodException + | IllegalAccessException | InvocationTargetException e) { // Do nothing } @@ -988,8 +1126,9 @@ public class BluetoothProxy { if (bluetoothLeAudio == null) return; try { - Method groupAddNodeMethod = BluetoothLeAudio.class.getDeclaredMethod("groupAddNode", - int.class, BluetoothDevice.class); + Method groupAddNodeMethod = + BluetoothLeAudio.class.getDeclaredMethod( + "groupAddNode", int.class, BluetoothDevice.class); groupAddNodeMethod.setAccessible(true); groupAddNodeMethod.invoke(bluetoothLeAudio, group_id, device); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { @@ -1001,8 +1140,9 @@ public class BluetoothProxy { if (bluetoothLeAudio == null) return; try { - Method groupRemoveNodeMethod = BluetoothLeAudio.class - .getDeclaredMethod("groupRemoveNode", int.class, BluetoothDevice.class); + Method groupRemoveNodeMethod = + BluetoothLeAudio.class.getDeclaredMethod( + "groupRemoveNode", int.class, BluetoothDevice.class); groupRemoveNodeMethod.setAccessible(true); groupRemoveNodeMethod.invoke(bluetoothLeAudio, group_id, device); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { @@ -1016,32 +1156,54 @@ public class BluetoothProxy { Log.d("Lock", "lock: " + lock); if (lock) { if (mGroupLocks.containsKey(group_id)) { - Log.e("Lock", "group" + group_id + " is already in locking process or locked: " + lock); + Log.e( + "Lock", + "group" + group_id + " is already in locking process or locked: " + lock); return; } - UUID uuid = bluetoothCsis.lockGroup(group_id, mExecutor, - (int group, int op_status, boolean is_locked) -> { - Log.d("LockCb", "lock: " + is_locked + " status: " + op_status); - if (((op_status == BluetoothStatusCodes.SUCCESS) - || (op_status == BluetoothStatusCodes.ERROR_CSIP_LOCKED_GROUP_MEMBER_LOST)) - && (group != BluetoothLeAudio.GROUP_ID_INVALID)) { - allLeAudioDevicesMutable.getValue().forEach((dev_wrapper) -> { - if (dev_wrapper.leAudioData.nodeStatusMutable.getValue() != null - && dev_wrapper.leAudioData.nodeStatusMutable - .getValue().first.equals(group_id)) { - dev_wrapper.leAudioData.groupLockStateMutable.postValue( - new Pair(group, is_locked)); + UUID uuid = + bluetoothCsis.lockGroup( + group_id, + mExecutor, + (int group, int op_status, boolean is_locked) -> { + Log.d("LockCb", "lock: " + is_locked + " status: " + op_status); + if (((op_status == BluetoothStatusCodes.SUCCESS) + || (op_status + == BluetoothStatusCodes + .ERROR_CSIP_LOCKED_GROUP_MEMBER_LOST)) + && (group != BluetoothLeAudio.GROUP_ID_INVALID)) { + allLeAudioDevicesMutable + .getValue() + .forEach( + (dev_wrapper) -> { + if (dev_wrapper.leAudioData + .nodeStatusMutable + .getValue() + != null + && dev_wrapper + .leAudioData + .nodeStatusMutable + .getValue() + .first + .equals(group_id)) { + dev_wrapper.leAudioData + .groupLockStateMutable + .postValue( + new Pair< + Integer, + Boolean>( + group, + is_locked)); + } + }); + } else { + // TODO: Set error status so it could be notified/toasted to the + // user } - }); - } else { - // TODO: Set error status so it could be notified/toasted to the - // user - } - if (!is_locked) - mGroupLocks.remove(group_id); - }); + if (!is_locked) mGroupLocks.remove(group_id); + }); // Store the lock key mGroupLocks.put(group_id, uuid); } else { @@ -1056,11 +1218,11 @@ public class BluetoothProxy { public void connectBass(BluetoothDevice device, boolean connect) { if (mBluetoothLeBroadcastAssistant != null) { if (connect) { - mBluetoothLeBroadcastAssistant.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + mBluetoothLeBroadcastAssistant.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { - mBluetoothLeBroadcastAssistant.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + mBluetoothLeBroadcastAssistant.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } } } @@ -1120,14 +1282,16 @@ public class BluetoothProxy { } // TODO: Uncomment this method if necessary -// public boolean getBroadcastReceiverState(BluetoothDevice device, int receiver_id) { -// if (mBluetoothLeBroadcastAssistant != null) { -// return mBluetoothLeBroadcastAssistant.getBroadcastReceiverState(device, receiver_id); -// } -// return false; -// } - - public boolean addBroadcastSource(BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata) { + // public boolean getBroadcastReceiverState(BluetoothDevice device, int receiver_id) { + // if (mBluetoothLeBroadcastAssistant != null) { + // return mBluetoothLeBroadcastAssistant.getBroadcastReceiverState(device, + // receiver_id); + // } + // return false; + // } + + public boolean addBroadcastSource( + BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata) { if (mBluetoothLeBroadcastAssistant != null) { mBluetoothLeBroadcastAssistant.addSource(sink, sourceMetadata, true /* isGroupOp */); return true; @@ -1135,8 +1299,8 @@ public class BluetoothProxy { return false; } - public boolean modifyBroadcastSource(BluetoothDevice sink, int sourceId, - BluetoothLeBroadcastMetadata metadata) { + public boolean modifyBroadcastSource( + BluetoothDevice sink, int sourceId, BluetoothLeBroadcastMetadata metadata) { if (mBluetoothLeBroadcastAssistant != null) { mBluetoothLeBroadcastAssistant.modifySource(sink, sourceId, metadata); return true; @@ -1171,49 +1335,48 @@ public class BluetoothProxy { public void connectHap(BluetoothDevice device, boolean connect) { if (bluetoothHapClient != null) { if (connect) { - bluetoothHapClient.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + bluetoothHapClient.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { - bluetoothHapClient.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + bluetoothHapClient.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } } } public boolean hapReadPresetInfo(BluetoothDevice device, int preset_index) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; BluetoothHapPresetInfo new_preset = null; // Use hidden API try { - Method getPresetInfoMethod = BluetoothHapClient.class.getDeclaredMethod("getPresetInfo", - BluetoothDevice.class, int.class); + Method getPresetInfoMethod = + BluetoothHapClient.class.getDeclaredMethod( + "getPresetInfo", BluetoothDevice.class, int.class); getPresetInfoMethod.setAccessible(true); - new_preset = (BluetoothHapPresetInfo) getPresetInfoMethod.invoke(bluetoothHapClient, - device, preset_index); - if (new_preset == null) - return false; + new_preset = + (BluetoothHapPresetInfo) + getPresetInfoMethod.invoke(bluetoothHapClient, device, preset_index); + if (new_preset == null) return false; } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { // Do nothing' return false; } - Optional valid_device_opt = allLeAudioDevicesMutable.getValue() - .stream().filter(state -> state.device.getAddress().equals(device.getAddress())) - .findAny(); + Optional valid_device_opt = + allLeAudioDevicesMutable.getValue().stream() + .filter(state -> state.device.getAddress().equals(device.getAddress())) + .findAny(); - if (!valid_device_opt.isPresent()) - return false; + if (!valid_device_opt.isPresent()) return false; LeAudioDeviceStateWrapper valid_device = valid_device_opt.get(); LeAudioDeviceStateWrapper.HapData svc_data = valid_device.hapData; List current_presets = svc_data.hapPresetsMutable.getValue(); - if (current_presets == null) - current_presets = new ArrayList(); + if (current_presets == null) current_presets = new ArrayList(); // Remove old one and add back the new one ListIterator iter = current_presets.listIterator(); @@ -1229,16 +1392,14 @@ public class BluetoothProxy { } public boolean hapSetActivePreset(BluetoothDevice device, int preset_index) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; bluetoothHapClient.selectPreset(device, preset_index); return true; } public boolean hapSetActivePresetForGroup(BluetoothDevice device, int preset_index) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; int groupId = bluetoothLeAudio.getGroupId(device); bluetoothHapClient.selectPresetForGroup(groupId, preset_index); @@ -1246,21 +1407,20 @@ public class BluetoothProxy { } public boolean hapChangePresetName(BluetoothDevice device, int preset_index, String name) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; bluetoothHapClient.setPresetName(device, preset_index, name); return true; } public boolean hapPreviousDevicePreset(BluetoothDevice device) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; // Use hidden API try { - Method switchToPreviousPresetMethod = BluetoothHapClient.class - .getDeclaredMethod("switchToPreviousPreset", BluetoothDevice.class); + Method switchToPreviousPresetMethod = + BluetoothHapClient.class.getDeclaredMethod( + "switchToPreviousPreset", BluetoothDevice.class); switchToPreviousPresetMethod.setAccessible(true); switchToPreviousPresetMethod.invoke(bluetoothHapClient, device); @@ -1271,13 +1431,13 @@ public class BluetoothProxy { } public boolean hapNextDevicePreset(BluetoothDevice device) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; // Use hidden API try { - Method switchToNextPresetMethod = BluetoothHapClient.class - .getDeclaredMethod("switchToNextPreset", BluetoothDevice.class); + Method switchToNextPresetMethod = + BluetoothHapClient.class.getDeclaredMethod( + "switchToNextPreset", BluetoothDevice.class); switchToNextPresetMethod.setAccessible(true); switchToNextPresetMethod.invoke(bluetoothHapClient, device); @@ -1288,13 +1448,13 @@ public class BluetoothProxy { } public boolean hapPreviousGroupPreset(int group_id) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; // Use hidden API try { - Method switchToPreviousPresetForGroupMethod = BluetoothHapClient.class - .getDeclaredMethod("switchToPreviousPresetForGroup", int.class); + Method switchToPreviousPresetForGroupMethod = + BluetoothHapClient.class.getDeclaredMethod( + "switchToPreviousPresetForGroup", int.class); switchToPreviousPresetForGroupMethod.setAccessible(true); switchToPreviousPresetForGroupMethod.invoke(bluetoothHapClient, group_id); @@ -1305,13 +1465,13 @@ public class BluetoothProxy { } public boolean hapNextGroupPreset(int group_id) { - if (bluetoothHapClient == null) - return false; + if (bluetoothHapClient == null) return false; // Use hidden API try { - Method switchToNextPresetForGroupMethod = BluetoothHapClient.class - .getDeclaredMethod("switchToNextPresetForGroup", int.class); + Method switchToNextPresetForGroupMethod = + BluetoothHapClient.class.getDeclaredMethod( + "switchToNextPresetForGroup", int.class); switchToNextPresetForGroupMethod.setAccessible(true); switchToNextPresetForGroupMethod.invoke(bluetoothHapClient, group_id); @@ -1322,13 +1482,13 @@ public class BluetoothProxy { } public int hapGetHapGroup(BluetoothDevice device) { - if (bluetoothHapClient == null) - return BluetoothCsipSetCoordinator.GROUP_ID_INVALID; + if (bluetoothHapClient == null) return BluetoothCsipSetCoordinator.GROUP_ID_INVALID; // Use hidden API try { - Method getHapGroupMethod = BluetoothHapClient.class.getDeclaredMethod("getHapGroup", - BluetoothDevice.class); + Method getHapGroupMethod = + BluetoothHapClient.class.getDeclaredMethod( + "getHapGroup", BluetoothDevice.class); getHapGroupMethod.setAccessible(true); return (Integer) getHapGroupMethod.invoke(bluetoothHapClient, device); @@ -1341,16 +1501,16 @@ public class BluetoothProxy { private void initLeAudioBroadcastProxy() { if (!isLeAudioBroadcastSourceSupported()) return; if (mBluetoothLeBroadcast == null) { - bluetoothAdapter.getProfileProxy(this.application, profileListener, - BluetoothProfile.LE_AUDIO_BROADCAST); + bluetoothAdapter.getProfileProxy( + this.application, profileListener, BluetoothProfile.LE_AUDIO_BROADCAST); } } private void cleanupLeAudioBroadcastProxy() { if (!isLeAudioBroadcastSourceSupported()) return; if (mBluetoothLeBroadcast != null) { - bluetoothAdapter.closeProfileProxy(BluetoothProfile.LE_AUDIO_BROADCAST, - mBluetoothLeBroadcast); + bluetoothAdapter.closeProfileProxy( + BluetoothProfile.LE_AUDIO_BROADCAST, mBluetoothLeBroadcast); } } @@ -1358,11 +1518,13 @@ public class BluetoothProxy { return mBroadcastUpdateMutableLive; } - public LiveData> getBroadcastPlaybackStartedMutableLive() { + public LiveData> + getBroadcastPlaybackStartedMutableLive() { return mBroadcastPlaybackStartedMutableLive; } - public LiveData> getBroadcastPlaybackStoppedMutableLive() { + public LiveData> + getBroadcastPlaybackStoppedMutableLive() { return mBroadcastPlaybackStoppedMutableLive; } @@ -1370,7 +1532,8 @@ public class BluetoothProxy { return mBroadcastAddedMutableLive; } - public LiveData> getBroadcastRemovedMutableLive() { + public LiveData> + getBroadcastRemovedMutableLive() { return mBroadcastRemovedMutableLive; } @@ -1379,8 +1542,7 @@ public class BluetoothProxy { } public boolean startBroadcast(BluetoothLeBroadcastSettings settings) { - if (mBluetoothLeBroadcast == null) - return false; + if (mBluetoothLeBroadcast == null) return false; mBluetoothLeBroadcast.startBroadcast(settings); return true; } @@ -1417,8 +1579,7 @@ public class BluetoothProxy { } boolean isLeAudioUnicastSupported() { - return (bluetoothAdapter - .isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + return (bluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); } boolean isCoordinatedSetProfileSupported() { @@ -1434,13 +1595,13 @@ public class BluetoothProxy { } public boolean isLeAudioBroadcastSourceSupported() { - return (bluetoothAdapter - .isLeAudioBroadcastSourceSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + return (bluetoothAdapter.isLeAudioBroadcastSourceSupported() + == BluetoothStatusCodes.FEATURE_SUPPORTED); } public boolean isLeAudioBroadcastScanAssistanSupported() { - return (bluetoothAdapter - .isLeAudioBroadcastAssistantSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + return (bluetoothAdapter.isLeAudioBroadcastAssistantSupported() + == BluetoothStatusCodes.FEATURE_SUPPORTED); } public void setOnBassEventListener(OnBassEventListener listener) { @@ -1450,6 +1611,7 @@ public class BluetoothProxy { // Used by BroadcastScanViewModel public interface OnBassEventListener { void onSourceFound(BluetoothLeBroadcastMetadata source); + void onScanningStateChanged(boolean isScanning); } @@ -1461,8 +1623,11 @@ public class BluetoothProxy { public interface OnLocalBroadcastEventListener { // TODO: Add arguments in methods void onBroadcastStarted(int broadcastId); + void onBroadcastStopped(int broadcastId); + void onBroadcastUpdated(int broadcastId); + void onBroadcastMetadataChanged(int broadcastId, BluetoothLeBroadcastMetadata metadata); } } diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastItemsAdapter.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastItemsAdapter.java index e346b82341c..ce5a042c6ae 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastItemsAdapter.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastItemsAdapter.java @@ -44,8 +44,9 @@ public class BroadcastItemsAdapter @NonNull @Override public BroadcastItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View item_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.broadcast_item, - parent, false); + View item_view = + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.broadcast_item, parent, false); return new BroadcastItemHolder(item_view, mOnItemClickListener); } @@ -60,7 +61,7 @@ public class BroadcastItemsAdapter Boolean isPlaybackStateKnown = mBroadcastPlaybackMap.containsKey(broadcastId); String broadcastText = - "ID: " + broadcastId + "(" + String.format("0x%06x", broadcastId) + ")"; + "ID: " + broadcastId + "(" + String.format("0x%06x", broadcastId) + ")"; ColorStateList color = ColorStateList.valueOf(Color.WHITE); @@ -69,10 +70,10 @@ public class BroadcastItemsAdapter Boolean isPlaying = mBroadcastPlaybackMap.getOrDefault(broadcastId, false); if (isPlaying) { - color = ColorStateList.valueOf(Color.parseColor("#92b141")); - broadcastText += " ▶️"; + color = ColorStateList.valueOf(Color.parseColor("#92b141")); + broadcastText += " ▶️"; } else { - broadcastText += " ⏸"; + broadcastText += " ⏸"; } } @@ -123,7 +124,7 @@ public class BroadcastItemsAdapter if (mBroadcastPlaybackMap.containsKey(broadcastId)) { continue; } -// mBroadcastPlaybackMap.remove(broadcastId); + // mBroadcastPlaybackMap.remove(broadcastId); mBroadcastPlaybackMap.put(broadcastId, false); } notifyDataSetChanged(); @@ -148,15 +149,17 @@ public class BroadcastItemsAdapter mTextViewBroadcastId = itemView.findViewById(R.id.broadcast_id_text); background = itemView.findViewById(R.id.broadcast_item_card_view); - itemView.setOnClickListener(v -> { - if (listener == null) return; - - int position = getAdapterPosition(); - if (position != RecyclerView.NO_POSITION) { - Integer broadcastId = mBroadcastMetadataList.get(position).getBroadcastId(); - listener.onItemClick(broadcastId); - } - }); + itemView.setOnClickListener( + v -> { + if (listener == null) return; + + int position = getAdapterPosition(); + if (position != RecyclerView.NO_POSITION) { + Integer broadcastId = + mBroadcastMetadataList.get(position).getBroadcastId(); + listener.onItemClick(broadcastId); + } + }); } } } diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanActivity.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanActivity.java index 9475c720e07..52e5cb07017 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanActivity.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanActivity.java @@ -54,129 +54,184 @@ public class BroadcastScanActivity extends AppCompatActivity { recyclerView.setHasFixedSize(true); adapter = new BroadcastItemsAdapter(); - adapter.setOnItemClickListener(broadcastId -> { - mViewModel.scanForBroadcasts(device, false); - - BluetoothLeBroadcastMetadata broadcast = null; - for (BluetoothLeBroadcastMetadata b : mViewModel.getAllBroadcasts().getValue()) { - if (Objects.equals(b.getBroadcastId(), broadcastId)) { - broadcast = b; - break; - } - } - - if (broadcast == null) { - Toast.makeText(recyclerView.getContext(), "Matching broadcast not found." - + " broadcastId=" + broadcastId, Toast.LENGTH_SHORT).show(); - return; - } - - // Set broadcast source on peer only if scan delegator device context is available - if (device != null) { - // Start Dialog with the broadcast input details - AlertDialog.Builder alert = new AlertDialog.Builder(this); - LayoutInflater inflater = getLayoutInflater(); - alert.setTitle("Add the Broadcast:"); - - View alertView = - inflater.inflate(R.layout.broadcast_scan_add_encrypted_source_dialog, - null); - - boolean isPublic = broadcast.isPublicBroadcast(); - TextView addr_text = alertView.findViewById(R.id.broadcast_with_pbp_text); - addr_text.setText("Broadcast with PBP: " + (isPublic ? "Yes" : "No")); - - String name = broadcast.getBroadcastName(); - addr_text = alertView.findViewById(R.id.broadcast_name_text); - if (isPublic && name != null) { - addr_text.setText("Public Name: " + name); - } else { - addr_text.setVisibility(View.INVISIBLE); - } - - BluetoothLeAudioContentMetadata publicMetadata = - broadcast.getPublicBroadcastMetadata(); - addr_text = alertView.findViewById(R.id.public_program_info_text); - if (isPublic && publicMetadata != null) { - addr_text.setText("Public Info: " + publicMetadata.getProgramInfo()); - } else { - addr_text.setVisibility(View.INVISIBLE); - } - - final EditText channels_input_text = - alertView.findViewById(R.id.broadcast_channel_map); - - final EditText code_input_text = - alertView.findViewById(R.id.broadcast_code_input); - BluetoothLeBroadcastMetadata.Builder builder = new - BluetoothLeBroadcastMetadata.Builder(broadcast); - - alert.setView(alertView).setNegativeButton("Cancel", (dialog, which) -> { - // Do nothing - }).setPositiveButton("Add", (dialog, which) -> { - BluetoothLeBroadcastMetadata metadata; - if (code_input_text.getText() == null) { - Toast.makeText(recyclerView.getContext(), "Invalid broadcast code", - Toast.LENGTH_SHORT).show(); - return; - } - if (code_input_text.getText().length() == 0) { - Toast.makeText(recyclerView.getContext(), "Adding not encrypted broadcast " - + "source broadcastId=" - + broadcastId, Toast.LENGTH_SHORT).show(); - metadata = builder.setEncrypted(false).build(); - } else { - if ((code_input_text.getText().length() > 16) || - (code_input_text.getText().length() < 4)) { - Toast.makeText(recyclerView.getContext(), - "Invalid Broadcast code length", - Toast.LENGTH_SHORT).show(); - - return; + adapter.setOnItemClickListener( + broadcastId -> { + mViewModel.scanForBroadcasts(device, false); + + BluetoothLeBroadcastMetadata broadcast = null; + for (BluetoothLeBroadcastMetadata b : + mViewModel.getAllBroadcasts().getValue()) { + if (Objects.equals(b.getBroadcastId(), broadcastId)) { + broadcast = b; + break; } + } - metadata = builder.setBroadcastCode( - code_input_text.getText().toString().getBytes()) - .setEncrypted(true) - .build(); + if (broadcast == null) { + Toast.makeText( + recyclerView.getContext(), + "Matching broadcast not found." + + " broadcastId=" + + broadcastId, + Toast.LENGTH_SHORT) + .show(); + return; } - if ((channels_input_text.getText() != null) - && (channels_input_text.getText().length() != 0)) { - int channelMap = Integer.parseInt(channels_input_text.getText().toString()); - // Apply a single channel map preference to all subgroups - for (BluetoothLeBroadcastSubgroup subGroup : metadata.getSubgroups()) { - List channels = subGroup.getChannels(); - for (int i = 0; i < channels.size(); i++) { - BluetoothLeBroadcastChannel channel = channels.get(i); - // Set the channel preference value according to the map - if (channel.getChannelIndex() != 0) { - if ((channelMap & (1 << (channel.getChannelIndex() - 1))) != 0) { - BluetoothLeBroadcastChannel.Builder bob - = new BluetoothLeBroadcastChannel.Builder(channel); - bob.setSelected(true); - channels.set(i, bob.build()); - } - } - } + // Set broadcast source on peer only if scan delegator device context is + // available + if (device != null) { + // Start Dialog with the broadcast input details + AlertDialog.Builder alert = new AlertDialog.Builder(this); + LayoutInflater inflater = getLayoutInflater(); + alert.setTitle("Add the Broadcast:"); + + View alertView = + inflater.inflate( + R.layout.broadcast_scan_add_encrypted_source_dialog, null); + + boolean isPublic = broadcast.isPublicBroadcast(); + TextView addr_text = alertView.findViewById(R.id.broadcast_with_pbp_text); + addr_text.setText("Broadcast with PBP: " + (isPublic ? "Yes" : "No")); + + String name = broadcast.getBroadcastName(); + addr_text = alertView.findViewById(R.id.broadcast_name_text); + if (isPublic && name != null) { + addr_text.setText("Public Name: " + name); + } else { + addr_text.setVisibility(View.INVISIBLE); } - } - Toast.makeText(recyclerView.getContext(), "Adding broadcast source" - + " broadcastId=" + broadcastId, Toast.LENGTH_SHORT).show(); - mViewModel.addBroadcastSource(device, metadata); - }); + BluetoothLeAudioContentMetadata publicMetadata = + broadcast.getPublicBroadcastMetadata(); + addr_text = alertView.findViewById(R.id.public_program_info_text); + if (isPublic && publicMetadata != null) { + addr_text.setText("Public Info: " + publicMetadata.getProgramInfo()); + } else { + addr_text.setVisibility(View.INVISIBLE); + } + + final EditText channels_input_text = + alertView.findViewById(R.id.broadcast_channel_map); + + final EditText code_input_text = + alertView.findViewById(R.id.broadcast_code_input); + BluetoothLeBroadcastMetadata.Builder builder = + new BluetoothLeBroadcastMetadata.Builder(broadcast); + + alert.setView(alertView) + .setNegativeButton( + "Cancel", + (dialog, which) -> { + // Do nothing + }) + .setPositiveButton( + "Add", + (dialog, which) -> { + BluetoothLeBroadcastMetadata metadata; + if (code_input_text.getText() == null) { + Toast.makeText( + recyclerView.getContext(), + "Invalid broadcast code", + Toast.LENGTH_SHORT) + .show(); + return; + } + if (code_input_text.getText().length() == 0) { + Toast.makeText( + recyclerView.getContext(), + "Adding not encrypted broadcast " + + "source broadcastId=" + + broadcastId, + Toast.LENGTH_SHORT) + .show(); + metadata = builder.setEncrypted(false).build(); + } else { + if ((code_input_text.getText().length() > 16) + || (code_input_text.getText().length() + < 4)) { + Toast.makeText( + recyclerView.getContext(), + "Invalid Broadcast code length", + Toast.LENGTH_SHORT) + .show(); + + return; + } - alert.show(); - } - }); + metadata = + builder.setBroadcastCode( + code_input_text + .getText() + .toString() + .getBytes()) + .setEncrypted(true) + .build(); + } + + if ((channels_input_text.getText() != null) + && (channels_input_text.getText().length() + != 0)) { + int channelMap = + Integer.parseInt( + channels_input_text + .getText() + .toString()); + // Apply a single channel map preference to all + // subgroups + for (BluetoothLeBroadcastSubgroup subGroup : + metadata.getSubgroups()) { + List channels = + subGroup.getChannels(); + for (int i = 0; i < channels.size(); i++) { + BluetoothLeBroadcastChannel channel = + channels.get(i); + // Set the channel preference value + // according to the map + if (channel.getChannelIndex() != 0) { + if ((channelMap + & (1 + << (channel + .getChannelIndex() + - 1))) + != 0) { + BluetoothLeBroadcastChannel.Builder + bob = + new BluetoothLeBroadcastChannel + .Builder( + channel); + bob.setSelected(true); + channels.set(i, bob.build()); + } + } + } + } + } + + Toast.makeText( + recyclerView.getContext(), + "Adding broadcast source" + + " broadcastId=" + + broadcastId, + Toast.LENGTH_SHORT) + .show(); + mViewModel.addBroadcastSource(device, metadata); + }); + + alert.show(); + } + }); recyclerView.setAdapter(adapter); mViewModel = ViewModelProviders.of(this).get(BroadcastScanViewModel.class); - mViewModel.getAllBroadcasts().observe(this, audioBroadcasts -> { - // Update Broadcast list in the adapter - adapter.setBroadcasts(audioBroadcasts); - }); + mViewModel + .getAllBroadcasts() + .observe( + this, + audioBroadcasts -> { + // Update Broadcast list in the adapter + adapter.setBroadcasts(audioBroadcasts); + }); Intent intent = getIntent(); device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanViewModel.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanViewModel.java index 85df5c71750..a5dee02825a 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanViewModel.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcastScanViewModel.java @@ -36,78 +36,80 @@ public class BroadcastScanViewModel extends AndroidViewModel { BluetoothDevice mScanDelegatorDevice; // TODO: Remove these variables if they are unnecessary -// // AddBroadcast context -// BluetoothDevice mSetSrcTargetDevice; -// List mSetSrcConfigs; -// boolean mSetSrcSyncPa; + // // AddBroadcast context + // BluetoothDevice mSetSrcTargetDevice; + // List mSetSrcConfigs; + // boolean mSetSrcSyncPa; BluetoothProxy mBluetooth; Application mApplication; - private MutableLiveData> mAllBroadcasts = new MutableLiveData<>(); + private MutableLiveData> mAllBroadcasts = + new MutableLiveData<>(); private HashMap mScanSessionBroadcasts = new HashMap<>(); private final BluetoothProxy.OnBassEventListener mBassEventListener = new BluetoothProxy.OnBassEventListener() { - @Override - public void onSourceFound(BluetoothLeBroadcastMetadata source) { - mScanSessionBroadcasts.put(source.getBroadcastId(), source); - refreshBroadcasts(); - } - - @Override - public void onScanningStateChanged(boolean isScanning) { - if (!isScanning) { - // Update the live broadcast list and clear scan session results - List localSessionBroadcasts = - mBluetooth.getAllLocalBroadcasts(); - ArrayList new_arr; - if (localSessionBroadcasts != null) { - new_arr = new ArrayList<>(localSessionBroadcasts); - } else { - new_arr = new ArrayList<>(); + @Override + public void onSourceFound(BluetoothLeBroadcastMetadata source) { + mScanSessionBroadcasts.put(source.getBroadcastId(), source); + refreshBroadcasts(); } - new_arr.addAll(mScanSessionBroadcasts.values()); - mAllBroadcasts.postValue(new_arr); - // Continue as long as the main activity wants - if (mIsActivityScanning) { - if (mScanDelegatorDevice != null) { - mBluetooth.scanForBroadcasts(mScanDelegatorDevice, true); + @Override + public void onScanningStateChanged(boolean isScanning) { + if (!isScanning) { + // Update the live broadcast list and clear scan session results + List localSessionBroadcasts = + mBluetooth.getAllLocalBroadcasts(); + ArrayList new_arr; + if (localSessionBroadcasts != null) { + new_arr = new ArrayList<>(localSessionBroadcasts); + } else { + new_arr = new ArrayList<>(); + } + new_arr.addAll(mScanSessionBroadcasts.values()); + mAllBroadcasts.postValue(new_arr); + + // Continue as long as the main activity wants + if (mIsActivityScanning) { + if (mScanDelegatorDevice != null) { + mBluetooth.scanForBroadcasts(mScanDelegatorDevice, true); + } + } + } else { + // FIXME: Clear won't work - it would auto-update the mutable and clear it + // as + // mutable uses reference to its values + mScanSessionBroadcasts = new HashMap<>(); } } - } else { - // FIXME: Clear won't work - it would auto-update the mutable and clear it as - // mutable uses reference to its values - mScanSessionBroadcasts = new HashMap<>(); - } - } - }; + }; private final BluetoothProxy.OnLocalBroadcastEventListener mLocalBroadcastEventListener = new BluetoothProxy.OnLocalBroadcastEventListener() { - @Override - public void onBroadcastStarted(int broadcastId) { - // FIXME: We need a finer grain control over updating individual broadcast state - // and not just the entire list of broadcasts - refreshBroadcasts(); - } + @Override + public void onBroadcastStarted(int broadcastId) { + // FIXME: We need a finer grain control over updating individual broadcast state + // and not just the entire list of broadcasts + refreshBroadcasts(); + } - @Override - public void onBroadcastStopped(int broadcastId) { - refreshBroadcasts(); - } + @Override + public void onBroadcastStopped(int broadcastId) { + refreshBroadcasts(); + } - @Override - public void onBroadcastUpdated(int broadcastId) { - refreshBroadcasts(); - } + @Override + public void onBroadcastUpdated(int broadcastId) { + refreshBroadcasts(); + } - @Override - public void onBroadcastMetadataChanged(int broadcastId, - BluetoothLeBroadcastMetadata metadata) { - refreshBroadcasts(); - } - }; + @Override + public void onBroadcastMetadataChanged( + int broadcastId, BluetoothLeBroadcastMetadata metadata) { + refreshBroadcasts(); + } + }; public BroadcastScanViewModel(@NonNull Application application) { super(application); @@ -147,7 +149,8 @@ public class BroadcastScanViewModel extends AndroidViewModel { mBluetooth.scanForBroadcasts(mScanDelegatorDevice, scan); } - public void addBroadcastSource(BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata) { + public void addBroadcastSource( + BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata) { mBluetooth.addBroadcastSource(sink, sourceMetadata); } @@ -155,8 +158,7 @@ public class BroadcastScanViewModel extends AndroidViewModel { // Concatenate local broadcasts to the scanned broadcast list List localSessionBroadcasts = mBluetooth.getAllLocalBroadcasts(); - ArrayList new_arr = new ArrayList<>( - localSessionBroadcasts); + ArrayList new_arr = new ArrayList<>(localSessionBroadcasts); new_arr.addAll(mScanSessionBroadcasts.values()); mAllBroadcasts.postValue(new_arr); } diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterActivity.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterActivity.java index f0e644c2b68..a86623bfc7f 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterActivity.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterActivity.java @@ -404,50 +404,97 @@ public class BroadcasterActivity extends AppCompatActivity { itemsAdapter.updateBroadcastsMetadata(metadata.isEmpty() ? new ArrayList<>() : metadata); // Put a watch on updates - mViewModel.getBroadcastUpdateMetadataLive().observe(this, audioBroadcast -> { - itemsAdapter.updateBroadcastMetadata(audioBroadcast); - - Toast.makeText(BroadcasterActivity.this, - "Updated broadcast " + audioBroadcast.getBroadcastId(), Toast.LENGTH_SHORT) - .show(); - }); + mViewModel + .getBroadcastUpdateMetadataLive() + .observe( + this, + audioBroadcast -> { + itemsAdapter.updateBroadcastMetadata(audioBroadcast); + + Toast.makeText( + BroadcasterActivity.this, + "Updated broadcast " + audioBroadcast.getBroadcastId(), + Toast.LENGTH_SHORT) + .show(); + }); // Put a watch on any error reports - mViewModel.getBroadcastStatusMutableLive().observe(this, msg -> { - Toast.makeText(BroadcasterActivity.this, msg, Toast.LENGTH_SHORT).show(); - }); + mViewModel + .getBroadcastStatusMutableLive() + .observe( + this, + msg -> { + Toast.makeText(BroadcasterActivity.this, msg, Toast.LENGTH_SHORT) + .show(); + }); // Put a watch on broadcast playback states - mViewModel.getBroadcastPlaybackStartedMutableLive().observe(this, reasonAndBidPair -> { - Toast.makeText(BroadcasterActivity.this, "Playing broadcast " + reasonAndBidPair.second - + ", reason " + reasonAndBidPair.first, Toast.LENGTH_SHORT).show(); - - itemsAdapter.updateBroadcastPlayback(reasonAndBidPair.second, true); - }); - - mViewModel.getBroadcastPlaybackStoppedMutableLive().observe(this, reasonAndBidPair -> { - Toast.makeText(BroadcasterActivity.this, "Paused broadcast " + reasonAndBidPair.second - + ", reason " + reasonAndBidPair.first, Toast.LENGTH_SHORT).show(); - - itemsAdapter.updateBroadcastPlayback(reasonAndBidPair.second, false); - }); - - mViewModel.getBroadcastAddedMutableLive().observe(this, broadcastId -> { - itemsAdapter.addBroadcasts(broadcastId); - - Toast.makeText(BroadcasterActivity.this, - "Broadcast was added broadcastId: " + broadcastId, Toast.LENGTH_SHORT).show(); - }); + mViewModel + .getBroadcastPlaybackStartedMutableLive() + .observe( + this, + reasonAndBidPair -> { + Toast.makeText( + BroadcasterActivity.this, + "Playing broadcast " + + reasonAndBidPair.second + + ", reason " + + reasonAndBidPair.first, + Toast.LENGTH_SHORT) + .show(); + + itemsAdapter.updateBroadcastPlayback(reasonAndBidPair.second, true); + }); + + mViewModel + .getBroadcastPlaybackStoppedMutableLive() + .observe( + this, + reasonAndBidPair -> { + Toast.makeText( + BroadcasterActivity.this, + "Paused broadcast " + + reasonAndBidPair.second + + ", reason " + + reasonAndBidPair.first, + Toast.LENGTH_SHORT) + .show(); + + itemsAdapter.updateBroadcastPlayback(reasonAndBidPair.second, false); + }); + + mViewModel + .getBroadcastAddedMutableLive() + .observe( + this, + broadcastId -> { + itemsAdapter.addBroadcasts(broadcastId); + + Toast.makeText( + BroadcasterActivity.this, + "Broadcast was added broadcastId: " + broadcastId, + Toast.LENGTH_SHORT) + .show(); + }); // Put a watch on broadcast removal - mViewModel.getBroadcastRemovedMutableLive().observe(this, reasonAndBidPair -> { - itemsAdapter.removeBroadcast(reasonAndBidPair.second); - - Toast.makeText( - BroadcasterActivity.this, "Broadcast was removed " + " broadcastId: " - + reasonAndBidPair.second + ", reason: " + reasonAndBidPair.first, - Toast.LENGTH_SHORT).show(); - }); + mViewModel + .getBroadcastRemovedMutableLive() + .observe( + this, + reasonAndBidPair -> { + itemsAdapter.removeBroadcast(reasonAndBidPair.second); + + Toast.makeText( + BroadcasterActivity.this, + "Broadcast was removed " + + " broadcastId: " + + reasonAndBidPair.second + + ", reason: " + + reasonAndBidPair.first, + Toast.LENGTH_SHORT) + .show(); + }); // Prevent destruction when loses focus this.setFinishOnTouchOutside(false); diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterViewModel.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterViewModel.java index e1beea3d2d6..03a4e101456 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterViewModel.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/BroadcasterViewModel.java @@ -68,11 +68,13 @@ public class BroadcasterViewModel extends AndroidViewModel { return mBluetooth.getBroadcastUpdateMetadataLive(); } - public LiveData> getBroadcastPlaybackStartedMutableLive() { + public LiveData> + getBroadcastPlaybackStartedMutableLive() { return mBluetooth.getBroadcastPlaybackStartedMutableLive(); } - public LiveData> getBroadcastPlaybackStoppedMutableLive() { + public LiveData> + getBroadcastPlaybackStoppedMutableLive() { return mBluetooth.getBroadcastPlaybackStoppedMutableLive(); } @@ -80,7 +82,8 @@ public class BroadcasterViewModel extends AndroidViewModel { return mBluetooth.getBroadcastAddedMutableLive(); } - public LiveData> getBroadcastRemovedMutableLive() { + public LiveData> + getBroadcastRemovedMutableLive() { return mBluetooth.getBroadcastRemovedMutableLive(); } diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioDeviceStateWrapper.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioDeviceStateWrapper.java index 748bd39fa3f..e181c94b9c2 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioDeviceStateWrapper.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioDeviceStateWrapper.java @@ -30,82 +30,80 @@ import java.util.Map; import java.util.TreeMap; public class LeAudioDeviceStateWrapper { - public BluetoothDevice device; - public LeAudioData leAudioData = null; - public VolumeControlData volumeControlData = null; - public BassData bassData = null; - public HapData hapData = null; - - public LeAudioDeviceStateWrapper(BluetoothDevice device) { - this.device = device; - } - - public static class LeAudioData { - public MutableLiveData isConnectedMutable = new MutableLiveData<>(); - public MutableLiveData> nodeStatusMutable = - new MutableLiveData<>(); - public MutableLiveData>> groupStatusMutable = - new MutableLiveData<>(); - public MutableLiveData> groupLockStateMutable = - new MutableLiveData<>(); - public MutableLiveData microphoneStateMutable = new MutableLiveData<>(); - - public Object viewsData = null; - } - - public static class HapData { - public MutableLiveData hapStateMutable = new MutableLiveData<>(); - public MutableLiveData hapStatusMutable = new MutableLiveData<>(); - public MutableLiveData hapFeaturesMutable = new MutableLiveData<>(); - public MutableLiveData hapActivePresetIndexMutable = - new MutableLiveData<>(); - public MutableLiveData> hapPresetsMutable = - new MutableLiveData<>(); - - public Object viewsData = null; - } - - public static class VolumeControlData { - public MutableLiveData isConnectedMutable = new MutableLiveData<>(false); - public MutableLiveData numInputsMutable = new MutableLiveData<>(0); - public MutableLiveData numOffsetsMutable = new MutableLiveData<>(0); - public MutableLiveData volumeStateMutable = new MutableLiveData<>(0); - public MutableLiveData mutedStateMutable = new MutableLiveData<>(false); - - public MutableLiveData> inputDescriptionsMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStateGainMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStateGainModeMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStateGainUnitMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStateGainMinMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStateGainMaxMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStateMuteMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputStatusMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> inputTypeMutable = - new MutableLiveData<>(new TreeMap<>()); - - public MutableLiveData> outputVolumeOffsetMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> outputLocationMutable = - new MutableLiveData<>(new TreeMap<>()); - public MutableLiveData> outputDescriptionMutable = - new MutableLiveData<>(new TreeMap<>()); - - public Object viewsData = null; - } - - public static class BassData { - public MutableLiveData isConnectedMutable = new MutableLiveData<>(); - public MutableLiveData> - receiverStatesMutable = new MutableLiveData<>(); - - public Object viewsData = null; - } + public BluetoothDevice device; + public LeAudioData leAudioData = null; + public VolumeControlData volumeControlData = null; + public BassData bassData = null; + public HapData hapData = null; + + public LeAudioDeviceStateWrapper(BluetoothDevice device) { + this.device = device; + } + + public static class LeAudioData { + public MutableLiveData isConnectedMutable = new MutableLiveData<>(); + public MutableLiveData> nodeStatusMutable = new MutableLiveData<>(); + public MutableLiveData>> groupStatusMutable = + new MutableLiveData<>(); + public MutableLiveData> groupLockStateMutable = + new MutableLiveData<>(); + public MutableLiveData microphoneStateMutable = new MutableLiveData<>(); + + public Object viewsData = null; + } + + public static class HapData { + public MutableLiveData hapStateMutable = new MutableLiveData<>(); + public MutableLiveData hapStatusMutable = new MutableLiveData<>(); + public MutableLiveData hapFeaturesMutable = new MutableLiveData<>(); + public MutableLiveData hapActivePresetIndexMutable = new MutableLiveData<>(); + public MutableLiveData> hapPresetsMutable = + new MutableLiveData<>(); + + public Object viewsData = null; + } + + public static class VolumeControlData { + public MutableLiveData isConnectedMutable = new MutableLiveData<>(false); + public MutableLiveData numInputsMutable = new MutableLiveData<>(0); + public MutableLiveData numOffsetsMutable = new MutableLiveData<>(0); + public MutableLiveData volumeStateMutable = new MutableLiveData<>(0); + public MutableLiveData mutedStateMutable = new MutableLiveData<>(false); + + public MutableLiveData> inputDescriptionsMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStateGainMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStateGainModeMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStateGainUnitMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStateGainMinMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStateGainMaxMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStateMuteMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputStatusMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> inputTypeMutable = + new MutableLiveData<>(new TreeMap<>()); + + public MutableLiveData> outputVolumeOffsetMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> outputLocationMutable = + new MutableLiveData<>(new TreeMap<>()); + public MutableLiveData> outputDescriptionMutable = + new MutableLiveData<>(new TreeMap<>()); + + public Object viewsData = null; + } + + public static class BassData { + public MutableLiveData isConnectedMutable = new MutableLiveData<>(); + public MutableLiveData> + receiverStatesMutable = new MutableLiveData<>(); + + public Object viewsData = null; + } } diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioRecycleViewAdapter.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioRecycleViewAdapter.java index e19d60e00cc..971cf710706 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioRecycleViewAdapter.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioRecycleViewAdapter.java @@ -90,8 +90,9 @@ public class LeAudioRecycleViewAdapter @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.le_audio_device_fragment, - parent, false); + View v = + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.le_audio_device_fragment, parent, false); return new ViewHolder(v); } @@ -103,28 +104,51 @@ public class LeAudioRecycleViewAdapter LeAudioDeviceStateWrapper leAudioDeviceStateWrapper = devices.get(position); if (leAudioDeviceStateWrapper != null) { - holder.deviceName.setText(parent.getString(R.string.notes_icon) + " " - + leAudioDeviceStateWrapper.device.getName() + " [" - + leAudioDeviceStateWrapper.device + "]"); + holder.deviceName.setText( + parent.getString(R.string.notes_icon) + + " " + + leAudioDeviceStateWrapper.device.getName() + + " [" + + leAudioDeviceStateWrapper.device + + "]"); if (leAudioDeviceStateWrapper.device.getUuids() != null) { - holder.itemView.findViewById(R.id.le_audio_switch) - .setEnabled(Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) - .contains(ParcelUuid - .fromString(parent.getString(R.string.svc_uuid_le_audio)))); - - holder.itemView.findViewById(R.id.vc_switch) - .setEnabled(Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) - .contains(ParcelUuid.fromString( - parent.getString(R.string.svc_uuid_volume_control)))); - - holder.itemView.findViewById(R.id.hap_switch).setEnabled( - Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()).contains( - ParcelUuid.fromString(parent.getString(R.string.svc_uuid_has)))); - - holder.itemView.findViewById(R.id.bass_switch) - .setEnabled(Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) - .contains(ParcelUuid.fromString(parent.getString(R.string.svc_uuid_broadcast_audio)))); + holder.itemView + .findViewById(R.id.le_audio_switch) + .setEnabled( + Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) + .contains( + ParcelUuid.fromString( + parent.getString( + R.string.svc_uuid_le_audio)))); + + holder.itemView + .findViewById(R.id.vc_switch) + .setEnabled( + Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) + .contains( + ParcelUuid.fromString( + parent.getString( + R.string + .svc_uuid_volume_control)))); + + holder.itemView + .findViewById(R.id.hap_switch) + .setEnabled( + Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) + .contains( + ParcelUuid.fromString( + parent.getString(R.string.svc_uuid_has)))); + + holder.itemView + .findViewById(R.id.bass_switch) + .setEnabled( + Arrays.asList(leAudioDeviceStateWrapper.device.getUuids()) + .contains( + ParcelUuid.fromString( + parent.getString( + R.string + .svc_uuid_broadcast_audio)))); } } @@ -137,67 +161,82 @@ public class LeAudioRecycleViewAdapter setBassUiStateObservers(holder, leAudioDeviceStateWrapper); } - private void setLeAudioStateObservers(@NonNull ViewHolder holder, - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { + private void setLeAudioStateObservers( + @NonNull ViewHolder holder, LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { LeAudioDeviceStateWrapper.LeAudioData le_audio_svc_data = leAudioDeviceStateWrapper.leAudioData; if (le_audio_svc_data != null) { if (le_audio_svc_data.isConnectedMutable.hasObservers()) le_audio_svc_data.isConnectedMutable.removeObservers(this.parent); - le_audio_svc_data.isConnectedMutable.observe(this.parent, is_connected -> { - // FIXME: How to prevent the callback from firing when we set this by code - if (is_connected != holder.leAudioConnectionSwitch.isChecked()) { - holder.leAudioConnectionSwitch.setActivated(false); - holder.leAudioConnectionSwitch.setChecked(is_connected); - holder.leAudioConnectionSwitch.setActivated(true); - } - - if (holder.itemView.findViewById(R.id.le_audio_layout) - .getVisibility() != (is_connected ? View.VISIBLE : View.GONE)) - holder.itemView.findViewById(R.id.le_audio_layout) - .setVisibility(is_connected ? View.VISIBLE : View.GONE); - }); - - holder.itemView.findViewById(R.id.le_audio_layout) - .setVisibility(le_audio_svc_data.isConnectedMutable.getValue() != null - && le_audio_svc_data.isConnectedMutable.getValue() ? View.VISIBLE + le_audio_svc_data.isConnectedMutable.observe( + this.parent, + is_connected -> { + // FIXME: How to prevent the callback from firing when we set this by code + if (is_connected != holder.leAudioConnectionSwitch.isChecked()) { + holder.leAudioConnectionSwitch.setActivated(false); + holder.leAudioConnectionSwitch.setChecked(is_connected); + holder.leAudioConnectionSwitch.setActivated(true); + } + + if (holder.itemView.findViewById(R.id.le_audio_layout).getVisibility() + != (is_connected ? View.VISIBLE : View.GONE)) + holder.itemView + .findViewById(R.id.le_audio_layout) + .setVisibility(is_connected ? View.VISIBLE : View.GONE); + }); + + holder.itemView + .findViewById(R.id.le_audio_layout) + .setVisibility( + le_audio_svc_data.isConnectedMutable.getValue() != null + && le_audio_svc_data.isConnectedMutable.getValue() + ? View.VISIBLE : View.GONE); if (le_audio_svc_data.nodeStatusMutable.hasObservers()) le_audio_svc_data.nodeStatusMutable.removeObservers(this.parent); - le_audio_svc_data.nodeStatusMutable.observe(this.parent, group_id_node_status_pair -> { - final Integer status = group_id_node_status_pair.second; - final Integer group_id = group_id_node_status_pair.first; + le_audio_svc_data.nodeStatusMutable.observe( + this.parent, + group_id_node_status_pair -> { + final Integer status = group_id_node_status_pair.second; + final Integer group_id = group_id_node_status_pair.first; - if (status == GROUP_NODE_REMOVED) - holder.leAudioGroupIdText - .setText(((Integer) BluetoothLeAudio.GROUP_ID_INVALID).toString()); - else - holder.leAudioGroupIdText.setText(group_id.toString()); - }); + if (status == GROUP_NODE_REMOVED) + holder.leAudioGroupIdText.setText( + ((Integer) BluetoothLeAudio.GROUP_ID_INVALID).toString()); + else holder.leAudioGroupIdText.setText(group_id.toString()); + }); if (le_audio_svc_data.groupStatusMutable.hasObservers()) le_audio_svc_data.groupStatusMutable.removeObservers(this.parent); - le_audio_svc_data.groupStatusMutable.observe(this.parent, group_id_node_status_pair -> { - final Integer group_id = group_id_node_status_pair.first; - final Integer status = group_id_node_status_pair.second.first; - final Integer flags = group_id_node_status_pair.second.second; - - // If our group.. actually we shouldn't get this event if it's nor ours, - // right? - if (holder.leAudioGroupIdText.getText().equals(group_id.toString())) { - holder.leAudioGroupStatusText.setText(status >= 0 - ? this.parent.getResources() - .getStringArray(R.array.group_statuses)[status] - : this.parent.getResources().getString(R.string.unknown)); - holder.leAudioGroupFlagsText.setText(flags > 0 ? flags.toString() - : this.parent.getResources().getString(R.string.none)); - } - }); + le_audio_svc_data.groupStatusMutable.observe( + this.parent, + group_id_node_status_pair -> { + final Integer group_id = group_id_node_status_pair.first; + final Integer status = group_id_node_status_pair.second.first; + final Integer flags = group_id_node_status_pair.second.second; + + // If our group.. actually we shouldn't get this event if it's nor ours, + // right? + if (holder.leAudioGroupIdText.getText().equals(group_id.toString())) { + holder.leAudioGroupStatusText.setText( + status >= 0 + ? this.parent.getResources() + .getStringArray(R.array.group_statuses)[status] + : this.parent + .getResources() + .getString(R.string.unknown)); + holder.leAudioGroupFlagsText.setText( + flags > 0 + ? flags.toString() + : this.parent.getResources().getString(R.string.none)); + } + }); if (le_audio_svc_data.groupLockStateMutable.hasObservers()) le_audio_svc_data.groupLockStateMutable.removeObservers(this.parent); - le_audio_svc_data.groupLockStateMutable.observe(this.parent, + le_audio_svc_data.groupLockStateMutable.observe( + this.parent, group_id_node_status_pair -> { final Integer group_id = group_id_node_status_pair.first; final Boolean locked = group_id_node_status_pair.second; @@ -205,398 +244,522 @@ public class LeAudioRecycleViewAdapter // If our group.. actually we shouldn't get this event if it's nor ours, // right? if (holder.leAudioGroupIdText.getText().equals(group_id.toString())) { - holder.leAudioSetLockStateText.setText(this.parent.getResources() - .getString(locked ? R.string.group_locked - : R.string.group_unlocked)); + holder.leAudioSetLockStateText.setText( + this.parent + .getResources() + .getString( + locked + ? R.string.group_locked + : R.string.group_unlocked)); } }); if (le_audio_svc_data.microphoneStateMutable.hasObservers()) le_audio_svc_data.microphoneStateMutable.removeObservers(this.parent); - le_audio_svc_data.microphoneStateMutable.observe(this.parent, microphone_state -> { - holder.leAudioGroupMicrophoneState.setText(this.parent.getResources() - .getStringArray(R.array.mic_states)[microphone_state]); - holder.leAudioGroupMicrophoneSwitch.setActivated(false); - }); + le_audio_svc_data.microphoneStateMutable.observe( + this.parent, + microphone_state -> { + holder.leAudioGroupMicrophoneState.setText( + this.parent.getResources() + .getStringArray(R.array.mic_states)[microphone_state]); + holder.leAudioGroupMicrophoneSwitch.setActivated(false); + }); } } - private void setHasStateObservers(@NonNull ViewHolder holder, - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { + private void setHasStateObservers( + @NonNull ViewHolder holder, LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { LeAudioDeviceStateWrapper.HapData hap_svc_data = leAudioDeviceStateWrapper.hapData; if (hap_svc_data != null) { if (hap_svc_data.hapStateMutable.hasObservers()) hap_svc_data.hapStateMutable.removeObservers(this.parent); - hap_svc_data.hapStateMutable.observe(this.parent, hap_state -> { - holder.leAudioHapState.setText(this.parent.getResources() - .getStringArray(R.array.profile_states)[hap_state]); - - boolean is_connected = (hap_state == BluetoothHapClient.STATE_CONNECTED); - if (is_connected != holder.hapConnectionSwitch.isChecked()) { - holder.hapConnectionSwitch.setActivated(false); - holder.hapConnectionSwitch.setChecked(is_connected); - holder.hapConnectionSwitch.setActivated(true); - } - - if (holder.itemView.findViewById(R.id.hap_layout) - .getVisibility() != (is_connected ? View.VISIBLE : View.GONE)) - holder.itemView.findViewById(R.id.hap_layout) - .setVisibility(is_connected ? View.VISIBLE : View.GONE); - }); + hap_svc_data.hapStateMutable.observe( + this.parent, + hap_state -> { + holder.leAudioHapState.setText( + this.parent.getResources() + .getStringArray(R.array.profile_states)[hap_state]); + + boolean is_connected = (hap_state == BluetoothHapClient.STATE_CONNECTED); + if (is_connected != holder.hapConnectionSwitch.isChecked()) { + holder.hapConnectionSwitch.setActivated(false); + holder.hapConnectionSwitch.setChecked(is_connected); + holder.hapConnectionSwitch.setActivated(true); + } + + if (holder.itemView.findViewById(R.id.hap_layout).getVisibility() + != (is_connected ? View.VISIBLE : View.GONE)) + holder.itemView + .findViewById(R.id.hap_layout) + .setVisibility(is_connected ? View.VISIBLE : View.GONE); + }); if (hap_svc_data.hapFeaturesMutable.hasObservers()) hap_svc_data.hapFeaturesMutable.removeObservers(this.parent); - hap_svc_data.hapFeaturesMutable.observe(this.parent, features -> { - try { - // Get hidden feature bits - Field field = - BluetoothHapClient.class.getDeclaredField("FEATURE_TYPE_MONAURAL"); - field.setAccessible(true); - Integer FEATURE_TYPE_MONAURAL = (Integer) field.get(null); - - field = BluetoothHapClient.class.getDeclaredField("FEATURE_TYPE_BANDED"); - field.setAccessible(true); - Integer FEATURE_TYPE_BANDED = (Integer) field.get(null); - - field = BluetoothHapClient.class - .getDeclaredField("FEATURE_SYNCHRONIZATED_PRESETS"); - field.setAccessible(true); - Integer FEATURE_SYNCHRONIZATED_PRESETS = (Integer) field.get(null); - - field = BluetoothHapClient.class - .getDeclaredField("FEATURE_INDEPENDENT_PRESETS"); - field.setAccessible(true); - Integer FEATURE_INDEPENDENT_PRESETS = (Integer) field.get(null); - - field = BluetoothHapClient.class.getDeclaredField("FEATURE_DYNAMIC_PRESETS"); - field.setAccessible(true); - Integer FEATURE_DYNAMIC_PRESETS = (Integer) field.get(null); - - field = BluetoothHapClient.class.getDeclaredField("FEATURE_WRITABLE_PRESETS"); - field.setAccessible(true); - Integer FEATURE_WRITABLE_PRESETS = (Integer) field.get(null); - - int hearing_aid_type_idx = (features & FEATURE_TYPE_MONAURAL) != 0 ? 0 - : ((features & FEATURE_TYPE_BANDED) != 0 ? 1 : 2); - String hearing_aid_type = this.parent.getResources() - .getStringArray(R.array.hearing_aid_types)[hearing_aid_type_idx]; - String preset_synchronization_support = this.parent.getResources() - .getStringArray(R.array.preset_synchronization_support)[(features - & FEATURE_SYNCHRONIZATED_PRESETS) != 0 ? 1 : 0]; - String independent_presets = this.parent.getResources() - .getStringArray(R.array.independent_presets)[(features - & FEATURE_INDEPENDENT_PRESETS) != 0 ? 1 : 0]; - String dynamic_presets = this.parent.getResources().getStringArray( - R.array.dynamic_presets)[(features & FEATURE_DYNAMIC_PRESETS) != 0 ? 1 - : 0]; - String writable_presets_support = this.parent.getResources() - .getStringArray(R.array.writable_presets_support)[(features - & FEATURE_WRITABLE_PRESETS) != 0 ? 1 : 0]; - holder.leAudioHapFeatures.setText(hearing_aid_type + " / " - + preset_synchronization_support + " / " + independent_presets + " / " - + dynamic_presets + " / " + writable_presets_support); - - } catch (IllegalAccessException | NoSuchFieldException e) { - // Do nothing - holder.leAudioHapFeatures.setText("Hidden API for feature fields unavailable."); - } - }); + hap_svc_data.hapFeaturesMutable.observe( + this.parent, + features -> { + try { + // Get hidden feature bits + Field field = + BluetoothHapClient.class.getDeclaredField( + "FEATURE_TYPE_MONAURAL"); + field.setAccessible(true); + Integer FEATURE_TYPE_MONAURAL = (Integer) field.get(null); + + field = + BluetoothHapClient.class.getDeclaredField( + "FEATURE_TYPE_BANDED"); + field.setAccessible(true); + Integer FEATURE_TYPE_BANDED = (Integer) field.get(null); + + field = + BluetoothHapClient.class.getDeclaredField( + "FEATURE_SYNCHRONIZATED_PRESETS"); + field.setAccessible(true); + Integer FEATURE_SYNCHRONIZATED_PRESETS = (Integer) field.get(null); + + field = + BluetoothHapClient.class.getDeclaredField( + "FEATURE_INDEPENDENT_PRESETS"); + field.setAccessible(true); + Integer FEATURE_INDEPENDENT_PRESETS = (Integer) field.get(null); + + field = + BluetoothHapClient.class.getDeclaredField( + "FEATURE_DYNAMIC_PRESETS"); + field.setAccessible(true); + Integer FEATURE_DYNAMIC_PRESETS = (Integer) field.get(null); + + field = + BluetoothHapClient.class.getDeclaredField( + "FEATURE_WRITABLE_PRESETS"); + field.setAccessible(true); + Integer FEATURE_WRITABLE_PRESETS = (Integer) field.get(null); + + int hearing_aid_type_idx = + (features & FEATURE_TYPE_MONAURAL) != 0 + ? 0 + : ((features & FEATURE_TYPE_BANDED) != 0 ? 1 : 2); + String hearing_aid_type = + this.parent.getResources() + .getStringArray(R.array.hearing_aid_types)[ + hearing_aid_type_idx]; + String preset_synchronization_support = + this.parent.getResources() + .getStringArray(R.array.preset_synchronization_support)[ + (features & FEATURE_SYNCHRONIZATED_PRESETS) != 0 + ? 1 + : 0]; + String independent_presets = + this.parent.getResources() + .getStringArray(R.array.independent_presets)[ + (features & FEATURE_INDEPENDENT_PRESETS) != 0 ? 1 : 0]; + String dynamic_presets = + this.parent.getResources() + .getStringArray(R.array.dynamic_presets)[ + (features & FEATURE_DYNAMIC_PRESETS) != 0 ? 1 : 0]; + String writable_presets_support = + this.parent.getResources() + .getStringArray(R.array.writable_presets_support)[ + (features & FEATURE_WRITABLE_PRESETS) != 0 ? 1 : 0]; + holder.leAudioHapFeatures.setText( + hearing_aid_type + + " / " + + preset_synchronization_support + + " / " + + independent_presets + + " / " + + dynamic_presets + + " / " + + writable_presets_support); + + } catch (IllegalAccessException | NoSuchFieldException e) { + // Do nothing + holder.leAudioHapFeatures.setText( + "Hidden API for feature fields unavailable."); + } + }); if (hap_svc_data.hapPresetsMutable.hasActiveObservers()) hap_svc_data.hapPresetsMutable.removeObservers(this.parent); - hap_svc_data.hapPresetsMutable.observe(this.parent, hapPresetsList -> { - List all_ids = hapPresetsList.stream() - .map(info -> "" + info.getIndex() + " " + info.getName() - + (info.isWritable() ? " [wr" : " [") - + (info.isAvailable() ? "a]" : "]")) - .collect(Collectors.toList()); - - ArrayAdapter adapter = new ArrayAdapter(this.parent, - android.R.layout.simple_spinner_item, all_ids); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - holder.leAudioHapPresetsSpinner.setAdapter(adapter); - - if (hap_svc_data.viewsData != null) { - Integer select_pos = - ((ViewHolderHapPersistentData) hap_svc_data.viewsData).selectedPresetPositionMutable - .getValue(); - if (select_pos != null) - holder.leAudioHapPresetsSpinner.setSelection(select_pos); - } - }); + hap_svc_data.hapPresetsMutable.observe( + this.parent, + hapPresetsList -> { + List all_ids = + hapPresetsList.stream() + .map( + info -> + "" + + info.getIndex() + + " " + + info.getName() + + (info.isWritable() + ? " [wr" + : " [") + + (info.isAvailable() ? "a]" : "]")) + .collect(Collectors.toList()); + + ArrayAdapter adapter = + new ArrayAdapter( + this.parent, android.R.layout.simple_spinner_item, all_ids); + adapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + holder.leAudioHapPresetsSpinner.setAdapter(adapter); + + if (hap_svc_data.viewsData != null) { + Integer select_pos = + ((ViewHolderHapPersistentData) hap_svc_data.viewsData) + .selectedPresetPositionMutable.getValue(); + if (select_pos != null) + holder.leAudioHapPresetsSpinner.setSelection(select_pos); + } + }); if (hap_svc_data.hapActivePresetIndexMutable.hasObservers()) hap_svc_data.hapActivePresetIndexMutable.removeObservers(this.parent); - hap_svc_data.hapActivePresetIndexMutable.observe(this.parent, active_preset_index -> { - holder.leAudioHapActivePresetIndex.setText(String.valueOf(active_preset_index)); - }); + hap_svc_data.hapActivePresetIndexMutable.observe( + this.parent, + active_preset_index -> { + holder.leAudioHapActivePresetIndex.setText( + String.valueOf(active_preset_index)); + }); if (hap_svc_data.hapActivePresetIndexMutable.hasObservers()) hap_svc_data.hapActivePresetIndexMutable.removeObservers(this.parent); - hap_svc_data.hapActivePresetIndexMutable.observe(this.parent, active_preset_index -> { - holder.leAudioHapActivePresetIndex.setText(String.valueOf(active_preset_index)); - }); + hap_svc_data.hapActivePresetIndexMutable.observe( + this.parent, + active_preset_index -> { + holder.leAudioHapActivePresetIndex.setText( + String.valueOf(active_preset_index)); + }); } else { holder.itemView.findViewById(R.id.hap_layout).setVisibility(View.GONE); } } - private void setVolumeControlStateObservers(@NonNull ViewHolder holder, - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { + private void setVolumeControlStateObservers( + @NonNull ViewHolder holder, LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { LeAudioDeviceStateWrapper.VolumeControlData vc_svc_data = leAudioDeviceStateWrapper.volumeControlData; if (vc_svc_data != null) { if (vc_svc_data.isConnectedMutable.hasObservers()) vc_svc_data.isConnectedMutable.removeObservers(this.parent); - vc_svc_data.isConnectedMutable.observe(this.parent, is_connected -> { - // FIXME: How to prevent the callback from firing when we set this by code - if (is_connected != holder.vcConnectionSwitch.isChecked()) { - holder.vcConnectionSwitch.setActivated(false); - holder.vcConnectionSwitch.setChecked(is_connected); - holder.vcConnectionSwitch.setActivated(true); - } - - if (holder.itemView.findViewById(R.id.vc_layout) - .getVisibility() != (is_connected ? View.VISIBLE : View.GONE)) - holder.itemView.findViewById(R.id.vc_layout) - .setVisibility(is_connected ? View.VISIBLE : View.GONE); - }); - - holder.itemView.findViewById(R.id.vc_layout) - .setVisibility(vc_svc_data.isConnectedMutable.getValue() != null - && vc_svc_data.isConnectedMutable.getValue() ? View.VISIBLE + vc_svc_data.isConnectedMutable.observe( + this.parent, + is_connected -> { + // FIXME: How to prevent the callback from firing when we set this by code + if (is_connected != holder.vcConnectionSwitch.isChecked()) { + holder.vcConnectionSwitch.setActivated(false); + holder.vcConnectionSwitch.setChecked(is_connected); + holder.vcConnectionSwitch.setActivated(true); + } + + if (holder.itemView.findViewById(R.id.vc_layout).getVisibility() + != (is_connected ? View.VISIBLE : View.GONE)) + holder.itemView + .findViewById(R.id.vc_layout) + .setVisibility(is_connected ? View.VISIBLE : View.GONE); + }); + + holder.itemView + .findViewById(R.id.vc_layout) + .setVisibility( + vc_svc_data.isConnectedMutable.getValue() != null + && vc_svc_data.isConnectedMutable.getValue() + ? View.VISIBLE : View.GONE); if (vc_svc_data.volumeStateMutable.hasObservers()) vc_svc_data.volumeStateMutable.removeObservers(this.parent); - vc_svc_data.volumeStateMutable.observe(this.parent, state -> { - holder.volumeSeekBar.setProgress(state); - }); + vc_svc_data.volumeStateMutable.observe( + this.parent, + state -> { + holder.volumeSeekBar.setProgress(state); + }); if (vc_svc_data.mutedStateMutable.hasObservers()) vc_svc_data.mutedStateMutable.removeObservers(this.parent); - vc_svc_data.mutedStateMutable.observe(this.parent, state -> { - holder.muteSwitch.setActivated(false); - holder.muteSwitch.setChecked(state); - holder.muteSwitch.setActivated(true); - }); + vc_svc_data.mutedStateMutable.observe( + this.parent, + state -> { + holder.muteSwitch.setActivated(false); + holder.muteSwitch.setChecked(state); + holder.muteSwitch.setActivated(true); + }); if (vc_svc_data.numInputsMutable.hasObservers()) vc_svc_data.numInputsMutable.removeObservers(this.parent); - vc_svc_data.numInputsMutable.observe(this.parent, num_inputs -> { - List range = new ArrayList<>(); - if (num_inputs != 0) - range = IntStream.rangeClosed(1, num_inputs).boxed() - .collect(Collectors.toList()); - ArrayAdapter adapter = - new ArrayAdapter(this.parent, android.R.layout.simple_spinner_item, range); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - holder.inputIdxSpinner.setAdapter(adapter); - }); + vc_svc_data.numInputsMutable.observe( + this.parent, + num_inputs -> { + List range = new ArrayList<>(); + if (num_inputs != 0) + range = + IntStream.rangeClosed(1, num_inputs) + .boxed() + .collect(Collectors.toList()); + ArrayAdapter adapter = + new ArrayAdapter( + this.parent, android.R.layout.simple_spinner_item, range); + adapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + holder.inputIdxSpinner.setAdapter(adapter); + }); if (vc_svc_data.viewsData != null) { Integer select_pos = ((ViewHolderVcPersistentData) vc_svc_data.viewsData).selectedInputPosition; - if (select_pos != null) - holder.inputIdxSpinner.setSelection(select_pos); + if (select_pos != null) holder.inputIdxSpinner.setSelection(select_pos); } if (vc_svc_data.inputDescriptionsMutable.hasObservers()) vc_svc_data.inputDescriptionsMutable.removeObservers(this.parent); - vc_svc_data.inputDescriptionsMutable.observe(this.parent, integerStringMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputDescriptionText - .setText(integerStringMap.getOrDefault(input_id, "")); - } - }); + vc_svc_data.inputDescriptionsMutable.observe( + this.parent, + integerStringMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputDescriptionText.setText( + integerStringMap.getOrDefault(input_id, "")); + } + }); if (vc_svc_data.inputStateGainMutable.hasObservers()) vc_svc_data.inputStateGainMutable.removeObservers(this.parent); - vc_svc_data.inputStateGainMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputGainSeekBar - .setProgress(integerIntegerMap.getOrDefault(input_id, 0)); - } - }); + vc_svc_data.inputStateGainMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputGainSeekBar.setProgress( + integerIntegerMap.getOrDefault(input_id, 0)); + } + }); if (vc_svc_data.inputStateGainModeMutable.hasObservers()) vc_svc_data.inputStateGainModeMutable.removeObservers(this.parent); - vc_svc_data.inputStateGainModeMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputGainModeText.setText(this.parent.getResources().getStringArray( - R.array.gain_modes)[integerIntegerMap.getOrDefault(input_id, 1)]); - } - }); + vc_svc_data.inputStateGainModeMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputGainModeText.setText( + this.parent.getResources() + .getStringArray(R.array.gain_modes)[ + integerIntegerMap.getOrDefault(input_id, 1)]); + } + }); if (vc_svc_data.inputStateGainUnitMutable.hasObservers()) vc_svc_data.inputStateGainUnitMutable.removeObservers(this.parent); - vc_svc_data.inputStateGainUnitMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - // TODO: Use string map with units instead of plain numbers - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputGainPropsUnitText - .setText(integerIntegerMap.getOrDefault(input_id, 0).toString()); - } - }); + vc_svc_data.inputStateGainUnitMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + // TODO: Use string map with units instead of plain numbers + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputGainPropsUnitText.setText( + integerIntegerMap.getOrDefault(input_id, 0).toString()); + } + }); if (vc_svc_data.inputStateGainMinMutable.hasObservers()) vc_svc_data.inputStateGainMinMutable.removeObservers(this.parent); - vc_svc_data.inputStateGainMinMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputGainPropsMinText - .setText(integerIntegerMap.getOrDefault(input_id, 0).toString()); - holder.inputGainSeekBar.setMin(integerIntegerMap.getOrDefault(input_id, -255)); - } - }); + vc_svc_data.inputStateGainMinMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputGainPropsMinText.setText( + integerIntegerMap.getOrDefault(input_id, 0).toString()); + holder.inputGainSeekBar.setMin( + integerIntegerMap.getOrDefault(input_id, -255)); + } + }); if (vc_svc_data.inputStateGainMaxMutable.hasObservers()) vc_svc_data.inputStateGainMaxMutable.removeObservers(this.parent); - vc_svc_data.inputStateGainMaxMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputGainPropsMaxText - .setText(integerIntegerMap.getOrDefault(input_id, 0).toString()); - holder.inputGainSeekBar.setMax(integerIntegerMap.getOrDefault(input_id, 255)); - } - }); + vc_svc_data.inputStateGainMaxMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputGainPropsMaxText.setText( + integerIntegerMap.getOrDefault(input_id, 0).toString()); + holder.inputGainSeekBar.setMax( + integerIntegerMap.getOrDefault(input_id, 255)); + } + }); if (vc_svc_data.inputStateMuteMutable.hasObservers()) vc_svc_data.inputStateMuteMutable.removeObservers(this.parent); - vc_svc_data.inputStateMuteMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - holder.inputMuteSwitch.setActivated(false); - holder.inputMuteSwitch - .setChecked(integerIntegerMap.getOrDefault(input_id, false)); - holder.inputMuteSwitch.setActivated(true); - } - }); + vc_svc_data.inputStateMuteMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + holder.inputMuteSwitch.setActivated(false); + holder.inputMuteSwitch.setChecked( + integerIntegerMap.getOrDefault(input_id, false)); + holder.inputMuteSwitch.setActivated(true); + } + }); if (vc_svc_data.inputStatusMutable.hasObservers()) vc_svc_data.inputStatusMutable.removeObservers(this.parent); - vc_svc_data.inputStatusMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - // TODO: Use string map with units instead of plain numbers - holder.inputStatusText - .setText(integerIntegerMap.getOrDefault(input_id, -1).toString()); - } - }); + vc_svc_data.inputStatusMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + // TODO: Use string map with units instead of plain numbers + holder.inputStatusText.setText( + integerIntegerMap.getOrDefault(input_id, -1).toString()); + } + }); if (vc_svc_data.inputTypeMutable.hasObservers()) vc_svc_data.inputTypeMutable.removeObservers(this.parent); - vc_svc_data.inputTypeMutable.observe(this.parent, integerIntegerMap -> { - if (holder.inputIdxSpinner.getSelectedItem() != null) { - Integer input_id = - Integer.valueOf(holder.inputIdxSpinner.getSelectedItem().toString()); - // TODO: Use string map with units instead of plain numbers - holder.inputTypeText - .setText(integerIntegerMap.getOrDefault(input_id, -1).toString()); - } - }); - - vc_svc_data.numOffsetsMutable.observe(this.parent, num_offsets -> { - List range = new ArrayList<>(); - if (num_offsets != 0) - range = IntStream.rangeClosed(1, num_offsets).boxed() - .collect(Collectors.toList()); - ArrayAdapter adapter = - new ArrayAdapter(this.parent, android.R.layout.simple_spinner_item, range); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - holder.outputIdxSpinner.setAdapter(adapter); - }); + vc_svc_data.inputTypeMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.inputIdxSpinner.getSelectedItem() != null) { + Integer input_id = + Integer.valueOf( + holder.inputIdxSpinner.getSelectedItem().toString()); + // TODO: Use string map with units instead of plain numbers + holder.inputTypeText.setText( + integerIntegerMap.getOrDefault(input_id, -1).toString()); + } + }); + + vc_svc_data.numOffsetsMutable.observe( + this.parent, + num_offsets -> { + List range = new ArrayList<>(); + if (num_offsets != 0) + range = + IntStream.rangeClosed(1, num_offsets) + .boxed() + .collect(Collectors.toList()); + ArrayAdapter adapter = + new ArrayAdapter( + this.parent, android.R.layout.simple_spinner_item, range); + adapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + holder.outputIdxSpinner.setAdapter(adapter); + }); if (vc_svc_data.viewsData != null) { Integer select_pos = ((ViewHolderVcPersistentData) vc_svc_data.viewsData).selectedOutputPosition; - if (select_pos != null) - holder.outputIdxSpinner.setSelection(select_pos); + if (select_pos != null) holder.outputIdxSpinner.setSelection(select_pos); } if (vc_svc_data.outputVolumeOffsetMutable.hasObservers()) vc_svc_data.outputVolumeOffsetMutable.removeObservers(this.parent); - vc_svc_data.outputVolumeOffsetMutable.observe(this.parent, integerIntegerMap -> { - if (holder.outputIdxSpinner.getSelectedItem() != null) { - Integer output_id = - Integer.valueOf(holder.outputIdxSpinner.getSelectedItem().toString()); - holder.outputGainOffsetSeekBar - .setProgress(integerIntegerMap.getOrDefault(output_id, 0)); - } - }); + vc_svc_data.outputVolumeOffsetMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.outputIdxSpinner.getSelectedItem() != null) { + Integer output_id = + Integer.valueOf( + holder.outputIdxSpinner.getSelectedItem().toString()); + holder.outputGainOffsetSeekBar.setProgress( + integerIntegerMap.getOrDefault(output_id, 0)); + } + }); if (vc_svc_data.outputLocationMutable.hasObservers()) vc_svc_data.outputLocationMutable.removeObservers(this.parent); - vc_svc_data.outputLocationMutable.observe(this.parent, integerIntegerMap -> { - if (holder.outputIdxSpinner.getSelectedItem() != null) { - Integer output_id = - Integer.valueOf(holder.outputIdxSpinner.getSelectedItem().toString()); - holder.outputLocationText.setText(this.parent.getResources().getStringArray( - R.array.audio_locations)[integerIntegerMap.getOrDefault(output_id, 0)]); - } - }); + vc_svc_data.outputLocationMutable.observe( + this.parent, + integerIntegerMap -> { + if (holder.outputIdxSpinner.getSelectedItem() != null) { + Integer output_id = + Integer.valueOf( + holder.outputIdxSpinner.getSelectedItem().toString()); + holder.outputLocationText.setText( + this.parent.getResources() + .getStringArray(R.array.audio_locations)[ + integerIntegerMap.getOrDefault(output_id, 0)]); + } + }); if (vc_svc_data.outputDescriptionMutable.hasObservers()) vc_svc_data.outputDescriptionMutable.removeObservers(this.parent); - vc_svc_data.outputDescriptionMutable.observe(this.parent, integerStringMap -> { - if (holder.outputIdxSpinner.getSelectedItem() != null) { - Integer output_id = - Integer.valueOf(holder.outputIdxSpinner.getSelectedItem().toString()); - holder.outputDescriptionText - .setText(integerStringMap.getOrDefault(output_id, "no description")); - } - }); + vc_svc_data.outputDescriptionMutable.observe( + this.parent, + integerStringMap -> { + if (holder.outputIdxSpinner.getSelectedItem() != null) { + Integer output_id = + Integer.valueOf( + holder.outputIdxSpinner.getSelectedItem().toString()); + holder.outputDescriptionText.setText( + integerStringMap.getOrDefault(output_id, "no description")); + } + }); } else { holder.itemView.findViewById(R.id.vc_layout).setVisibility(View.GONE); } } - private void setVolumeControlUiStateObservers(@NonNull ViewHolder holder, - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - if (leAudioDeviceStateWrapper.volumeControlData == null) - return; + private void setVolumeControlUiStateObservers( + @NonNull ViewHolder holder, LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { + if (leAudioDeviceStateWrapper.volumeControlData == null) return; ViewHolderVcPersistentData vData = (ViewHolderVcPersistentData) leAudioDeviceStateWrapper.volumeControlData.viewsData; - if (vData == null) - return; + if (vData == null) return; if (vData.isInputsCollapsedMutable.hasObservers()) vData.isInputsCollapsedMutable.removeObservers(this.parent); - vData.isInputsCollapsedMutable.observe(this.parent, aBoolean -> { - Float rbegin = aBoolean ? 0.0f : 180.0f; - Float rend = aBoolean ? 180.0f : 0.0f; - - ObjectAnimator.ofFloat(holder.inputFoldableIcon, "rotation", rbegin, rend) - .setDuration(300).start(); - holder.inputFoldable.setVisibility(aBoolean ? View.GONE : View.VISIBLE); - }); + vData.isInputsCollapsedMutable.observe( + this.parent, + aBoolean -> { + Float rbegin = aBoolean ? 0.0f : 180.0f; + Float rend = aBoolean ? 180.0f : 0.0f; + + ObjectAnimator.ofFloat(holder.inputFoldableIcon, "rotation", rbegin, rend) + .setDuration(300) + .start(); + holder.inputFoldable.setVisibility(aBoolean ? View.GONE : View.VISIBLE); + }); vData.isInputsCollapsedMutable.setValue(holder.inputFoldable.getVisibility() == View.GONE); if (vData.isOutputsCollapsedMutable.hasObservers()) vData.isOutputsCollapsedMutable.removeObservers(this.parent); - vData.isOutputsCollapsedMutable.observe(this.parent, aBoolean -> { - Float rbegin = aBoolean ? 0.0f : 180.0f; - Float rend = aBoolean ? 180.0f : 0.0f; - - ObjectAnimator.ofFloat(holder.outputFoldableIcon, "rotation", rbegin, rend) - .setDuration(300).start(); - holder.outputFoldable.setVisibility(aBoolean ? View.GONE : View.VISIBLE); - }); - vData.isOutputsCollapsedMutable - .setValue(holder.outputFoldable.getVisibility() == View.GONE); + vData.isOutputsCollapsedMutable.observe( + this.parent, + aBoolean -> { + Float rbegin = aBoolean ? 0.0f : 180.0f; + Float rend = aBoolean ? 180.0f : 0.0f; + + ObjectAnimator.ofFloat(holder.outputFoldableIcon, "rotation", rbegin, rend) + .setDuration(300) + .start(); + holder.outputFoldable.setVisibility(aBoolean ? View.GONE : View.VISIBLE); + }); + vData.isOutputsCollapsedMutable.setValue( + holder.outputFoldable.getVisibility() == View.GONE); } private void setBassStateObservers( @@ -605,19 +768,22 @@ public class LeAudioRecycleViewAdapter if (bass_svc_data != null) { if (bass_svc_data.isConnectedMutable.hasObservers()) bass_svc_data.isConnectedMutable.removeObservers(this.parent); - bass_svc_data.isConnectedMutable.observe(this.parent, is_connected -> { - // FIXME: How to prevent the callback from firing when we set this by code - if (is_connected != holder.bassConnectionSwitch.isChecked()) { - holder.bassConnectionSwitch.setActivated(false); - holder.bassConnectionSwitch.setChecked(is_connected); - holder.bassConnectionSwitch.setActivated(true); - } - - if (holder.itemView.findViewById(R.id.bass_layout) - .getVisibility() != (is_connected ? View.VISIBLE : View.GONE)) - holder.itemView.findViewById(R.id.bass_layout) - .setVisibility(is_connected ? View.VISIBLE : View.GONE); - }); + bass_svc_data.isConnectedMutable.observe( + this.parent, + is_connected -> { + // FIXME: How to prevent the callback from firing when we set this by code + if (is_connected != holder.bassConnectionSwitch.isChecked()) { + holder.bassConnectionSwitch.setActivated(false); + holder.bassConnectionSwitch.setChecked(is_connected); + holder.bassConnectionSwitch.setActivated(true); + } + + if (holder.itemView.findViewById(R.id.bass_layout).getVisibility() + != (is_connected ? View.VISIBLE : View.GONE)) + holder.itemView + .findViewById(R.id.bass_layout) + .setVisibility(is_connected ? View.VISIBLE : View.GONE); + }); holder.itemView .findViewById(R.id.bass_layout) @@ -629,21 +795,25 @@ public class LeAudioRecycleViewAdapter if (bass_svc_data.receiverStatesMutable.hasActiveObservers()) bass_svc_data.receiverStatesMutable.removeObservers(this.parent); - bass_svc_data.receiverStatesMutable.observe(this.parent, + bass_svc_data.receiverStatesMutable.observe( + this.parent, integerReceiverStateHashMap -> { - List all_ids = integerReceiverStateHashMap.entrySet().stream() - .map(Map.Entry::getKey).collect(Collectors.toList()); - - ArrayAdapter adapter = new ArrayAdapter(this.parent, - android.R.layout.simple_spinner_item, all_ids); + List all_ids = + integerReceiverStateHashMap.entrySet().stream() + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + ArrayAdapter adapter = + new ArrayAdapter( + this.parent, android.R.layout.simple_spinner_item, all_ids); adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); holder.bassReceiverIdSpinner.setAdapter(adapter); if (bass_svc_data.viewsData != null) { Integer select_pos = - ((ViewHolderBassPersistentData) bass_svc_data.viewsData).selectedReceiverPositionMutable - .getValue(); + ((ViewHolderBassPersistentData) bass_svc_data.viewsData) + .selectedReceiverPositionMutable.getValue(); if (select_pos != null) holder.bassReceiverIdSpinner.setSelection(select_pos); } @@ -653,13 +823,13 @@ public class LeAudioRecycleViewAdapter } } - private void setBassUiStateObservers(@NonNull ViewHolder holder, LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - if (leAudioDeviceStateWrapper.bassData == null) - return; + private void setBassUiStateObservers( + @NonNull ViewHolder holder, LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { + if (leAudioDeviceStateWrapper.bassData == null) return; - ViewHolderBassPersistentData vData = (ViewHolderBassPersistentData)leAudioDeviceStateWrapper.bassData.viewsData; - if (vData == null) - return; + ViewHolderBassPersistentData vData = + (ViewHolderBassPersistentData) leAudioDeviceStateWrapper.bassData.viewsData; + if (vData == null) return; if (vData.selectedReceiverPositionMutable.hasObservers()) vData.selectedReceiverPositionMutable.removeObservers(this.parent); @@ -858,23 +1028,30 @@ public class LeAudioRecycleViewAdapter void onDisconnectClick(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper); - void onStreamActionClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - Integer group_id, Integer content_type, Integer action); + void onStreamActionClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + Integer group_id, + Integer content_type, + Integer action); - void onGroupSetClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - Integer group_id); + void onGroupSetClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, Integer group_id); - void onGroupUnsetClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - Integer group_id); + void onGroupUnsetClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, Integer group_id); - void onGroupDestroyClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - Integer group_id); + void onGroupDestroyClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, Integer group_id); - void onGroupSetLockClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - Integer group_id, boolean lock); + void onGroupSetLockClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + Integer group_id, + boolean lock); - void onMicrophoneMuteChanged(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - boolean mute, boolean is_from_user); + void onMicrophoneMuteChanged( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + boolean mute, + boolean is_from_user); } public interface OnVolumeControlInteractionListener { @@ -882,56 +1059,64 @@ public class LeAudioRecycleViewAdapter void onDisconnectClick(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper); - void onVolumeChanged(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int value, + void onVolumeChanged( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int value, boolean is_from_user); - void onCheckedChanged(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - boolean is_checked); + void onCheckedChanged( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, boolean is_checked); - void onInputGetStateButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id); + void onInputGetStateButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id); - void onInputGainValueChanged(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id, int value); + void onInputGainValueChanged( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, int value); - void onInputMuteSwitched(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, + void onInputMuteSwitched( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int input_id, boolean is_muted); - void onInputSetGainModeButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id, boolean is_auto); + void onInputSetGainModeButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, boolean is_auto); - void onInputGetGainPropsButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id); + void onInputGetGainPropsButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id); - void onInputGetTypeButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id); + void onInputGetTypeButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id); - void onInputGetStatusButton(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id); + void onInputGetStatusButton( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id); - void onInputGetDescriptionButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id); + void onInputGetDescriptionButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id); - void onInputSetDescriptionButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int input_id, String description); + void onInputSetDescriptionButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int input_id, + String description); - void onOutputGetGainButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int output_id); + void onOutputGetGainButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id); - void onOutputGainOffsetGainValueChanged(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int output_id, int value); + void onOutputGainOffsetGainValueChanged( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id, int value); - void onOutputGetLocationButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int output_id); + void onOutputGetLocationButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id); - void onOutputSetLocationButtonClicked(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int output_id, int location); + void onOutputSetLocationButtonClicked( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id, int location); void onOutputGetDescriptionButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id); - void onOutputSetDescriptionButton(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int output_id, String description); + void onOutputSetDescriptionButton( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int output_id, + String description); } public interface OnHapInteractionListener { @@ -961,7 +1146,8 @@ public class LeAudioRecycleViewAdapter void onDisconnectClick(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper); - void onReceiverSelected(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int receiver_id); + void onReceiverSelected( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int receiver_id); void onBroadcastCodeEntered(BluetoothDevice device, int receiver_id, byte[] broadcast_code); @@ -1066,31 +1252,32 @@ public class LeAudioRecycleViewAdapter setupBassView(itemView); // Notify viewmodel via parent's click listener - itemView.setOnClickListener(view -> { - Integer position = getAdapterPosition(); - if (clickListener != null && position != RecyclerView.NO_POSITION) { - clickListener.onItemClick(devices.get(position)); - } - }); + itemView.setOnClickListener( + view -> { + Integer position = getAdapterPosition(); + if (clickListener != null && position != RecyclerView.NO_POSITION) { + clickListener.onItemClick(devices.get(position)); + } + }); } private void setupHapView(@NonNull View itemView) { hapConnectionSwitch = itemView.findViewById(R.id.hap_switch); hapConnectionSwitch.setActivated(true); - hapConnectionSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; - - if (bassInteractionListener != null) { - if (b) - hapInteractionListener - .onConnectClick(devices.get(ViewHolder.this.getAdapterPosition())); - else - hapInteractionListener.onDisconnectClick( - devices.get(ViewHolder.this.getAdapterPosition())); - } - }); + hapConnectionSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (bassInteractionListener != null) { + if (b) + hapInteractionListener.onConnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + else + hapInteractionListener.onDisconnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + } + }); leAudioHapState = itemView.findViewById(R.id.hap_profile_state_text); leAudioHapFeatures = itemView.findViewById(R.id.hap_profile_features_text); @@ -1114,15 +1301,15 @@ public class LeAudioRecycleViewAdapter leAudioHapPreviousGroupPresetButton = itemView.findViewById(R.id.hap_previous_group_preset_button); - leAudioHapPresetsSpinner - .setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + leAudioHapPresetsSpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { @Override - public void onItemSelected(AdapterView adapterView, View view, - int position, long l) { + public void onItemSelected( + AdapterView adapterView, View view, int position, long l) { LeAudioDeviceStateWrapper device = devices.get(ViewHolder.this.getAdapterPosition()); - ((ViewHolderHapPersistentData) device.leAudioData.viewsData).selectedPresetPositionMutable - .setValue(position); + ((ViewHolderHapPersistentData) device.leAudioData.viewsData) + .selectedPresetPositionMutable.setValue(position); } @Override @@ -1131,104 +1318,150 @@ public class LeAudioRecycleViewAdapter } }); - leAudioHapChangePresetNameButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - if (leAudioHapPresetsSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known preset, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + leAudioHapChangePresetNameButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + if (leAudioHapPresetsSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known preset, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Set a name"); - final EditText input = new EditText(itemView.getContext()); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - Integer index = Integer.valueOf(leAudioHapPresetsSpinner.getSelectedItem() - .toString().split("\\s")[0]); - hapInteractionListener.onChangePresetNameClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device, index, - input.getText().toString()); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - } - }); - - leAudioHapSetActivePresetButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - if (leAudioHapPresetsSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known preset, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + AlertDialog.Builder alert = + new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Set a name"); + final EditText input = new EditText(itemView.getContext()); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + Integer index = + Integer.valueOf( + leAudioHapPresetsSpinner + .getSelectedItem() + .toString() + .split("\\s")[0]); + hapInteractionListener.onChangePresetNameClicked( + devices.get(ViewHolder.this.getAdapterPosition()) + .device, + index, + input.getText().toString()); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + } + }); - Integer index = Integer.valueOf( - leAudioHapPresetsSpinner.getSelectedItem().toString().split("\\s")[0]); - hapInteractionListener.onSetActivePresetClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device, index); - } - }); - - leAudioHapSetActivePresetForGroupButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - if (leAudioHapPresetsSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known preset, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + leAudioHapSetActivePresetButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + if (leAudioHapPresetsSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known preset, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } - Integer index = Integer.valueOf( - leAudioHapPresetsSpinner.getSelectedItem().toString().split("\\s")[0]); - hapInteractionListener.onSetActivePresetForGroupClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device, index); - } - }); - - leAudioHapReadPresetInfoButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - if (leAudioHapPresetsSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known preset, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + Integer index = + Integer.valueOf( + leAudioHapPresetsSpinner + .getSelectedItem() + .toString() + .split("\\s")[0]); + hapInteractionListener.onSetActivePresetClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device, + index); + } + }); + + leAudioHapSetActivePresetForGroupButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + if (leAudioHapPresetsSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known preset, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + + Integer index = + Integer.valueOf( + leAudioHapPresetsSpinner + .getSelectedItem() + .toString() + .split("\\s")[0]); + hapInteractionListener.onSetActivePresetForGroupClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device, + index); + } + }); + + leAudioHapReadPresetInfoButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + if (leAudioHapPresetsSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known preset, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + + Integer index = + Integer.valueOf( + leAudioHapPresetsSpinner + .getSelectedItem() + .toString() + .split("\\s")[0]); + hapInteractionListener.onReadPresetInfoClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device, + index); + } + }); + + leAudioHapNextDevicePresetButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + hapInteractionListener.onNextDevicePresetClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device); + } + }); + + leAudioHapPreviousDevicePresetButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + hapInteractionListener.onPreviousDevicePresetClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device); + } + }); + + leAudioHapNextGroupPresetButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + hapInteractionListener.onNextGroupPresetClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device); + } + }); - Integer index = Integer.valueOf( - leAudioHapPresetsSpinner.getSelectedItem().toString().split("\\s")[0]); - hapInteractionListener.onReadPresetInfoClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device, index); - } - }); - - leAudioHapNextDevicePresetButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - hapInteractionListener.onNextDevicePresetClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device); - } - }); - - leAudioHapPreviousDevicePresetButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - hapInteractionListener.onPreviousDevicePresetClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device); - } - }); - - leAudioHapNextGroupPresetButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - hapInteractionListener.onNextGroupPresetClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device); - } - }); - - leAudioHapPreviousGroupPresetButton.setOnClickListener(view -> { - if (hapInteractionListener != null) { - hapInteractionListener.onPreviousGroupPresetClicked( - devices.get(ViewHolder.this.getAdapterPosition()).device); - } - }); + leAudioHapPreviousGroupPresetButton.setOnClickListener( + view -> { + if (hapInteractionListener != null) { + hapInteractionListener.onPreviousGroupPresetClicked( + devices.get(ViewHolder.this.getAdapterPosition()).device); + } + }); } private void SetupLeAudioView(@NonNull View itemView) { @@ -1248,144 +1481,198 @@ public class LeAudioRecycleViewAdapter leAudioGroupMicrophoneSwitch = itemView.findViewById(R.id.group_mic_mute_state_switch); leAudioGroupMicrophoneState = itemView.findViewById(R.id.group_mic_mute_state_text); - leAudioConnectionSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; - - if (leAudioInteractionListener != null) { - if (b) - leAudioInteractionListener - .onConnectClick(devices.get(ViewHolder.this.getAdapterPosition())); - else - leAudioInteractionListener.onDisconnectClick( - devices.get(ViewHolder.this.getAdapterPosition())); - } - }); - - leAudioStartStreamButton.setOnClickListener(view -> { - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Pick a content type"); - NumberPicker input = new NumberPicker(itemView.getContext()); - input.setMinValue(1); - input.setMaxValue( - itemView.getResources().getStringArray(R.array.content_types).length - 1); - input.setDisplayedValues( - itemView.getResources().getStringArray(R.array.content_types)); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - final Integer group_id = Integer - .parseInt(ViewHolder.this.leAudioGroupIdText.getText().toString()); - if (leAudioInteractionListener != null && group_id != null) - leAudioInteractionListener.onStreamActionClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id, - 1 << (input.getValue() - 1), 0); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - }); - - leAudioSuspendStreamButton.setOnClickListener(view -> { - final Integer group_id = - Integer.parseInt(ViewHolder.this.leAudioGroupIdText.getText().toString()); - if (leAudioInteractionListener != null && group_id != null) - leAudioInteractionListener.onStreamActionClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id, 0, 1); - }); - - leAudioStopStreamButton.setOnClickListener(view -> { - final Integer group_id = - Integer.parseInt(ViewHolder.this.leAudioGroupIdText.getText().toString()); - if (leAudioInteractionListener != null && group_id != null) - leAudioInteractionListener.onStreamActionClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id, 0, 2); - }); - - leAudioGroupSetButton.setOnClickListener(view -> { - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Pick a group ID"); - final EditText input = new EditText(itemView.getContext()); - input.setInputType(InputType.TYPE_CLASS_NUMBER); - input.setRawInputType(Configuration.KEYBOARD_12KEY); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - final Integer group_id = Integer.valueOf(input.getText().toString()); - leAudioInteractionListener.onGroupSetClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - }); - - leAudioGroupUnsetButton.setOnClickListener(view -> { - final Integer group_id = Integer.parseInt( - ViewHolder.this.leAudioGroupIdText.getText().toString().equals("Unknown") - ? "0" - : ViewHolder.this.leAudioGroupIdText.getText().toString()); - if (leAudioInteractionListener != null) - leAudioInteractionListener.onGroupUnsetClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id); - }); - - leAudioGroupDestroyButton.setOnClickListener(view -> { - final Integer group_id = - Integer.parseInt(ViewHolder.this.leAudioGroupIdText.getText().toString()); - if (leAudioInteractionListener != null) - leAudioInteractionListener.onGroupDestroyClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id); - }); - - leAudioSetLockButton.setOnClickListener(view -> { - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Pick a group ID"); - final EditText input = new EditText(itemView.getContext()); - input.setInputType(InputType.TYPE_CLASS_NUMBER); - input.setRawInputType(Configuration.KEYBOARD_12KEY); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - final Integer group_id = Integer.valueOf(input.getText().toString()); - if (leAudioInteractionListener != null) - leAudioInteractionListener.onGroupSetLockClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id, true); + leAudioConnectionSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (leAudioInteractionListener != null) { + if (b) + leAudioInteractionListener.onConnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + else + leAudioInteractionListener.onDisconnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + } + }); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - }); - - leAudioSetUnlockButton.setOnClickListener(view -> { - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Pick a group ID"); - final EditText input = new EditText(itemView.getContext()); - input.setInputType(InputType.TYPE_CLASS_NUMBER); - input.setRawInputType(Configuration.KEYBOARD_12KEY); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - final Integer group_id = Integer.valueOf(input.getText().toString()); - if (leAudioInteractionListener != null) - leAudioInteractionListener.onGroupSetLockClicked( - devices.get(ViewHolder.this.getAdapterPosition()), group_id, false); + leAudioStartStreamButton.setOnClickListener( + view -> { + AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Pick a content type"); + NumberPicker input = new NumberPicker(itemView.getContext()); + input.setMinValue(1); + input.setMaxValue( + itemView.getResources().getStringArray(R.array.content_types).length + - 1); + input.setDisplayedValues( + itemView.getResources().getStringArray(R.array.content_types)); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + final Integer group_id = + Integer.parseInt( + ViewHolder.this + .leAudioGroupIdText + .getText() + .toString()); + if (leAudioInteractionListener != null && group_id != null) + leAudioInteractionListener.onStreamActionClicked( + devices.get(ViewHolder.this.getAdapterPosition()), + group_id, + 1 << (input.getValue() - 1), + 0); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + }); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - }); + leAudioSuspendStreamButton.setOnClickListener( + view -> { + final Integer group_id = + Integer.parseInt( + ViewHolder.this.leAudioGroupIdText.getText().toString()); + if (leAudioInteractionListener != null && group_id != null) + leAudioInteractionListener.onStreamActionClicked( + devices.get(ViewHolder.this.getAdapterPosition()), + group_id, + 0, + 1); + }); - leAudioGroupMicrophoneSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; + leAudioStopStreamButton.setOnClickListener( + view -> { + final Integer group_id = + Integer.parseInt( + ViewHolder.this.leAudioGroupIdText.getText().toString()); + if (leAudioInteractionListener != null && group_id != null) + leAudioInteractionListener.onStreamActionClicked( + devices.get(ViewHolder.this.getAdapterPosition()), + group_id, + 0, + 2); + }); + + leAudioGroupSetButton.setOnClickListener( + view -> { + AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Pick a group ID"); + final EditText input = new EditText(itemView.getContext()); + input.setInputType(InputType.TYPE_CLASS_NUMBER); + input.setRawInputType(Configuration.KEYBOARD_12KEY); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + final Integer group_id = + Integer.valueOf(input.getText().toString()); + leAudioInteractionListener.onGroupSetClicked( + devices.get(ViewHolder.this.getAdapterPosition()), + group_id); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + }); + + leAudioGroupUnsetButton.setOnClickListener( + view -> { + final Integer group_id = + Integer.parseInt( + ViewHolder.this + .leAudioGroupIdText + .getText() + .toString() + .equals("Unknown") + ? "0" + : ViewHolder.this + .leAudioGroupIdText + .getText() + .toString()); + if (leAudioInteractionListener != null) + leAudioInteractionListener.onGroupUnsetClicked( + devices.get(ViewHolder.this.getAdapterPosition()), group_id); + }); + + leAudioGroupDestroyButton.setOnClickListener( + view -> { + final Integer group_id = + Integer.parseInt( + ViewHolder.this.leAudioGroupIdText.getText().toString()); + if (leAudioInteractionListener != null) + leAudioInteractionListener.onGroupDestroyClicked( + devices.get(ViewHolder.this.getAdapterPosition()), group_id); + }); + + leAudioSetLockButton.setOnClickListener( + view -> { + AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Pick a group ID"); + final EditText input = new EditText(itemView.getContext()); + input.setInputType(InputType.TYPE_CLASS_NUMBER); + input.setRawInputType(Configuration.KEYBOARD_12KEY); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + final Integer group_id = + Integer.valueOf(input.getText().toString()); + if (leAudioInteractionListener != null) + leAudioInteractionListener.onGroupSetLockClicked( + devices.get(ViewHolder.this.getAdapterPosition()), + group_id, + true); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + }); - if (leAudioInteractionListener != null) - leAudioInteractionListener.onMicrophoneMuteChanged( - devices.get(ViewHolder.this.getAdapterPosition()), b, true); - }); + leAudioSetUnlockButton.setOnClickListener( + view -> { + AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Pick a group ID"); + final EditText input = new EditText(itemView.getContext()); + input.setInputType(InputType.TYPE_CLASS_NUMBER); + input.setRawInputType(Configuration.KEYBOARD_12KEY); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + final Integer group_id = + Integer.valueOf(input.getText().toString()); + if (leAudioInteractionListener != null) + leAudioInteractionListener.onGroupSetLockClicked( + devices.get(ViewHolder.this.getAdapterPosition()), + group_id, + false); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + }); + + leAudioGroupMicrophoneSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (leAudioInteractionListener != null) + leAudioInteractionListener.onMicrophoneMuteChanged( + devices.get(ViewHolder.this.getAdapterPosition()), b, true); + }); } private void setupVcView(@NonNull View itemView) { @@ -1427,288 +1714,366 @@ public class LeAudioRecycleViewAdapter outputLocationText = itemView.findViewById(R.id.outputLocationText); outputDescriptionText = itemView.findViewById(R.id.outputDescriptionText); - vcConnectionSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; - - if (volumeControlInteractionListener != null) { - if (b) - volumeControlInteractionListener - .onConnectClick(devices.get(ViewHolder.this.getAdapterPosition())); - else - volumeControlInteractionListener.onDisconnectClick( - devices.get(ViewHolder.this.getAdapterPosition())); - } - }); - - volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - // Nothing to do here - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - // Nothing to do here - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - // Set value only on release - if (volumeControlInteractionListener != null) - volumeControlInteractionListener.onVolumeChanged( - devices.get(ViewHolder.this.getAdapterPosition()), - seekBar.getProgress(), true); - } - }); - - muteSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; - - if (volumeControlInteractionListener != null) - volumeControlInteractionListener - .onCheckedChanged(devices.get(ViewHolder.this.getAdapterPosition()), b); - }); - - inputFoldableIcon.setOnClickListener(view -> { - ViewHolderVcPersistentData vData = (ViewHolderVcPersistentData) devices - .get(ViewHolder.this.getAdapterPosition()).volumeControlData.viewsData; - if (vData != null) - vData.isInputsCollapsedMutable - .setValue(!vData.isInputsCollapsedMutable.getValue()); - }); - - inputIdxSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, - long l) { - Integer index = ViewHolder.this.getAdapterPosition(); - ((ViewHolderVcPersistentData) devices - .get(index).volumeControlData.viewsData).selectedInputPosition = + vcConnectionSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (volumeControlInteractionListener != null) { + if (b) + volumeControlInteractionListener.onConnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + else + volumeControlInteractionListener.onDisconnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + } + }); + + volumeSeekBar.setOnSeekBarChangeListener( + new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int i, boolean b) { + // Nothing to do here + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + // Nothing to do here + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + // Set value only on release + if (volumeControlInteractionListener != null) + volumeControlInteractionListener.onVolumeChanged( + devices.get(ViewHolder.this.getAdapterPosition()), + seekBar.getProgress(), + true); + } + }); + + muteSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (volumeControlInteractionListener != null) + volumeControlInteractionListener.onCheckedChanged( + devices.get(ViewHolder.this.getAdapterPosition()), b); + }); + + inputFoldableIcon.setOnClickListener( + view -> { + ViewHolderVcPersistentData vData = + (ViewHolderVcPersistentData) + devices.get(ViewHolder.this.getAdapterPosition()) + .volumeControlData + .viewsData; + if (vData != null) + vData.isInputsCollapsedMutable.setValue( + !vData.isInputsCollapsedMutable.getValue()); + }); + + inputIdxSpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected( + AdapterView adapterView, View view, int position, long l) { + Integer index = ViewHolder.this.getAdapterPosition(); + ((ViewHolderVcPersistentData) + devices.get(index).volumeControlData.viewsData) + .selectedInputPosition = position; - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - // Nothing to do here - } - }); - - outputFoldableIcon.setOnClickListener(view -> { - ViewHolderVcPersistentData vData = (ViewHolderVcPersistentData) devices - .get(ViewHolder.this.getAdapterPosition()).volumeControlData.viewsData; - vData.isOutputsCollapsedMutable - .setValue(!vData.isOutputsCollapsedMutable.getValue()); - }); - - outputIdxSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, - long l) { - Integer index = ViewHolder.this.getAdapterPosition(); - ((ViewHolderVcPersistentData) devices - .get(index).volumeControlData.viewsData).selectedOutputPosition = + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + // Nothing to do here + } + }); + + outputFoldableIcon.setOnClickListener( + view -> { + ViewHolderVcPersistentData vData = + (ViewHolderVcPersistentData) + devices.get(ViewHolder.this.getAdapterPosition()) + .volumeControlData + .viewsData; + vData.isOutputsCollapsedMutable.setValue( + !vData.isOutputsCollapsedMutable.getValue()); + }); + + outputIdxSpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected( + AdapterView adapterView, View view, int position, long l) { + Integer index = ViewHolder.this.getAdapterPosition(); + ((ViewHolderVcPersistentData) + devices.get(index).volumeControlData.viewsData) + .selectedOutputPosition = position; - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - // Nothing to do here - } - }); - - inputGetStateButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputGetStateButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), input_id); - } - }); - - inputGainSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean is_user_set) { - // Nothing to do here - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - // Nothing to do here - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(seekBar.getContext(), - "No known ext. input, please reconnect.", Toast.LENGTH_SHORT) + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + // Nothing to do here + } + }); + + inputGetStateButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputGetStateButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), input_id); + } + }); + + inputGainSeekBar.setOnSeekBarChangeListener( + new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int i, boolean is_user_set) { + // Nothing to do here + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + // Nothing to do here + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + seekBar.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf( + inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputGainValueChanged( + devices.get(ViewHolder.this.getAdapterPosition()), + input_id, + seekBar.getProgress()); + } + } + }); + + inputMuteSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + compoundButton.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputMuteSwitched( + devices.get(ViewHolder.this.getAdapterPosition()), input_id, b); + } + }); + + inputSetGainModeButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + + AlertDialog.Builder alert = + new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Select Gain mode"); + NumberPicker input = new NumberPicker(itemView.getContext()); + input.setMinValue(0); + input.setMaxValue(2); + input.setDisplayedValues( + itemView.getResources().getStringArray(R.array.gain_modes)); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + Integer input_id = + Integer.valueOf( + inputIdxSpinner + .getSelectedItem() + .toString()); + volumeControlInteractionListener + .onInputSetGainModeButtonClicked( + devices.get( + ViewHolder.this + .getAdapterPosition()), + input_id, + input.getValue() == 2); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + } + }); + + inputGetGainPropsButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputGetGainPropsButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), input_id); + } + }); + + inputGetTypeButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputGetTypeButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), input_id); + } + }); + + inputGetStatusButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputGetStatusButton( + devices.get(ViewHolder.this.getAdapterPosition()), input_id); + } + }); + + inputGetDescriptionButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + Integer input_id = + Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onInputGetDescriptionButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), input_id); + } + }); + + inputSetDescriptionButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (inputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. input, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + + AlertDialog.Builder alert = + new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Set a description"); + final EditText input = new EditText(itemView.getContext()); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + Integer input_id = + Integer.valueOf( + inputIdxSpinner + .getSelectedItem() + .toString()); + volumeControlInteractionListener + .onInputSetDescriptionButtonClicked( + devices.get( + ViewHolder.this + .getAdapterPosition()), + input_id, + input.getText().toString()); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + } + }); + + outpuGetGainButton.setOnClickListener( + view -> { + if (outputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. output, please reconnect.", + Toast.LENGTH_SHORT) .show(); return; } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputGainValueChanged( - devices.get(ViewHolder.this.getAdapterPosition()), input_id, - seekBar.getProgress()); - } - } - }); - - inputMuteSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; - - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(compoundButton.getContext(), - "No known ext. input, please reconnect.", Toast.LENGTH_SHORT) - .show(); - return; - } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputMuteSwitched( - devices.get(ViewHolder.this.getAdapterPosition()), input_id, b); - } - }); - - inputSetGainModeButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Select Gain mode"); - NumberPicker input = new NumberPicker(itemView.getContext()); - input.setMinValue(0); - input.setMaxValue(2); - input.setDisplayedValues( - itemView.getResources().getStringArray(R.array.gain_modes)); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputSetGainModeButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), input_id, - input.getValue() == 2); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - } - }); - - inputGetGainPropsButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputGetGainPropsButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), input_id); - } - }); - - inputGetTypeButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputGetTypeButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), input_id); - } - }); - - inputGetStatusButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputGetStatusButton( - devices.get(ViewHolder.this.getAdapterPosition()), input_id); - } - }); - - inputGetDescriptionButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputGetDescriptionButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), input_id); - } - }); - - inputSetDescriptionButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (inputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. input, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + Integer output_id = + Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); + if (volumeControlInteractionListener != null) + volumeControlInteractionListener.onOutputGetGainButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), output_id); + }); - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Set a description"); - final EditText input = new EditText(itemView.getContext()); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - Integer input_id = - Integer.valueOf(inputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onInputSetDescriptionButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), input_id, - input.getText().toString()); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - } - }); - - outpuGetGainButton.setOnClickListener(view -> { - if (outputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. output, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } - - Integer output_id = Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); - if (volumeControlInteractionListener != null) - volumeControlInteractionListener.onOutputGetGainButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), output_id); - }); - - outputGainOffsetSeekBar - .setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + outputGainOffsetSeekBar.setOnSeekBarChangeListener( + new SeekBar.OnSeekBarChangeListener() { @Override - public void onProgressChanged(SeekBar seekBar, int value, - boolean is_from_user) { + public void onProgressChanged( + SeekBar seekBar, int value, boolean is_from_user) { // Do nothing here } @@ -1720,9 +2085,11 @@ public class LeAudioRecycleViewAdapter @Override public void onStopTrackingTouch(SeekBar seekBar) { if (outputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(seekBar.getContext(), - "No known ext. output, please reconnect.", - Toast.LENGTH_SHORT).show(); + Toast.makeText( + seekBar.getContext(), + "No known ext. output, please reconnect.", + Toast.LENGTH_SHORT) + .show(); return; } @@ -1731,97 +2098,141 @@ public class LeAudioRecycleViewAdapter if (volumeControlInteractionListener != null) volumeControlInteractionListener.onOutputGainOffsetGainValueChanged( devices.get(ViewHolder.this.getAdapterPosition()), - output_id, seekBar.getProgress()); + output_id, + seekBar.getProgress()); } }); - outputGetLocationButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (outputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. output, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + outputGetLocationButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (outputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. output, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } - Integer output_id = - Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onOutputGetLocationButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), output_id); - } - }); - - outputSetLocationButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (outputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. output, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + Integer output_id = + Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onOutputGetLocationButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), output_id); + } + }); - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Pick an Audio Location"); - NumberPicker input = new NumberPicker(itemView.getContext()); - input.setMinValue(0); - input.setMaxValue( - itemView.getResources().getStringArray(R.array.audio_locations).length - - 1); - input.setDisplayedValues( - itemView.getResources().getStringArray(R.array.audio_locations)); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - Integer output_id = - Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onOutputSetLocationButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), output_id, - input.getValue()); - }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing - }); - alert.show(); - } - }); - - outputGetDescriptionButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (outputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. output, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + outputSetLocationButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (outputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. output, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } - Integer output_id = - Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onOutputGetDescriptionButtonClicked( - devices.get(ViewHolder.this.getAdapterPosition()), output_id); - } - }); - - outputSetDescriptionButton.setOnClickListener(view -> { - if (volumeControlInteractionListener != null) { - if (outputIdxSpinner.getSelectedItem() == null) { - Toast.makeText(view.getContext(), "No known ext. output, please reconnect.", - Toast.LENGTH_SHORT).show(); - return; - } + AlertDialog.Builder alert = + new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Pick an Audio Location"); + NumberPicker input = new NumberPicker(itemView.getContext()); + input.setMinValue(0); + input.setMaxValue( + itemView.getResources() + .getStringArray(R.array.audio_locations) + .length + - 1); + input.setDisplayedValues( + itemView.getResources() + .getStringArray(R.array.audio_locations)); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + Integer output_id = + Integer.valueOf( + outputIdxSpinner + .getSelectedItem() + .toString()); + volumeControlInteractionListener + .onOutputSetLocationButtonClicked( + devices.get( + ViewHolder.this + .getAdapterPosition()), + output_id, + input.getValue()); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + } + }); - AlertDialog.Builder alert = new AlertDialog.Builder(itemView.getContext()); - alert.setTitle("Set a description"); - final EditText input = new EditText(itemView.getContext()); - alert.setView(input); - alert.setPositiveButton("Ok", (dialog, whichButton) -> { - Integer output_id = - Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); - volumeControlInteractionListener.onOutputSetDescriptionButton( - devices.get(ViewHolder.this.getAdapterPosition()), output_id, - input.getText().toString()); + outputGetDescriptionButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (outputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. output, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + + Integer output_id = + Integer.valueOf(outputIdxSpinner.getSelectedItem().toString()); + volumeControlInteractionListener.onOutputGetDescriptionButtonClicked( + devices.get(ViewHolder.this.getAdapterPosition()), output_id); + } }); - alert.setNegativeButton("Cancel", (dialog, whichButton) -> { - // Do nothing + + outputSetDescriptionButton.setOnClickListener( + view -> { + if (volumeControlInteractionListener != null) { + if (outputIdxSpinner.getSelectedItem() == null) { + Toast.makeText( + view.getContext(), + "No known ext. output, please reconnect.", + Toast.LENGTH_SHORT) + .show(); + return; + } + + AlertDialog.Builder alert = + new AlertDialog.Builder(itemView.getContext()); + alert.setTitle("Set a description"); + final EditText input = new EditText(itemView.getContext()); + alert.setView(input); + alert.setPositiveButton( + "Ok", + (dialog, whichButton) -> { + Integer output_id = + Integer.valueOf( + outputIdxSpinner + .getSelectedItem() + .toString()); + volumeControlInteractionListener + .onOutputSetDescriptionButton( + devices.get( + ViewHolder.this + .getAdapterPosition()), + output_id, + input.getText().toString()); + }); + alert.setNegativeButton( + "Cancel", + (dialog, whichButton) -> { + // Do nothing + }); + alert.show(); + } }); - alert.show(); - } - }); } private void setupBassView(@NonNull View itemView) { @@ -1833,32 +2244,36 @@ public class LeAudioRecycleViewAdapter bassReceiverBisStateText = itemView.findViewById(R.id.receiver_bis_state_text); bassScanButton = itemView.findViewById(R.id.broadcast_button); - bassConnectionSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - if (!compoundButton.isActivated()) - return; - - if (bassInteractionListener != null) { - if (b) - bassInteractionListener.onConnectClick( - devices.get(ViewHolder.this.getAdapterPosition())); - else - bassInteractionListener.onDisconnectClick( - devices.get(ViewHolder.this.getAdapterPosition())); - } - }); - - bassReceiverIdSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, long l) { - LeAudioDeviceStateWrapper device = devices.get(ViewHolder.this.getAdapterPosition()); - ((ViewHolderBassPersistentData) device.bassData.viewsData).selectedReceiverPositionMutable.setValue(position); - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - // Nothing to do here - } - }); + bassConnectionSwitch.setOnCheckedChangeListener( + (compoundButton, b) -> { + if (!compoundButton.isActivated()) return; + + if (bassInteractionListener != null) { + if (b) + bassInteractionListener.onConnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + else + bassInteractionListener.onDisconnectClick( + devices.get(ViewHolder.this.getAdapterPosition())); + } + }); + + bassReceiverIdSpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected( + AdapterView adapterView, View view, int position, long l) { + LeAudioDeviceStateWrapper device = + devices.get(ViewHolder.this.getAdapterPosition()); + ((ViewHolderBassPersistentData) device.bassData.viewsData) + .selectedReceiverPositionMutable.setValue(position); + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + // Nothing to do here + } + }); bassScanButton.setOnClickListener( view -> { diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioViewModel.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioViewModel.java index 188440eb4d1..de389a818da 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioViewModel.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/LeAudioViewModel.java @@ -130,15 +130,16 @@ public class LeAudioViewModel extends AndroidViewModel { } // TODO: Uncomment this method if necessary -// public boolean getBroadcastReceiverState(BluetoothDevice device, int receiver_id) { -// return bluetoothProxy.getBroadcastReceiverState(device, receiver_id); -// } + // public boolean getBroadcastReceiverState(BluetoothDevice device, int receiver_id) { + // return bluetoothProxy.getBroadcastReceiverState(device, receiver_id); + // } // TODO: Uncomment this method if necessary -// public boolean modifyBroadcastSource(BluetoothDevice device, int receiver_id, boolean sync_pa, -// List configs) { -// return bluetoothProxy.modifyBroadcastSource(device, receiver_id, sync_pa, configs); -// } + // public boolean modifyBroadcastSource(BluetoothDevice device, int receiver_id, boolean + // sync_pa, + // List configs) { + // return bluetoothProxy.modifyBroadcastSource(device, receiver_id, sync_pa, configs); + // } public boolean removeBroadcastSource(BluetoothDevice sink, int receiver_id) { // TODO: Find source ID from receiver_id. What is receiver_id? diff --git a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/MainActivity.java b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/MainActivity.java index c2b2aaca2c7..14602b94f6b 100644 --- a/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/MainActivity.java +++ b/android/leaudio/app/src/main/java/com/android/bluetooth/leaudio/MainActivity.java @@ -45,19 +45,22 @@ import java.util.List; import java.util.Objects; public class MainActivity extends AppCompatActivity { - private static final String[] REQUIRED_PERMISSIONS = new String[] { - Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH_CONNECT, - Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_PRIVILEGED, - Manifest.permission.BLUETOOTH_ADVERTISE, Manifest.permission.INTERACT_ACROSS_USERS_FULL, - Manifest.permission.ACCESS_FINE_LOCATION,}; + private static final String[] REQUIRED_PERMISSIONS = + new String[] { + Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH_CONNECT, + Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_PRIVILEGED, + Manifest.permission.BLUETOOTH_ADVERTISE, + Manifest.permission.INTERACT_ACROSS_USERS_FULL, + Manifest.permission.ACCESS_FINE_LOCATION, + }; LeAudioRecycleViewAdapter recyclerViewAdapter; private LeAudioViewModel leAudioViewModel; /** Returns true if any of the required permissions is missing. */ private boolean isPermissionMissing() { for (String permission : REQUIRED_PERMISSIONS) { - if (ContextCompat.checkSelfPermission(this, - permission) != PackageManager.PERMISSION_GRANTED) { + if (ContextCompat.checkSelfPermission(this, permission) + != PackageManager.PERMISSION_GRANTED) { return true; } } @@ -76,28 +79,33 @@ public class MainActivity extends AppCompatActivity { // The 'refresh devices' button FloatingActionButton fab = findViewById(R.id.fab); - fab.setOnClickListener(view -> { - leAudioViewModel.queryDevices(); - ObjectAnimator.ofFloat(fab, "rotation", 0f, 360f).setDuration(500).start(); - }); + fab.setOnClickListener( + view -> { + leAudioViewModel.queryDevices(); + ObjectAnimator.ofFloat(fab, "rotation", 0f, 360f).setDuration(500).start(); + }); } /** Request permission if missing. */ private void setupPermissions() { if (isPermissionMissing()) { - ActivityResultLauncher permissionLauncher = registerForActivityResult( - new ActivityResultContracts.RequestMultiplePermissions(), result -> { - for (String permission : REQUIRED_PERMISSIONS) { - if (!Objects.requireNonNull(result.get(permission))) { - Toast.makeText(getApplicationContext(), - "LeAudio test apk permission denied.", Toast.LENGTH_SHORT) - .show(); - finish(); - return; - } - } - initialize(); - }); + ActivityResultLauncher permissionLauncher = + registerForActivityResult( + new ActivityResultContracts.RequestMultiplePermissions(), + result -> { + for (String permission : REQUIRED_PERMISSIONS) { + if (!Objects.requireNonNull(result.get(permission))) { + Toast.makeText( + getApplicationContext(), + "LeAudio test apk permission denied.", + Toast.LENGTH_SHORT) + .show(); + finish(); + return; + } + } + initialize(); + }); permissionLauncher.launch(REQUIRED_PERMISSIONS); } else { @@ -150,8 +158,11 @@ public class MainActivity extends AppCompatActivity { intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivityForResult(intent, 0); } else { - Toast.makeText(MainActivity.this, "Broadcast Source is not supported.", - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Broadcast Source is not supported.", + Toast.LENGTH_SHORT) + .show(); } return true; default: @@ -169,8 +180,11 @@ public class MainActivity extends AppCompatActivity { if (requestCode == 0xc0de) { if (intent != null) { String message = intent.getStringExtra("MESSAGE"); - Toast.makeText(MainActivity.this, message + "(" + resultCode + ")", - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + message + "(" + resultCode + ")", + Toast.LENGTH_SHORT) + .show(); } // TODO: Depending on the resultCode we should either stop the sync or try the PAST @@ -188,21 +202,28 @@ public class MainActivity extends AppCompatActivity { leAudioViewModel = ViewModelProviders.of(this).get(LeAudioViewModel.class); // Observe bluetooth adapter state - leAudioViewModel.getBluetoothEnabledLive().observe(this, is_enabled -> { - if (is_enabled) { - List deviceList = - leAudioViewModel.getAllLeAudioDevicesLive().getValue(); - if (deviceList == null || deviceList.size() == 0) - leAudioViewModel.queryDevices(); - } else { - Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); - startActivityForResult(enableBtIntent, 1); - } + leAudioViewModel + .getBluetoothEnabledLive() + .observe( + this, + is_enabled -> { + if (is_enabled) { + List deviceList = + leAudioViewModel.getAllLeAudioDevicesLive().getValue(); + if (deviceList == null || deviceList.size() == 0) + leAudioViewModel.queryDevices(); + } else { + Intent enableBtIntent = + new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + startActivityForResult(enableBtIntent, 1); + } - Toast.makeText(MainActivity.this, - "Bluetooth is " + (is_enabled ? "enabled" : "disabled"), Toast.LENGTH_SHORT) - .show(); - }); + Toast.makeText( + MainActivity.this, + "Bluetooth is " + (is_enabled ? "enabled" : "disabled"), + Toast.LENGTH_SHORT) + .show(); + }); } private void cleanupLeAudioViewModel() { @@ -229,9 +250,10 @@ public class MainActivity extends AppCompatActivity { } private void setupViewsListItemClickListener() { - recyclerViewAdapter.setOnItemClickListener(device -> { - // Not used anymore - }); + recyclerViewAdapter.setOnItemClickListener( + device -> { + // Not used anymore + }); } private void cleanupViewsListItemClickListener() { @@ -244,27 +266,33 @@ public class MainActivity extends AppCompatActivity { @Override public void onConnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - Toast.makeText(MainActivity.this, - "Connecting Le Audio to " - + leAudioDeviceStateWrapper.device.toString(), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Connecting Le Audio to " + + leAudioDeviceStateWrapper.device.toString(), + Toast.LENGTH_SHORT) + .show(); leAudioViewModel.connectLeAudio(leAudioDeviceStateWrapper.device, true); } @Override public void onDisconnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - Toast.makeText(MainActivity.this, - "Disconnecting Le Audio from " - + leAudioDeviceStateWrapper.device.toString(), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Disconnecting Le Audio from " + + leAudioDeviceStateWrapper.device.toString(), + Toast.LENGTH_SHORT) + .show(); leAudioViewModel.connectLeAudio(leAudioDeviceStateWrapper.device, false); } @Override public void onStreamActionClicked( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, Integer group_id, - Integer content_type, Integer action) { + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + Integer group_id, + Integer content_type, + Integer action) { leAudioViewModel.streamAction(group_id, action, content_type); } @@ -284,25 +312,31 @@ public class MainActivity extends AppCompatActivity { public void onGroupDestroyClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, Integer group_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onGroupSetLockClicked( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, Integer group_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + Integer group_id, boolean lock) { leAudioViewModel.groupSetLock(group_id, lock); } @Override public void onMicrophoneMuteChanged( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, boolean mute, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + boolean mute, boolean is_from_user) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } }); @@ -313,8 +347,10 @@ public class MainActivity extends AppCompatActivity { public void onConnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -322,14 +358,18 @@ public class MainActivity extends AppCompatActivity { public void onDisconnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override - public void onVolumeChanged(LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, - int volume, boolean is_from_user) { + public void onVolumeChanged( + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int volume, + boolean is_from_user) { if (is_from_user) { leAudioViewModel.setVolume(leAudioDeviceStateWrapper.device, volume); } @@ -340,8 +380,10 @@ public class MainActivity extends AppCompatActivity { LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, boolean is_checked) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -349,38 +391,49 @@ public class MainActivity extends AppCompatActivity { public void onInputGetStateButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onInputGainValueChanged( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int input_id, int value) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onInputMuteSwitched( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int input_id, boolean is_muted) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onInputSetGainModeButtonClicked( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int input_id, boolean is_auto) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -388,8 +441,10 @@ public class MainActivity extends AppCompatActivity { public void onInputGetGainPropsButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -397,8 +452,10 @@ public class MainActivity extends AppCompatActivity { public void onInputGetTypeButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -406,8 +463,10 @@ public class MainActivity extends AppCompatActivity { public void onInputGetStatusButton( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -415,18 +474,23 @@ public class MainActivity extends AppCompatActivity { public void onInputGetDescriptionButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onInputSetDescriptionButtonClicked( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int input_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int input_id, String description) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -434,18 +498,23 @@ public class MainActivity extends AppCompatActivity { public void onOutputGetGainButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onOutputGainOffsetGainValueChanged( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int output_id, int value) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -453,18 +522,23 @@ public class MainActivity extends AppCompatActivity { public void onOutputGetLocationButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onOutputSetLocationButtonClicked( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int output_id, int location) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @@ -472,18 +546,23 @@ public class MainActivity extends AppCompatActivity { public void onOutputGetDescriptionButtonClicked( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } @Override public void onOutputSetDescriptionButton( - LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, int output_id, + LeAudioDeviceStateWrapper leAudioDeviceStateWrapper, + int output_id, String description) { // Not available anymore - Toast.makeText(MainActivity.this, - "Operation not supported on this API version", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Operation not supported on this API version", + Toast.LENGTH_SHORT) .show(); } }); @@ -493,19 +572,24 @@ public class MainActivity extends AppCompatActivity { @Override public void onConnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - Toast.makeText(MainActivity.this, - "Connecting HAP to " + leAudioDeviceStateWrapper.device.toString(), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Connecting HAP to " + + leAudioDeviceStateWrapper.device.toString(), + Toast.LENGTH_SHORT) + .show(); leAudioViewModel.connectHap(leAudioDeviceStateWrapper.device, true); } @Override public void onDisconnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - Toast.makeText(MainActivity.this, - "Disconnecting HAP from " - + leAudioDeviceStateWrapper.device.toString(), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Disconnecting HAP from " + + leAudioDeviceStateWrapper.device.toString(), + Toast.LENGTH_SHORT) + .show(); leAudioViewModel.connectHap(leAudioDeviceStateWrapper.device, false); } @@ -520,13 +604,14 @@ public class MainActivity extends AppCompatActivity { } @Override - public void onSetActivePresetForGroupClicked(BluetoothDevice device, int preset_index) { + public void onSetActivePresetForGroupClicked( + BluetoothDevice device, int preset_index) { leAudioViewModel.hapSetActivePresetForGroup(device, preset_index); } @Override - public void onChangePresetNameClicked(BluetoothDevice device, int preset_index, - String name) { + public void onChangePresetNameClicked( + BluetoothDevice device, int preset_index, String name) { leAudioViewModel.hapChangePresetName(device, preset_index, name); } @@ -545,8 +630,10 @@ public class MainActivity extends AppCompatActivity { final int group_id = leAudioViewModel.hapGetHapGroup(device); final boolean sent = leAudioViewModel.hapPreviousGroupPreset(group_id); if (!sent) - Toast.makeText(MainActivity.this, - "Group " + group_id + " operation failed", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Group " + group_id + " operation failed", + Toast.LENGTH_SHORT) .show(); } @@ -555,8 +642,10 @@ public class MainActivity extends AppCompatActivity { final int group_id = leAudioViewModel.hapGetHapGroup(device); final boolean sent = leAudioViewModel.hapNextGroupPreset(group_id); if (!sent) - Toast.makeText(MainActivity.this, - "Group " + group_id + " operation failed", Toast.LENGTH_SHORT) + Toast.makeText( + MainActivity.this, + "Group " + group_id + " operation failed", + Toast.LENGTH_SHORT) .show(); } }); @@ -566,19 +655,24 @@ public class MainActivity extends AppCompatActivity { @Override public void onConnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - Toast.makeText(MainActivity.this, - "Connecting BASS to " + leAudioDeviceStateWrapper.device.toString(), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Connecting BASS to " + + leAudioDeviceStateWrapper.device.toString(), + Toast.LENGTH_SHORT) + .show(); leAudioViewModel.connectBass(leAudioDeviceStateWrapper.device, true); } @Override public void onDisconnectClick( LeAudioDeviceStateWrapper leAudioDeviceStateWrapper) { - Toast.makeText(MainActivity.this, - "Disconnecting BASS from " - + leAudioDeviceStateWrapper.device.toString(), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, + "Disconnecting BASS from " + + leAudioDeviceStateWrapper.device.toString(), + Toast.LENGTH_SHORT) + .show(); leAudioViewModel.connectBass(leAudioDeviceStateWrapper.device, false); } @@ -590,8 +684,8 @@ public class MainActivity extends AppCompatActivity { } @Override - public void onBroadcastCodeEntered(BluetoothDevice device, int receiver_id, - byte[] broadcast_code) { + public void onBroadcastCodeEntered( + BluetoothDevice device, int receiver_id, byte[] broadcast_code) { leAudioViewModel.setBroadcastCode(device, receiver_id, broadcast_code); } @@ -599,14 +693,20 @@ public class MainActivity extends AppCompatActivity { public void onStopSyncReq(BluetoothDevice device, int receiver_id) { // TODO: When is onStopSyncReq called? and what does below code do? -// List configs = new ArrayList<>(); -// // JT@CC: How come you can call this with null metadata when the -// // constructor has the @Nonull annotation for the param? -// BluetoothBroadcastAudioScanBaseConfig stop_config = -// new BluetoothBroadcastAudioScanBaseConfig(0, new byte[] {}); -// configs.add(stop_config); -// -// leAudioViewModel.modifyBroadcastSource(device, receiver_id, false, configs); + // List + // configs = new ArrayList<>(); + // // JT@CC: How come you can call this with null + // metadata when the + // // constructor has the @Nonull annotation for the + // param? + // BluetoothBroadcastAudioScanBaseConfig stop_config + // = + // new + // BluetoothBroadcastAudioScanBaseConfig(0, new byte[] {}); + // configs.add(stop_config); + // + // leAudioViewModel.modifyBroadcastSource(device, + // receiver_id, false, configs); } @Override @@ -633,11 +733,14 @@ public class MainActivity extends AppCompatActivity { List devices = leAudioViewModel.getAllLeAudioDevicesLive().getValue(); - if (devices != null) - recyclerViewAdapter.updateLeAudioDeviceList(devices); - leAudioViewModel.getAllLeAudioDevicesLive().observe(this, bluetoothDevices -> { - recyclerViewAdapter.updateLeAudioDeviceList(bluetoothDevices); - }); + if (devices != null) recyclerViewAdapter.updateLeAudioDeviceList(devices); + leAudioViewModel + .getAllLeAudioDevicesLive() + .observe( + this, + bluetoothDevices -> { + recyclerViewAdapter.updateLeAudioDeviceList(bluetoothDevices); + }); } private void cleanupViewModelObservers() { diff --git a/android/leaudio/app/src/test/java/pl/codecoup/ehima/leaudio/ExampleUnitTest.java b/android/leaudio/app/src/test/java/pl/codecoup/ehima/leaudio/ExampleUnitTest.java index 3b28728ef63..53e6ef47b36 100644 --- a/android/leaudio/app/src/test/java/pl/codecoup/ehima/leaudio/ExampleUnitTest.java +++ b/android/leaudio/app/src/test/java/pl/codecoup/ehima/leaudio/ExampleUnitTest.java @@ -14,4 +14,4 @@ public class ExampleUnitTest { public void addition_isCorrect() { assertEquals(4, 2 + 2); } -} \ No newline at end of file +} -- GitLab From cbf09319488928298b51f1a65d6378547d4a9da1 Mon Sep 17 00:00:00 2001 From: William Escande Date: Fri, 31 May 2024 11:54:50 -0700 Subject: [PATCH 2/3] Reformat java file in android/app/tests Bug: 311772251 Flag: Exempt refactor Test: None Change-Id: I9d280c4e5ad8c7362f6dff440b27180ee0e230b1 --- .../bluetooth/FileSystemWriteTest.java | 5 +- .../bluetooth/ObexAppParametersTest.java | 12 +- .../android/bluetooth/SignedLongLongTest.java | 10 +- .../src/com/android/bluetooth/TestUtils.java | 114 +- .../src/com/android/bluetooth/UtilsTest.java | 15 +- .../bluetooth/a2dp/A2dpCodecConfigTest.java | 830 +++++---- .../bluetooth/a2dp/A2dpServiceBinderTest.java | 2 +- .../bluetooth/a2dp/A2dpStateMachineTest.java | 197 +- .../a2dpsink/A2dpSinkServiceBinderTest.java | 2 +- .../a2dpsink/A2dpSinkServiceTest.java | 178 +- .../a2dpsink/A2dpSinkStateMachineTest.java | 6 +- .../a2dpsink/A2dpSinkStreamHandlerTest.java | 40 +- .../BrowsablePlayerConnectorTest.java | 40 +- .../audio_util/BrowserPlayerWrapperTest.java | 67 +- .../bluetooth/audio_util/GPMWrapperTest.java | 42 +- .../bluetooth/audio_util/ImageTest.java | 199 +- .../audio_util/MediaPlayerListTest.java | 46 +- .../audio_util/MediaPlayerWrapperTest.java | 62 +- .../bluetooth/audio_util/MetadataTest.java | 1058 +++++++---- .../bluetooth/audio_util/UtilTest.java | 39 +- .../avrcp/AvrcpBipObexServerTest.java | 161 +- .../avrcp/AvrcpCoverArtStorageTest.java | 20 +- .../bluetooth/avrcp/AvrcpPassthroughTest.java | 227 ++- .../avrcp/AvrcpVolumeManagerTest.java | 6 +- .../android/bluetooth/avrcp/CoverArtTest.java | 60 +- .../avrcpcontroller/AvrcpBipClientTest.java | 24 +- .../AvrcpControllerServiceBinderTest.java | 3 +- .../AvrcpControllerServiceTest.java | 57 +- .../AvrcpControllerStateMachineTest.java | 468 +++-- .../AvrcpCoverArtProviderTest.java | 13 +- .../AvrcpCoverArtStorageTest.java | 23 +- .../avrcpcontroller/AvrcpItemTest.java | 313 ++-- .../avrcpcontroller/AvrcpPlayerTest.java | 48 +- .../avrcpcontroller/BrowseNodeTest.java | 121 +- .../avrcpcontroller/BrowseTreeTest.java | 55 +- .../PlayerApplicationSettingsTest.java | 162 +- .../avrcpcontroller/StackEventTest.java | 10 +- .../bip/BipAttachmentFormatTest.java | 301 ++- .../avrcpcontroller/bip/BipDatetimeTest.java | 81 +- .../avrcpcontroller/bip/BipEncodingTest.java | 43 +- .../bip/BipImageDescriptorTest.java | 95 +- .../bip/BipImageFormatTest.java | 110 +- .../bip/BipImagePropertiesTest.java | 272 +-- .../avrcpcontroller/bip/BipImageTest.java | 32 +- .../avrcpcontroller/bip/BipPixelTest.java | 87 +- .../bip/BipTransformationTest.java | 31 +- .../bip/RequestGetImagePropertiesTest.java | 14 +- .../bip/RequestGetImageTest.java | 10 +- .../bas/BatteryServiceBinderTest.java | 5 +- .../bluetooth/bas/BatteryServiceTest.java | 175 +- .../bas/BatteryStateMachineTest.java | 48 +- .../bluetooth/bass_client/BaseDataTest.java | 2 +- .../bass_client/BassClientServiceTest.java | 881 +++++---- .../BassClientStateMachineTest.java | 633 ++++--- .../BleBroadcastAssistantBinderTest.java | 15 +- .../PeriodicAdvertisementResultTest.java | 51 +- .../bass_client/PublicBroadcastDataTest.java | 51 +- .../btservice/ActiveDeviceManagerTest.java | 275 ++- .../btservice/AdapterServiceBinderTest.java | 2 +- .../btservice/AdapterServiceRestartTest.java | 29 +- .../btservice/AdapterServiceTest.java | 85 +- .../btservice/BondStateMachineTest.java | 565 +++--- .../btservice/CompanionManagerTest.java | 41 +- .../btservice/DataMigrationTest.java | 112 +- .../bluetooth/btservice/PhonePolicyTest.java | 437 +++-- .../btservice/ProfileServiceTest.java | 1 - .../btservice/RemoteDevicesTest.java | 422 +++-- .../btservice/SilenceDeviceManagerTest.java | 48 +- .../BluetoothKeystoreServiceTest.java | 159 +- .../storage/DatabaseManagerTest.java | 802 ++++---- .../csip/BluetoothCsisBinderTest.java | 5 +- .../csip/CsipSetCoordinatorServiceTest.java | 277 +-- .../CsipSetCoordinatorStateMachineTest.java | 230 ++- .../bluetooth/gatt/AdvertiseHelperTest.java | 53 +- .../bluetooth/gatt/AdvertiseManagerTest.java | 36 +- .../bluetooth/gatt/AppAdvertiseStatsTest.java | 91 +- .../bluetooth/gatt/CallbackInfoTest.java | 10 +- .../bluetooth/gatt/ContextMapTest.java | 10 +- .../gatt/DistanceMeasurementManagerTest.java | 177 +- .../gatt/DistanceMeasurementTrackerTest.java | 51 +- .../bluetooth/gatt/FilterParamsTest.java | 32 +- .../bluetooth/gatt/GattDebugUtilsTest.java | 11 +- .../bluetooth/gatt/GattServiceBinderTest.java | 106 +- .../bluetooth/gatt/GattServiceTest.java | 139 +- .../hap/HapClientNativeInterfaceTest.java | 77 +- .../hap/HapClientStackEventTest.java | 279 +-- .../hap/HapClientStateMachineTest.java | 175 +- .../android/bluetooth/hap/HapClientTest.java | 605 +++--- .../HearingAidNativeInterfaceTest.java | 24 +- .../HearingAidStateMachineTest.java | 122 +- .../bluetooth/hfp/AtPhonebookTest.java | 174 +- .../hfp/BluetoothHeadsetBinderTest.java | 9 +- .../HeadsetAgIndicatorEnableStateTest.java | 4 +- .../hfp/HeadsetClccResponseTest.java | 73 +- .../bluetooth/hfp/HeadsetPhoneStateTest.java | 161 +- .../bluetooth/hfp/HeadsetStackEventTest.java | 10 +- .../hfp/HeadsetStateMachineTest.java | 1604 +++++++++------- .../bluetooth/hfp/HeadsetTestUtils.java | 62 +- .../HeadsetVendorSpecificResultCodeTest.java | 18 +- .../HeadsetClientServiceBinderTest.java | 3 +- .../hfpclient/HeadsetClientServiceTest.java | 10 +- .../HeadsetClientStateMachineTest.java | 785 ++++---- .../hfpclient/HfpNativeInterfaceTest.java | 8 +- .../bluetooth/hfpclient/StackEventTest.java | 25 +- .../VendorCommandResponseProcessorTest.java | 41 +- .../HeadsetClientServiceInterfaceTest.java | 40 +- .../hfpclient/connserv/HfpClientCallTest.java | 407 ++-- .../HfpClientConnectionServiceTest.java | 242 ++- .../connserv/HfpClientConnectionTest.java | 186 +- .../connserv/HfpClientDeviceBlockTest.java | 80 +- .../hid/BluetoothHidDeviceBinderTest.java | 36 +- .../hid/HidDeviceNativeInterfaceTest.java | 16 +- .../android/bluetooth/hid/HidDeviceTest.java | 280 ++- .../hid/HidHostServiceBinderTest.java | 7 +- .../bluetooth/hid/HidHostServiceTest.java | 95 +- .../le_audio/ContentControlIdKeeperTest.java | 35 +- .../bluetooth/le_audio/LeAudioBinderTest.java | 15 +- .../le_audio/LeAudioBroadcastServiceTest.java | 83 +- ...LeAudioBroadcasterNativeInterfaceTest.java | 29 +- .../le_audio/LeAudioNativeInterfaceTest.java | 61 +- .../le_audio/LeAudioServiceTest.java | 797 ++++---- .../le_audio/LeAudioStateMachineTest.java | 42 +- .../le_audio/LeAudioTmapGattServerTest.java | 3 +- .../AdvtFilterOnFoundOnLostInfoTest.java | 40 +- .../bluetooth/le_scan/AppScanStatsTest.java | 10 +- .../le_scan/ScanFilterQueueTest.java | 49 +- .../bluetooth/le_scan/ScanManagerTest.java | 299 ++- .../map/BluetoothMapAccountItemTest.java | 398 +++- .../map/BluetoothMapAppParamsTest.java | 117 +- .../map/BluetoothMapContentObserverTest.java | 1659 +++++++++++------ .../map/BluetoothMapContentTest.java | 1521 +++++++++------ .../BluetoothMapConvoContactElementTest.java | 125 +- .../BluetoothMapConvoListingElementTest.java | 44 +- .../map/BluetoothMapConvoListingTest.java | 14 +- .../map/BluetoothMapFolderElementTest.java | 57 +- .../map/BluetoothMapMasInstanceTest.java | 32 +- ...BluetoothMapMessageListingElementTest.java | 34 +- .../map/BluetoothMapMessageListingTest.java | 12 +- .../map/BluetoothMapObexServerTest.java | 176 +- .../map/BluetoothMapServiceBinderTest.java | 3 +- .../map/BluetoothMapServiceTest.java | 17 +- .../map/BluetoothMapSettingsTest.java | 15 +- .../bluetooth/map/BluetoothMapSmsPduTest.java | 107 +- .../bluetooth/map/BluetoothMapUtilsTest.java | 11 +- .../map/BluetoothMapbMessageEmailTest.java | 10 +- .../map/BluetoothMapbMessageMimeTest.java | 87 +- .../map/BluetoothMapbMessageSmsTest.java | 14 +- .../map/BluetoothMapbMessageTest.java | 78 +- .../map/BluetoothMapbMessageVCardTest.java | 63 +- .../bluetooth/map/ConvoContactInfoTest.java | 27 +- .../com/android/bluetooth/map/EventTest.java | 85 +- .../android/bluetooth/map/FilterInfoTest.java | 125 +- .../android/bluetooth/map/MapContactTest.java | 4 +- .../com/android/bluetooth/map/MsgTest.java | 36 +- .../bluetooth/map/SmsMmsContactsTest.java | 114 +- .../mapapi/BluetoothMapContractTest.java | 92 +- .../mapapi/BluetoothMapEmailProviderTest.java | 328 ++-- .../mapapi/BluetoothMapIMProviderTest.java | 446 +++-- .../bluetooth/mapclient/BmessageTest.java | 26 +- .../bluetooth/mapclient/EventReportTest.java | 4 +- .../mapclient/MapClientContentTest.java | 293 ++- .../mapclient/MapClientServiceBinderTest.java | 6 +- .../mapclient/MapClientServiceTest.java | 12 +- .../mapclient/MapClientStateMachineTest.java | 819 ++++---- .../bluetooth/mapclient/MapClientTest.java | 17 +- .../mapclient/MnsObexServerTest.java | 22 +- .../bluetooth/mapclient/ObexTimeTest.java | 48 +- ...estGetMessagesListingForOwnNumberTest.java | 309 +-- .../bluetooth/mapclient/RequestTest.java | 49 +- .../android/bluetooth/mcp/McpServiceTest.java | 13 +- .../mcp/MediaControlGattServiceTest.java | 709 ++++--- .../mcp/MediaControlProfileTest.java | 127 +- .../bluetooth/obex/FakeObexServer.java | 19 +- .../bluetooth/obex/FakeObexTransport.java | 21 +- .../bluetooth/opp/BluetoothOppBatchTest.java | 66 +- .../opp/BluetoothOppBtEnableActivityTest.java | 10 +- .../BluetoothOppBtEnablingActivityTest.java | 53 +- .../opp/BluetoothOppHandoverReceiverTest.java | 53 +- .../opp/BluetoothOppLauncherActivityTest.java | 62 +- .../opp/BluetoothOppManagerTest.java | 157 +- .../opp/BluetoothOppNotificationTest.java | 303 ++- .../BluetoothOppObexClientSessionTest.java | 77 +- .../BluetoothOppObexServerSessionTest.java | 110 +- .../opp/BluetoothOppPreferenceTest.java | 32 +- .../opp/BluetoothOppReceiveFileInfoTest.java | 151 +- .../opp/BluetoothOppReceiverTest.java | 209 ++- .../opp/BluetoothOppSendFileInfoTest.java | 69 +- .../opp/BluetoothOppShareInfoTest.java | 19 +- .../bluetooth/opp/BluetoothOppTestUtils.java | 91 +- .../opp/BluetoothOppTransferActivityTest.java | 138 +- .../opp/BluetoothOppTransferHistoryTest.java | 129 +- .../opp/BluetoothOppTransferTest.java | 232 ++- .../opp/BluetoothOppUtilityTest.java | 304 +-- .../opp/IncomingFileConfirmActivityTest.java | 149 +- .../android/bluetooth/opp/TestActivity.java | 405 ++-- .../BluetoothTetheringNetworkFactoryTest.java | 10 +- .../bluetooth/pan/PanServiceBinderTest.java | 3 +- .../android/bluetooth/pan/PanServiceTest.java | 28 +- .../pbap/BluetoothPbapActivityTest.java | 47 +- .../pbap/BluetoothPbapAuthenticatorTest.java | 49 +- .../BluetoothPbapCallLogComposerTest.java | 32 +- .../pbap/BluetoothPbapConfigTest.java | 20 +- .../pbap/BluetoothPbapObexServerTest.java | 185 +- .../pbap/BluetoothPbapServiceBinderTest.java | 3 +- .../pbap/BluetoothPbapServiceTest.java | 6 +- .../BluetoothPbapSimVcardManagerTest.java | 298 +-- .../pbap/BluetoothPbapUtilsTest.java | 116 +- ...oothPbapVcardManagerNestedClassesTest.java | 110 +- .../pbap/BluetoothPbapVcardManagerTest.java | 324 ++-- .../pbap/HandlerForStringBufferTest.java | 11 +- .../bluetooth/pbap/PbapStateMachineTest.java | 51 +- .../pbapclient/AuthenticationServiceTest.java | 15 +- .../pbapclient/AuthenticatorTest.java | 17 +- .../BluetoothPbapObexAuthenticatorTest.java | 7 +- ...toothPbapRequestPullPhoneBookSizeTest.java | 4 +- ...BluetoothPbapRequestPullPhoneBookTest.java | 71 +- .../pbapclient/BluetoothPbapRequestTest.java | 3 +- .../BluetoothPbapVcardListTest.java | 87 +- .../pbapclient/CallLogPullRequestTest.java | 40 +- .../PbapClientConnectionHandlerTest.java | 25 +- .../pbapclient/PbapClientServiceTest.java | 27 +- .../PbapClientStateMachineTest.java | 38 +- .../bluetooth/pbapclient/PbapParserTest.java | 98 +- .../android/bluetooth/sap/SapMessageTest.java | 22 +- .../bluetooth/sap/SapRilReceiverHidlTest.java | 359 ++-- .../bluetooth/sap/SapRilReceiverTest.java | 359 ++-- .../android/bluetooth/sap/SapServerTest.java | 99 +- .../android/bluetooth/sap/SapServiceTest.java | 10 +- .../com/android/bluetooth/sdp/DipTest.java | 59 +- .../android/bluetooth/tbs/TbsGattTest.java | 718 ++++--- .../android/bluetooth/tbs/TbsGenericTest.java | 274 ++- .../telephony/BluetoothCallTest.java | 22 +- .../telephony/BluetoothInCallServiceTest.java | 843 ++++++--- .../bluetooth/telephony/CallInfoTest.java | 16 +- .../bluetooth/util/GsmAlphabetTest.java | 325 ++-- .../vc/VolumeControlNativeInterfaceTest.java | 44 +- .../vc/VolumeControlServiceTest.java | 574 +++--- .../vc/VolumeControlStateMachineTest.java | 201 +- 238 files changed, 21007 insertions(+), 14806 deletions(-) diff --git a/android/app/tests/unit/src/com/android/bluetooth/FileSystemWriteTest.java b/android/app/tests/unit/src/com/android/bluetooth/FileSystemWriteTest.java index a0215a8a243..d04d2c2026e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/FileSystemWriteTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/FileSystemWriteTest.java @@ -25,10 +25,7 @@ import org.junit.runner.RunWith; import java.io.File; import java.io.IOException; -/** - * Test Bluetooth's ability to write to the different directories that it - * is supposed to own - */ +/** Test Bluetooth's ability to write to the different directories that it is supposed to own */ @MediumTest @RunWith(AndroidJUnit4.class) public class FileSystemWriteTest { diff --git a/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java b/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java index 4e8459168aa..c7bb30475e3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java @@ -40,8 +40,10 @@ public class ObexAppParametersTest { public void constructorWithByteArrays_withOneInvalidElement() { final int length = 4; - byte[] byteArray = new byte[] {KEY, length, 0x12, 0x34, 0x56, 0x78, - 0x66}; // Last one is invalid. It will be filtered out. + byte[] byteArray = + new byte[] { + KEY, length, 0x12, 0x34, 0x56, 0x78, 0x66 + }; // Last one is invalid. It will be filtered out. ObexAppParameters params = new ObexAppParameters(byteArray); assertThat(params.exists(KEY)).isTrue(); @@ -53,8 +55,10 @@ public class ObexAppParametersTest { @Test public void constructorWithByteArrays_withTwoInvalidElements() { final int length = 4; - byte[] byteArray = new byte[] {KEY, length, 0x12, 0x34, 0x56, 0x78, - 0x66, 0x77}; // Last two are invalid. It will be filtered out. + byte[] byteArray = + new byte[] { + KEY, length, 0x12, 0x34, 0x56, 0x78, 0x66, 0x77 + }; // Last two are invalid. It will be filtered out. ObexAppParameters params = new ObexAppParameters(byteArray); assertThat(params.exists(KEY)).isTrue(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java b/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java index 0a4b682a42f..8a887b71eb7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java @@ -25,9 +25,7 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; -/** - * Test for SignedLongLong.java - */ +/** Test for SignedLongLong.java */ @SmallTest @RunWith(AndroidJUnit4.class) public class SignedLongLongTest { @@ -125,15 +123,13 @@ public class SignedLongLongTest { public void fromString_whenLengthIsNotGreaterThan16() throws Exception { String strValue = "1"; - assertThat(SignedLongLong.fromString(strValue)) - .isEqualTo(new SignedLongLong(1, 0)); + assertThat(SignedLongLong.fromString(strValue)).isEqualTo(new SignedLongLong(1, 0)); } @Test public void fromString_whenLengthIsGreaterThan16() throws Exception { String strValue = "B0000000000000002"; - assertThat(SignedLongLong.fromString(strValue)) - .isEqualTo(new SignedLongLong(2, 11)); + assertThat(SignedLongLong.fromString(strValue)).isEqualTo(new SignedLongLong(2, 11)); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java index e954a5cbccc..0821b7cd78c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java +++ b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java @@ -54,11 +54,9 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; -/** - * A set of methods useful in Bluetooth instrumentation tests - */ +/** A set of methods useful in Bluetooth instrumentation tests */ public class TestUtils { - private static final int SERVICE_TOGGLE_TIMEOUT_MS = 1000; // 1s + private static final int SERVICE_TOGGLE_TIMEOUT_MS = 1000; // 1s private static String sSystemScreenOffTimeout = "10000"; @@ -67,17 +65,18 @@ public class TestUtils { /** * Utility method to replace obj.fieldName with newValue where obj is of type c * - * @param c type of obj + * @param c type of obj * @param fieldName field name to be replaced - * @param obj instance of type c whose fieldName is to be replaced, null for static fields - * @param newValue object used to replace fieldName - * @return the old value of fieldName that got replaced, caller is responsible for restoring - * it back to obj - * @throws NoSuchFieldException when fieldName is not found in type c + * @param obj instance of type c whose fieldName is to be replaced, null for static fields + * @param newValue object used to replace fieldName + * @return the old value of fieldName that got replaced, caller is responsible for restoring it + * back to obj + * @throws NoSuchFieldException when fieldName is not found in type c * @throws IllegalAccessException when fieldName cannot be accessed in type c */ - public static Object replaceField(final Class c, final String fieldName, final Object obj, - final Object newValue) throws NoSuchFieldException, IllegalAccessException { + public static Object replaceField( + final Class c, final String fieldName, final Object obj, final Object newValue) + throws NoSuchFieldException, IllegalAccessException { Field field = c.getDeclaredField(fieldName); field.setAccessible(true); @@ -93,8 +92,10 @@ public class TestUtils { * mocked or spied */ public static void setAdapterService(AdapterService adapterService) { - Assert.assertNull("AdapterService.getAdapterService() must be null before setting another" - + " AdapterService", AdapterService.getAdapterService()); + Assert.assertNull( + "AdapterService.getAdapterService() must be null before setting another" + + " AdapterService", + AdapterService.getAdapterService()); Assert.assertNotNull("Adapter service should not be null", adapterService); // We cannot mock AdapterService.getAdapterService() with Mockito. // Hence we need to set AdapterService.sAdapterService field. @@ -108,8 +109,10 @@ public class TestUtils { * TestUtils#setAdapterService(AdapterService)} */ public static void clearAdapterService(AdapterService adapterService) { - Assert.assertSame("AdapterService.getAdapterService() must return the same object as the" - + " supplied adapterService in this method", adapterService, + Assert.assertSame( + "AdapterService.getAdapterService() must return the same object as the" + + " supplied adapterService in this method", + adapterService, AdapterService.getAdapterService()); Assert.assertNotNull("Adapter service should not be null", adapterService); AdapterService.clearAdapterService(adapterService); @@ -134,7 +137,7 @@ public class TestUtils { * Create a test device. * * @param bluetoothAdapter the Bluetooth adapter to use - * @param id the test device ID. It must be an integer in the interval [0, 0xFF]. + * @param id the test device ID. It must be an integer in the interval [0, 0xFF]. * @return {@link BluetoothDevice} test device for the device ID */ public static BluetoothDevice getTestDevice(BluetoothAdapter bluetoothAdapter, int id) { @@ -148,11 +151,13 @@ public class TestUtils { public static Resources getTestApplicationResources(Context context) { try { - return context.getPackageManager().getResourcesForApplication( - "com.android.bluetooth.tests"); + return context.getPackageManager() + .getResourcesForApplication("com.android.bluetooth.tests"); } catch (PackageManager.NameNotFoundException e) { - assertWithMessage("Setup Failure: Unable to get test application resources" - + e.toString()).fail(); + assertWithMessage( + "Setup Failure: Unable to get test application resources" + + e.toString()) + .fail(); return null; } } @@ -161,7 +166,7 @@ public class TestUtils { * Wait and verify that an intent has been received. * * @param timeoutMs the time (in milliseconds) to wait for the intent - * @param queue the queue for the intent + * @param queue the queue for the intent * @return the received intent */ public static Intent waitForIntent(int timeoutMs, BlockingQueue queue) { @@ -178,9 +183,8 @@ public class TestUtils { /** * Wait and verify that no intent has been received. * - * @param timeoutMs the time (in milliseconds) to wait and verify no intent - * has been received - * @param queue the queue for the intent + * @param timeoutMs the time (in milliseconds) to wait and verify no intent has been received + * @param queue the queue for the intent * @return the received intent. Should be null under normal circumstances */ public static Intent waitForNoIntent(int timeoutMs, BlockingQueue queue) { @@ -200,9 +204,11 @@ public class TestUtils { * @param looper looper of interest */ public static void waitForLooperToFinishScheduledTask(Looper looper) { - runOnLooperSync(looper, () -> { - // do nothing, just need to make sure looper finishes current task - }); + runOnLooperSync( + looper, + () -> { + // do nothing, just need to make sure looper finishes current task + }); } /** @@ -263,19 +269,18 @@ public class TestUtils { } /** - * Run synchronously a runnable action on a looper. - * The method will return after the action has been execution to completion. + * Run synchronously a runnable action on a looper. The method will return after the action has + * been execution to completion. + * + *

Example: * - * Example: - *

-     * {@code
+     * 
{@code
      * TestUtils.runOnMainSync(new Runnable() {
      *       public void run() {
      *           Assert.assertTrue(mA2dpService.stop());
      *       }
      *   });
-     * }
-     * 
+ * }
* * @param looper the looper used to run the action * @param action the action to run @@ -295,15 +300,13 @@ public class TestUtils { /** * Read Bluetooth adapter configuration from the filesystem * - * @return A {@link HashMap} of Bluetooth configs in the format: - * section -> key1 -> value1 - * -> key2 -> value2 - * Assume no empty section name, no duplicate keys in the same section + * @return A {@link HashMap} of Bluetooth configs in the format: section -> key1 -> value1 -> + * key2 -> value2 Assume no empty section name, no duplicate keys in the same section */ public static HashMap> readAdapterConfig() { HashMap> adapterConfig = new HashMap<>(); try (BufferedReader reader = - new BufferedReader(new FileReader("/data/misc/bluedroid/bt_config.conf"))) { + new BufferedReader(new FileReader("/data/misc/bluedroid/bt_config.conf"))) { String section = ""; for (String line; (line = reader.readLine()) != null; ) { line = line.trim(); @@ -319,8 +322,11 @@ public class TestUtils { adapterConfig.put(section, new HashMap<>()); } else { String[] keyValue = line.split("="); - adapterConfig.get(section).put(keyValue[0].trim(), - keyValue.length == 1 ? "" : keyValue[1].trim()); + adapterConfig + .get(section) + .put( + keyValue[0].trim(), + keyValue.length == 1 ? "" : keyValue[1].trim()); } } } catch (IOException e) { @@ -336,15 +342,18 @@ public class TestUtils { * @return intent with the appropriate component & action set. */ public static Intent prepareIntentToStartBluetoothBrowserMediaService() { - final Intent intent = new Intent(InstrumentationRegistry.getTargetContext(), - BluetoothMediaBrowserService.class); + final Intent intent = + new Intent( + InstrumentationRegistry.getTargetContext(), + BluetoothMediaBrowserService.class); intent.setAction(MediaBrowserService.SERVICE_INTERFACE); return intent; } public static void setUpUiTest() throws Exception { - final UiDevice device = UiDevice.getInstance( - androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); + final UiDevice device = + UiDevice.getInstance( + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); // Disable animation device.executeShellCommand("settings put global window_animation_scale 0.0"); device.executeShellCommand("settings put global transition_animation_scale 0.0"); @@ -364,8 +373,9 @@ public class TestUtils { } public static void tearDownUiTest() throws Exception { - final UiDevice device = UiDevice.getInstance( - androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); + final UiDevice device = + UiDevice.getInstance( + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); device.executeShellCommand("wm dismiss-keyguard"); // Re-enable animation @@ -374,8 +384,8 @@ public class TestUtils { device.executeShellCommand("settings put global animator_duration_scale 1.0"); // restore screen_off_timeout - device.executeShellCommand("settings put system screen_off_timeout " - + sSystemScreenOffTimeout); + device.executeShellCommand( + "settings put system screen_off_timeout " + sSystemScreenOffTimeout); } public static class RetryTestRule implements TestRule { @@ -420,9 +430,7 @@ public class TestUtils { } } - /** - * Helper class used to run synchronously a runnable action on a looper. - */ + /** Helper class used to run synchronously a runnable action on a looper. */ private static final class SyncRunnable implements Runnable { private final Runnable mTarget; private volatile boolean mComplete = false; diff --git a/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java index b4d73bc5c18..ded05bfd841 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java @@ -50,9 +50,7 @@ import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.UUID; -/** - * Test for Utils.java - */ +/** Test for Utils.java */ @SmallTest @RunWith(AndroidJUnit4.class) public class UtilsTest { @@ -72,10 +70,10 @@ public class UtilsTest { @Test public void uuidsToByteArray() { - ParcelUuid[] uuids = new ParcelUuid[] { - new ParcelUuid(new UUID(10, 20)), - new ParcelUuid(new UUID(30, 40)) - }; + ParcelUuid[] uuids = + new ParcelUuid[] { + new ParcelUuid(new UUID(10, 20)), new ParcelUuid(new UUID(30, 40)) + }; ByteBuffer converter = ByteBuffer.allocate(uuids.length * 16); converter.order(ByteOrder.BIG_ENDIAN); converter.putLong(0, 10); @@ -211,8 +209,7 @@ public class UtilsTest { .isEqualTo("STATE_TURNING_ON"); assertThat(Utils.debugGetAdapterStateString(BluetoothAdapter.STATE_TURNING_OFF)) .isEqualTo("STATE_TURNING_OFF"); - assertThat(Utils.debugGetAdapterStateString(-124)) - .isEqualTo("UNKNOWN"); + assertThat(Utils.debugGetAdapterStateString(-124)).isEqualTo("UNKNOWN"); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java index 97cf8e0f865..ebfddc6c49b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java @@ -57,13 +57,14 @@ public class A2dpCodecConfigTest { @Mock private Resources mMockResources; @Mock private A2dpNativeInterface mA2dpNativeInterface; - private static final int[] sOptionalCodecTypes = new int[] { - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS - }; + private static final int[] sOptionalCodecTypes = + new int[] { + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS + }; // Not use the default value to make sure it reads from config private static final int SBC_PRIORITY_DEFAULT = 1001; @@ -75,91 +76,141 @@ public class A2dpCodecConfigTest { private static final int OPUS_PRIORITY_DEFAULT = 13001; private static final int PRIORITY_HIGH = 1000000; - private static final BluetoothCodecConfig[] sCodecCapabilities = new BluetoothCodecConfig[] { - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, - SBC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_MONO - | BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, - AAC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, - APTX_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100 - | BluetoothCodecConfig.SAMPLE_RATE_48000, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, - APTX_HD_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100 - | BluetoothCodecConfig.SAMPLE_RATE_48000, - BluetoothCodecConfig.BITS_PER_SAMPLE_24, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, - LDAC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100 - | BluetoothCodecConfig.SAMPLE_RATE_48000 - | BluetoothCodecConfig.SAMPLE_RATE_88200 - | BluetoothCodecConfig.SAMPLE_RATE_96000, - BluetoothCodecConfig.BITS_PER_SAMPLE_16 - | BluetoothCodecConfig.BITS_PER_SAMPLE_24 - | BluetoothCodecConfig.BITS_PER_SAMPLE_32, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, - OPUS_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_48000, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0) // Codec-specific fields - }; - - private static final BluetoothCodecConfig[] sDefaultCodecConfigs = new BluetoothCodecConfig[] { - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, - SBC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, - AAC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_44100, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, - APTX_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_48000, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, - APTX_HD_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_48000, - BluetoothCodecConfig.BITS_PER_SAMPLE_24, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, - LDAC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_96000, - BluetoothCodecConfig.BITS_PER_SAMPLE_32, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0), // Codec-specific fields - buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, - OPUS_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_48000, - BluetoothCodecConfig.BITS_PER_SAMPLE_16, - BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0) // Codec-specific fields - }; + private static final BluetoothCodecConfig[] sCodecCapabilities = + new BluetoothCodecConfig[] { + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + SBC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_MONO + | BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + AAC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + APTX_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100 + | BluetoothCodecConfig.SAMPLE_RATE_48000, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + APTX_HD_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100 + | BluetoothCodecConfig.SAMPLE_RATE_48000, + BluetoothCodecConfig.BITS_PER_SAMPLE_24, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + LDAC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100 + | BluetoothCodecConfig.SAMPLE_RATE_48000 + | BluetoothCodecConfig.SAMPLE_RATE_88200 + | BluetoothCodecConfig.SAMPLE_RATE_96000, + BluetoothCodecConfig.BITS_PER_SAMPLE_16 + | BluetoothCodecConfig.BITS_PER_SAMPLE_24 + | BluetoothCodecConfig.BITS_PER_SAMPLE_32, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_48000, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0) // Codec-specific fields + }; + + private static final BluetoothCodecConfig[] sDefaultCodecConfigs = + new BluetoothCodecConfig[] { + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + SBC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + AAC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_44100, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + APTX_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_48000, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + APTX_HD_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_48000, + BluetoothCodecConfig.BITS_PER_SAMPLE_24, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + LDAC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_96000, + BluetoothCodecConfig.BITS_PER_SAMPLE_32, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0), // Codec-specific fields + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_48000, + BluetoothCodecConfig.BITS_PER_SAMPLE_16, + BluetoothCodecConfig.CHANNEL_MODE_STEREO, + 0, + 0, + 0, + 0) // Codec-specific fields + }; @Before public void setUp() throws Exception { @@ -182,20 +233,20 @@ public class A2dpCodecConfigTest { mA2dpCodecConfig = new A2dpCodecConfig(mMockContext, mA2dpNativeInterface); mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("00:01:02:03:04:05"); - doReturn(true).when(mA2dpNativeInterface).setCodecConfigPreference( - any(BluetoothDevice.class), - any(BluetoothCodecConfig[].class)); + doReturn(true) + .when(mA2dpNativeInterface) + .setCodecConfigPreference( + any(BluetoothDevice.class), any(BluetoothCodecConfig[].class)); } @After - public void tearDown() throws Exception { - } + public void tearDown() throws Exception {} @Test public void testAssignCodecConfigPriorities() { BluetoothCodecConfig[] codecConfigs = mA2dpCodecConfig.codecConfigPriorities(); for (BluetoothCodecConfig config : codecConfigs) { - switch(config.getCodecType()) { + switch (config.getCodecType()) { case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC: Assert.assertEquals(config.getCodecPriority(), SBC_PRIORITY_DEFAULT); break; @@ -218,122 +269,168 @@ public class A2dpCodecConfigTest { } } - /** - * Test that we can fallback to default codec by lower the codec priority we changed before. - */ + /** Test that we can fallback to default codec by lower the codec priority we changed before. */ @Test public void testSetCodecPreference_priorityHighToDefault() { testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + SBC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, AAC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + AAC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, APTX_PRIORITY_DEFAULT, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + APTX_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, APTX_HD_PRIORITY_DEFAULT, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + APTX_HD_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + LDAC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + PRIORITY_HIGH, false); } /** - * Test that we can change the default codec to another by raising the codec priority. - * LDAC is the default highest codec, so no need to test others. + * Test that we can change the default codec to another by raising the codec priority. LDAC is + * the default highest codec, so no need to test others. */ @Test public void testSetCodecPreference_priorityDefaultToRaiseHigh() { testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + OPUS_PRIORITY_DEFAULT, false); } @Test public void testSetCodecPreference_prioritySbcHighToOthersHigh() { testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, false); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, true); } @Test public void testSetCodecPreference_priorityAacHighToOthersHigh() { testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, false); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, true); testCodecPriorityChangeHelper( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH, - BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS, + PRIORITY_HIGH, + BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, + PRIORITY_HIGH, true); } @@ -608,15 +705,18 @@ public class A2dpCodecConfigTest { @Test public void testDisableOptionalCodecs() { - BluetoothCodecConfig[] codecConfigsArray = - new BluetoothCodecConfig[6]; - codecConfigsArray[0] = buildBluetoothCodecConfig( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, - BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, - BluetoothCodecConfig.SAMPLE_RATE_NONE, - BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, - BluetoothCodecConfig.CHANNEL_MODE_NONE, - 0, 0, 0, 0); // Codec-specific fields + BluetoothCodecConfig[] codecConfigsArray = new BluetoothCodecConfig[6]; + codecConfigsArray[0] = + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, + BluetoothCodecConfig.SAMPLE_RATE_NONE, + BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, + BluetoothCodecConfig.CHANNEL_MODE_NONE, + 0, + 0, + 0, + 0); // Codec-specific fields // shouldn't invoke to native when current codec is SBC mA2dpCodecConfig.disableOptionalCodecs( @@ -624,16 +724,16 @@ public class A2dpCodecConfigTest { getDefaultCodecConfigByType( BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); - verify(mA2dpNativeInterface, times(0)).setCodecConfigPreference(mTestDevice, - codecConfigsArray); + verify(mA2dpNativeInterface, times(0)) + .setCodecConfigPreference(mTestDevice, codecConfigsArray); // should invoke to native when current codec is an optional codec int invokedCounter = 0; for (int codecType : sOptionalCodecTypes) { mA2dpCodecConfig.disableOptionalCodecs( mTestDevice, - getDefaultCodecConfigByType(codecType, - BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); + getDefaultCodecConfigByType( + codecType, BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); verify(mA2dpNativeInterface, times(++invokedCounter)) .setCodecConfigPreference(mTestDevice, codecConfigsArray); } @@ -641,21 +741,25 @@ public class A2dpCodecConfigTest { @Test public void testEnableOptionalCodecs() { - BluetoothCodecConfig[] codecConfigsArray = - new BluetoothCodecConfig[6]; - codecConfigsArray[0] = buildBluetoothCodecConfig( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, - SBC_PRIORITY_DEFAULT, - BluetoothCodecConfig.SAMPLE_RATE_NONE, - BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, - BluetoothCodecConfig.CHANNEL_MODE_NONE, - 0, 0, 0, 0); // Codec-specific fields + BluetoothCodecConfig[] codecConfigsArray = new BluetoothCodecConfig[6]; + codecConfigsArray[0] = + buildBluetoothCodecConfig( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + SBC_PRIORITY_DEFAULT, + BluetoothCodecConfig.SAMPLE_RATE_NONE, + BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, + BluetoothCodecConfig.CHANNEL_MODE_NONE, + 0, + 0, + 0, + 0); // Codec-specific fields // should invoke to native when current codec is SBC mA2dpCodecConfig.enableOptionalCodecs( mTestDevice, - getDefaultCodecConfigByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, - BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); + getDefaultCodecConfigByType( + BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, + BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); verify(mA2dpNativeInterface, times(1)) .setCodecConfigPreference(mTestDevice, codecConfigsArray); @@ -663,8 +767,8 @@ public class A2dpCodecConfigTest { for (int codecType : sOptionalCodecTypes) { mA2dpCodecConfig.enableOptionalCodecs( mTestDevice, - getDefaultCodecConfigByType(codecType, - BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); + getDefaultCodecConfigByType( + codecType, BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)); verify(mA2dpNativeInterface, times(1)) .setCodecConfigPreference(mTestDevice, codecConfigsArray); } @@ -678,14 +782,20 @@ public class A2dpCodecConfigTest { return buildBluetoothCodecConfig( codecConfig.getCodecType(), (codecPriority != BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT - ? codecPriority : codecConfig.getCodecPriority()), - codecConfig.getSampleRate(), codecConfig.getBitsPerSample(), - codecConfig.getChannelMode(), codecConfig.getCodecSpecific1(), - codecConfig.getCodecSpecific2(), codecConfig.getCodecSpecific3(), + ? codecPriority + : codecConfig.getCodecPriority()), + codecConfig.getSampleRate(), + codecConfig.getBitsPerSample(), + codecConfig.getChannelMode(), + codecConfig.getCodecSpecific1(), + codecConfig.getCodecSpecific2(), + codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4()); } - Assert.fail("getDefaultCodecConfigByType: No such codecType=" + codecType - + " in sDefaultCodecConfigs"); + Assert.fail( + "getDefaultCodecConfigByType: No such codecType=" + + codecType + + " in sDefaultCodecConfigs"); return null; } @@ -695,135 +805,177 @@ public class A2dpCodecConfigTest { continue; } return buildBluetoothCodecConfig( - codecCapabilities.getCodecType(), codecCapabilities.getCodecPriority(), - codecCapabilities.getSampleRate(), codecCapabilities.getBitsPerSample(), - codecCapabilities.getChannelMode(), codecCapabilities.getCodecSpecific1(), - codecCapabilities.getCodecSpecific2(), codecCapabilities.getCodecSpecific3(), + codecCapabilities.getCodecType(), + codecCapabilities.getCodecPriority(), + codecCapabilities.getSampleRate(), + codecCapabilities.getBitsPerSample(), + codecCapabilities.getChannelMode(), + codecCapabilities.getCodecSpecific1(), + codecCapabilities.getCodecSpecific2(), + codecCapabilities.getCodecSpecific3(), codecCapabilities.getCodecSpecific4()); } - Assert.fail("getCodecCapabilitiesByType: No such codecType=" + codecType - + " in sCodecCapabilities"); + Assert.fail( + "getCodecCapabilitiesByType: No such codecType=" + + codecType + + " in sCodecCapabilities"); return null; } - private void testCodecParametersChangeHelper(int newCodecType, int oldCodecType, - int sampleRate, int bitsPerSample, int channelMode, boolean invokeNative) { + private void testCodecParametersChangeHelper( + int newCodecType, + int oldCodecType, + int sampleRate, + int bitsPerSample, + int channelMode, + boolean invokeNative) { BluetoothCodecConfig oldCodecConfig = getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH); - BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { - buildBluetoothCodecConfig(newCodecType, - PRIORITY_HIGH, - sampleRate, bitsPerSample, channelMode, - 0, 0, 0, 0) // Codec-specific fields - }; + BluetoothCodecConfig[] newCodecConfigsArray = + new BluetoothCodecConfig[] { + buildBluetoothCodecConfig( + newCodecType, + PRIORITY_HIGH, + sampleRate, + bitsPerSample, + channelMode, + 0, + 0, + 0, + 0) // Codec-specific fields + }; // Test cases: 1. no mandatory; 2. mandatory + old + new; 3. all codecs BluetoothCodecConfig[] minimumCodecsArray; if (!oldCodecConfig.isMandatoryCodec() && !newCodecConfigsArray[0].isMandatoryCodec()) { BluetoothCodecConfig[] optionalCodecsArray; if (oldCodecType != newCodecType) { - optionalCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(oldCodecType), - getCodecCapabilitiesByType(newCodecType) - }; - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), - getCodecCapabilitiesByType(oldCodecType), - getCodecCapabilitiesByType(newCodecType) - }; + optionalCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(oldCodecType), + getCodecCapabilitiesByType(newCodecType) + }; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), + getCodecCapabilitiesByType(oldCodecType), + getCodecCapabilitiesByType(newCodecType) + }; } else { - optionalCodecsArray = new BluetoothCodecConfig[] - {getCodecCapabilitiesByType(oldCodecType)}; - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), - getCodecCapabilitiesByType(oldCodecType) - }; + optionalCodecsArray = + new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), + getCodecCapabilitiesByType(oldCodecType) + }; } - BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, - Arrays.asList(sCodecCapabilities), - Arrays.asList(optionalCodecsArray)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + BluetoothCodecStatus codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, + Arrays.asList(sCodecCapabilities), + Arrays.asList(optionalCodecsArray)); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); // no mandatory codec in selectable, and should not apply - verify(mA2dpNativeInterface, times(0)).setCodecConfigPreference(mTestDevice, - newCodecConfigsArray); - + verify(mA2dpNativeInterface, times(0)) + .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); } else { if (oldCodecType != newCodecType) { - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(oldCodecType), - getCodecCapabilitiesByType(newCodecType) - }; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(oldCodecType), + getCodecCapabilitiesByType(newCodecType) + }; } else { - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(oldCodecType), - }; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(oldCodecType), + }; } } // 2. mandatory + old + new codecs only BluetoothCodecStatus codecStatus = - new BluetoothCodecStatus(oldCodecConfig, + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(minimumCodecsArray)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokeNative ? 1 : 0)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); // 3. all codecs were selectable - codecStatus = new BluetoothCodecStatus(oldCodecConfig, + codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokeNative ? 2 : 0)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); } - private void testCodecSpecificParametersChangeHelper(int newCodecType, int newCodecSpecific, - int oldCodecType, int oldCodecSpecific, boolean invokeNative) { + private void testCodecSpecificParametersChangeHelper( + int newCodecType, + int newCodecSpecific, + int oldCodecType, + int oldCodecSpecific, + boolean invokeNative) { BluetoothCodecConfig codecDefaultTemp = getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH); BluetoothCodecConfig oldCodecConfig = - buildBluetoothCodecConfig(codecDefaultTemp.getCodecType(), - codecDefaultTemp.getCodecPriority(), - codecDefaultTemp.getSampleRate(), - codecDefaultTemp.getBitsPerSample(), - codecDefaultTemp.getChannelMode(), - oldCodecSpecific, 0, 0, 0); // Codec-specific fields + buildBluetoothCodecConfig( + codecDefaultTemp.getCodecType(), + codecDefaultTemp.getCodecPriority(), + codecDefaultTemp.getSampleRate(), + codecDefaultTemp.getBitsPerSample(), + codecDefaultTemp.getChannelMode(), + oldCodecSpecific, + 0, + 0, + 0); // Codec-specific fields codecDefaultTemp = getDefaultCodecConfigByType(newCodecType, PRIORITY_HIGH); - BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { - buildBluetoothCodecConfig(codecDefaultTemp.getCodecType(), - codecDefaultTemp.getCodecPriority(), - codecDefaultTemp.getSampleRate(), - codecDefaultTemp.getBitsPerSample(), - codecDefaultTemp.getChannelMode(), - newCodecSpecific, 0, 0, 0) // Codec-specific fields - }; - BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, + BluetoothCodecConfig[] newCodecConfigsArray = + new BluetoothCodecConfig[] { + buildBluetoothCodecConfig( + codecDefaultTemp.getCodecType(), + codecDefaultTemp.getCodecPriority(), + codecDefaultTemp.getSampleRate(), + codecDefaultTemp.getBitsPerSample(), + codecDefaultTemp.getChannelMode(), + newCodecSpecific, + 0, + 0, + 0) // Codec-specific fields + }; + BluetoothCodecStatus codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokeNative ? 1 : 0)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); } - private void testCodecPriorityChangeHelper(int newCodecType, int newCodecPriority, - int oldCodecType, int oldCodecPriority, boolean shouldApplyWhenAllSelectable) { + private void testCodecPriorityChangeHelper( + int newCodecType, + int newCodecPriority, + int oldCodecType, + int oldCodecPriority, + boolean shouldApplyWhenAllSelectable) { BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { - getDefaultCodecConfigByType(newCodecType, newCodecPriority) + getDefaultCodecConfigByType(newCodecType, newCodecPriority) }; - BluetoothCodecConfig oldCodecConfig = getDefaultCodecConfigByType(oldCodecType, - oldCodecPriority); + BluetoothCodecConfig oldCodecConfig = + getDefaultCodecConfigByType(oldCodecType, oldCodecPriority); // Test cases: 1. no mandatory; 2. no new codec; 3. mandatory + old + new; 4. all codecs BluetoothCodecConfig[] minimumCodecsArray; @@ -832,30 +984,35 @@ public class A2dpCodecConfigTest { if (oldCodecType == newCodecType || newCodecConfigsArray[0].isMandatoryCodec()) { // selectable: {-mandatory, +oldCodec = newCodec}, or // selectable: {-mandatory = newCodec, +oldCodec}. Not applied - BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] - {getCodecCapabilitiesByType(oldCodecType)}; - BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, + BluetoothCodecConfig[] poorCodecsArray = + new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; + BluetoothCodecStatus codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(0)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); // selectable: {+mandatory, +oldCodec = newCodec}, or // selectable: {+mandatory = newCodec, +oldCodec}. - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), - getCodecCapabilitiesByType(oldCodecType) - }; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), + getCodecCapabilitiesByType(oldCodecType) + }; } else { // selectable: {-mandatory, +oldCodec, +newCodec}. Not applied - BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(oldCodecType), - getCodecCapabilitiesByType(newCodecType) - }; - BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, + BluetoothCodecConfig[] poorCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(oldCodecType), + getCodecCapabilitiesByType(newCodecType) + }; + BluetoothCodecStatus codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference( @@ -864,31 +1021,35 @@ public class A2dpCodecConfigTest { .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); // selectable: {+mandatory, +oldCodec, -newCodec}. Not applied - poorCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), - getCodecCapabilitiesByType(oldCodecType) - }; - codecStatus = new BluetoothCodecStatus(oldCodecConfig, + poorCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), + getCodecCapabilitiesByType(oldCodecType) + }; + codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(0)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); // selectable: {+mandatory, +oldCodec, +newCodec}. - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), - getCodecCapabilitiesByType(oldCodecType), - getCodecCapabilitiesByType(newCodecType) - }; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC), + getCodecCapabilitiesByType(oldCodecType), + getCodecCapabilitiesByType(newCodecType) + }; } // oldCodec priority should be reset to default, so compare with the default if (newCodecConfigsArray[0].getCodecPriority() - > getDefaultCodecConfigByType( - oldCodecType, - BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT).getCodecPriority() + > getDefaultCodecConfigByType( + oldCodecType, + BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) + .getCodecPriority() && oldCodecType != newCodecType) { isMinimumCodecsArraySelectable = true; } else { @@ -897,68 +1058,79 @@ public class A2dpCodecConfigTest { } } else if (oldCodecType != newCodecType) { // selectable: {+mandatory = oldCodec, -newCodec}. Not applied - BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] - {getCodecCapabilitiesByType(oldCodecType)}; + BluetoothCodecConfig[] poorCodecsArray = + new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; BluetoothCodecStatus codecStatus = - new BluetoothCodecStatus(oldCodecConfig, - Arrays.asList(sCodecCapabilities), - Arrays.asList(poorCodecsArray)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + new BluetoothCodecStatus( + oldCodecConfig, + Arrays.asList(sCodecCapabilities), + Arrays.asList(poorCodecsArray)); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(0)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); // selectable: {+mandatory = oldCodec, +newCodec}. - minimumCodecsArray = new BluetoothCodecConfig[] { - getCodecCapabilitiesByType(oldCodecType), - getCodecCapabilitiesByType(newCodecType) - }; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(oldCodecType), + getCodecCapabilitiesByType(newCodecType) + }; isMinimumCodecsArraySelectable = true; } else { // selectable: {mandatory = oldCodec = newCodec}. - minimumCodecsArray = new BluetoothCodecConfig[] - {getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)}; + minimumCodecsArray = + new BluetoothCodecConfig[] { + getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) + }; isMinimumCodecsArraySelectable = false; } // 3. mandatory + old + new codecs only int invokedCounter = (isMinimumCodecsArraySelectable ? 1 : 0); BluetoothCodecStatus codecStatus = - new BluetoothCodecStatus(oldCodecConfig, + new BluetoothCodecStatus( + oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(minimumCodecsArray)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokedCounter)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); // 4. all codecs were selectable invokedCounter += (shouldApplyWhenAllSelectable ? 1 : 0); - codecStatus = new BluetoothCodecStatus(oldCodecConfig, - Arrays.asList(sCodecCapabilities), - Arrays.asList(sCodecCapabilities)); - mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, - codecStatus, - newCodecConfigsArray[0]); + codecStatus = + new BluetoothCodecStatus( + oldCodecConfig, + Arrays.asList(sCodecCapabilities), + Arrays.asList(sCodecCapabilities)); + mA2dpCodecConfig.setCodecConfigPreference( + mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokedCounter)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); } - private static BluetoothCodecConfig buildBluetoothCodecConfig(int sourceCodecType, - int codecPriority, int sampleRate, int bitsPerSample, int channelMode, - long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) { + private static BluetoothCodecConfig buildBluetoothCodecConfig( + int sourceCodecType, + int codecPriority, + int sampleRate, + int bitsPerSample, + int channelMode, + long codecSpecific1, + long codecSpecific2, + long codecSpecific3, + long codecSpecific4) { return new BluetoothCodecConfig.Builder() - .setCodecType(sourceCodecType) - .setCodecPriority(codecPriority) - .setSampleRate(sampleRate) - .setBitsPerSample(bitsPerSample) - .setChannelMode(channelMode) - .setCodecSpecific1(codecSpecific1) - .setCodecSpecific2(codecSpecific2) - .setCodecSpecific3(codecSpecific3) - .setCodecSpecific4(codecSpecific4) - .build(); + .setCodecType(sourceCodecType) + .setCodecPriority(codecPriority) + .setSampleRate(sampleRate) + .setBitsPerSample(bitsPerSample) + .setChannelMode(channelMode) + .setCodecSpecific1(codecSpecific1) + .setCodecSpecific2(codecSpecific2) + .setCodecSpecific3(codecSpecific3) + .setCodecSpecific4(codecSpecific4) + .build(); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java index 054de5c9fba..2f1713ef3c2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java @@ -101,7 +101,7 @@ public class A2dpServiceBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] {BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; mBinder.getDevicesMatchingConnectionStates(states, sSource); verify(mA2dpService).getDevicesMatchingConnectionStates(states); diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java index 56283ce1a22..32a30906ffd 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java @@ -60,7 +60,7 @@ public class A2dpStateMachineTest { private HandlerThread mHandlerThread; private A2dpStateMachine mA2dpStateMachine; private BluetoothDevice mTestDevice; - private static final int TIMEOUT_MS = 1000; // 1s + private static final int TIMEOUT_MS = 1000; // 1s private BluetoothCodecConfig mCodecConfigSbc; private BluetoothCodecConfig mCodecConfigAac; @@ -88,48 +88,55 @@ public class A2dpStateMachineTest { mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); // Set up sample codec config - mCodecConfigSbc = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_44100) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .setCodecSpecific1(0) - .setCodecSpecific2(0) - .setCodecSpecific3(0) - .setCodecSpecific4(0) - .build(); - mCodecConfigAac = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .setCodecSpecific1(0) - .setCodecSpecific2(0) - .setCodecSpecific3(0) - .setCodecSpecific4(0) - .build(); - - mCodecConfigOpus = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .setCodecSpecific1(0) - .setCodecSpecific2(0) - .setCodecSpecific3(0) - .setCodecSpecific4(0) - .build(); + mCodecConfigSbc = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) + .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) + .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_44100) + .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) + .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) + .setCodecSpecific1(0) + .setCodecSpecific2(0) + .setCodecSpecific3(0) + .setCodecSpecific4(0) + .build(); + mCodecConfigAac = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) + .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) + .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000) + .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) + .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) + .setCodecSpecific1(0) + .setCodecSpecific2(0) + .setCodecSpecific3(0) + .setCodecSpecific4(0) + .build(); + + mCodecConfigOpus = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) + .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT) + .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000) + .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) + .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) + .setCodecSpecific1(0) + .setCodecSpecific2(0) + .setCodecSpecific3(0) + .setCodecSpecific4(0) + .build(); // Set up thread and looper mHandlerThread = new HandlerThread("A2dpStateMachineTestHandlerThread"); mHandlerThread.start(); - mA2dpStateMachine = new A2dpStateMachine(mTestDevice, mA2dpService, - mA2dpNativeInterface, mHandlerThread.getLooper()); + mA2dpStateMachine = + new A2dpStateMachine( + mTestDevice, + mA2dpService, + mA2dpNativeInterface, + mHandlerThread.getLooper()); // Override the timeout value to speed up the test - A2dpStateMachine.sConnectTimeoutMs = 1000; // 1s + A2dpStateMachine.sConnectTimeoutMs = 1000; // 1s mA2dpStateMachine.start(); } @@ -141,9 +148,7 @@ public class A2dpStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { assertThat(mA2dpStateMachine.getConnectionState()) @@ -156,13 +161,10 @@ public class A2dpStateMachineTest { * @param allow if true, connection is allowed */ private void allowConnection(boolean allow) { - doReturn(allow).when(mA2dpService).okToConnect(any(BluetoothDevice.class), - anyBoolean()); + doReturn(allow).when(mA2dpService).okToConnect(any(BluetoothDevice.class), anyBoolean()); } - /** - * Test that an incoming connection with low priority is rejected - */ + /** Test that an incoming connection with low priority is rejected */ @Test public void testIncomingPriorityReject() { allowConnection(false); @@ -175,16 +177,14 @@ public class A2dpStateMachineTest { mA2dpStateMachine.sendMessage(A2dpStateMachine.STACK_EVENT, connStCh); // Verify that no connection state broadcast is executed - verify(mA2dpService, after(TIMEOUT_MS).never()).sendBroadcast(any(Intent.class), - anyString(), any(Bundle.class)); + verify(mA2dpService, after(TIMEOUT_MS).never()) + .sendBroadcast(any(Intent.class), anyString(), any(Bundle.class)); // Check that we are in Disconnected state assertThat(mA2dpStateMachine.getCurrentState()) .isInstanceOf(A2dpStateMachine.Disconnected.class); } - /** - * Test that an incoming connection with high priority is accepted - */ + /** Test that an incoming connection with high priority is accepted */ @Test public void testIncomingPriorityAccept() { allowConnection(true); @@ -198,8 +198,8 @@ public class A2dpStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(intentArgument1.capture(), - anyString(), any(Bundle.class)); + verify(mA2dpService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); assertThat(intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); @@ -218,8 +218,8 @@ public class A2dpStateMachineTest { // - two calls to broadcastConnectionState(): Disconnected -> Connecting -> Connected // - one call to broadcastAudioState() when entering Connected state ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(TIMEOUT_MS).times(3)).sendBroadcast(intentArgument2.capture(), - anyString(), any(Bundle.class)); + verify(mA2dpService, timeout(TIMEOUT_MS).times(3)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); // Verify that the last broadcast was to change the A2DP playing state // to STATE_NOT_PLAYING assertThat(intentArgument2.getValue().getAction()) @@ -231,9 +231,7 @@ public class A2dpStateMachineTest { .isInstanceOf(A2dpStateMachine.Connected.class); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingTimeout() { allowConnection(true); @@ -245,8 +243,8 @@ public class A2dpStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(intentArgument1.capture(), - anyString(), any(Bundle.class)); + verify(mA2dpService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); assertThat(intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); @@ -256,9 +254,8 @@ public class A2dpStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(A2dpStateMachine.sConnectTimeoutMs * 2).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString(), - any(Bundle.class)); + verify(mA2dpService, timeout(A2dpStateMachine.sConnectTimeoutMs * 2).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); assertThat(intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)) .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); @@ -267,9 +264,7 @@ public class A2dpStateMachineTest { .isInstanceOf(A2dpStateMachine.Disconnected.class); } - /** - * Test that an incoming connection times out - */ + /** Test that an incoming connection times out */ @Test public void testIncomingTimeout() { allowConnection(true); @@ -285,8 +280,8 @@ public class A2dpStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(intentArgument1.capture(), - anyString(), any(Bundle.class)); + verify(mA2dpService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); assertThat(intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); @@ -296,9 +291,8 @@ public class A2dpStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(A2dpStateMachine.sConnectTimeoutMs * 2).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString(), - any(Bundle.class)); + verify(mA2dpService, timeout(A2dpStateMachine.sConnectTimeoutMs * 2).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); assertThat(intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)) .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); @@ -307,33 +301,31 @@ public class A2dpStateMachineTest { .isInstanceOf(A2dpStateMachine.Disconnected.class); } - /** - * Test that codec config change been reported to A2dpService properly. - */ + /** Test that codec config change been reported to A2dpService properly. */ @Test public void testProcessCodecConfigEvent() { testProcessCodecConfigEventCase(false); } /** - * Test that codec config change been reported to A2dpService properly when - * A2DP hardware offloading is enabled. + * Test that codec config change been reported to A2dpService properly when A2DP hardware + * offloading is enabled. */ @Test public void testProcessCodecConfigEvent_OffloadEnabled() { testProcessCodecConfigEventCase(true); } - /** - * Helper methold to test processCodecConfigEvent() - */ + /** Helper methold to test processCodecConfigEvent() */ public void testProcessCodecConfigEventCase(boolean offloadEnabled) { if (offloadEnabled) { mA2dpStateMachine.mA2dpOffloadEnabled = true; } - doNothing().when(mA2dpService).codecConfigUpdated(any(BluetoothDevice.class), - any(BluetoothCodecStatus.class), anyBoolean()); + doNothing() + .when(mA2dpService) + .codecConfigUpdated( + any(BluetoothDevice.class), any(BluetoothCodecStatus.class), anyBoolean()); doNothing().when(mA2dpService).updateOptionalCodecsSupport(any(BluetoothDevice.class)); allowConnection(true); @@ -352,15 +344,26 @@ public class A2dpStateMachineTest { codecsSelectableSbcAacOpus[1] = mCodecConfigAac; codecsSelectableSbcAacOpus[2] = mCodecConfigOpus; - BluetoothCodecStatus codecStatusSbcAndSbc = new BluetoothCodecStatus(mCodecConfigSbc, - Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbc)); - BluetoothCodecStatus codecStatusSbcAndSbcAac = new BluetoothCodecStatus(mCodecConfigSbc, - Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbcAac)); - BluetoothCodecStatus codecStatusAacAndSbcAac = new BluetoothCodecStatus(mCodecConfigAac, - Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbcAac)); - BluetoothCodecStatus codecStatusOpusAndSbcAacOpus = new BluetoothCodecStatus( - mCodecConfigOpus, Arrays.asList(codecsSelectableSbcAacOpus), - Arrays.asList(codecsSelectableSbcAacOpus)); + BluetoothCodecStatus codecStatusSbcAndSbc = + new BluetoothCodecStatus( + mCodecConfigSbc, + Arrays.asList(codecsSelectableSbcAac), + Arrays.asList(codecsSelectableSbc)); + BluetoothCodecStatus codecStatusSbcAndSbcAac = + new BluetoothCodecStatus( + mCodecConfigSbc, + Arrays.asList(codecsSelectableSbcAac), + Arrays.asList(codecsSelectableSbcAac)); + BluetoothCodecStatus codecStatusAacAndSbcAac = + new BluetoothCodecStatus( + mCodecConfigAac, + Arrays.asList(codecsSelectableSbcAac), + Arrays.asList(codecsSelectableSbcAac)); + BluetoothCodecStatus codecStatusOpusAndSbcAacOpus = + new BluetoothCodecStatus( + mCodecConfigOpus, + Arrays.asList(codecsSelectableSbcAacOpus), + Arrays.asList(codecsSelectableSbcAacOpus)); // Set default codec status when device disconnected // Selected codec = SBC, selectable codec = SBC @@ -379,8 +382,8 @@ public class A2dpStateMachineTest { // - two calls to broadcastConnectionState(): Disconnected -> Conecting -> Connected // - one call to broadcastAudioState() when entering Connected state ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mA2dpService, timeout(TIMEOUT_MS).times(2)).sendBroadcast(intentArgument2.capture(), - anyString(), any(Bundle.class)); + verify(mA2dpService, timeout(TIMEOUT_MS).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); // Verify that state machine update optional codec when enter connected state verify(mA2dpService, times(1)).updateOptionalCodecsSupport(mTestDevice); @@ -406,7 +409,8 @@ public class A2dpStateMachineTest { // Selected codec = OPUS, selectable codec = SBC+AAC+OPUS mA2dpStateMachine.processCodecConfigEvent(codecStatusOpusAndSbcAacOpus); if (!offloadEnabled) { - verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusOpusAndSbcAacOpus, true); + verify(mA2dpService) + .codecConfigUpdated(mTestDevice, codecStatusOpusAndSbcAacOpus, true); } verify(mA2dpService, times(3)).updateOptionalCodecsSupport(mTestDevice); // Check if low latency audio been updated. @@ -433,8 +437,11 @@ public class A2dpStateMachineTest { codecsSelectableSbcAac[0] = mCodecConfigSbc; codecsSelectableSbcAac[1] = mCodecConfigAac; - BluetoothCodecStatus codecStatusSbcAndSbc = new BluetoothCodecStatus(mCodecConfigSbc, - Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbc)); + BluetoothCodecStatus codecStatusSbcAndSbc = + new BluetoothCodecStatus( + mCodecConfigSbc, + Arrays.asList(codecsSelectableSbcAac), + Arrays.asList(codecsSelectableSbc)); mA2dpStateMachine.processCodecConfigEvent(codecStatusSbcAndSbc); mA2dpStateMachine.dump(new StringBuilder()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java index 5ed765dbc0e..2d4462d3404 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java @@ -79,7 +79,7 @@ public class A2dpSinkServiceBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] {BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.getDevicesMatchingConnectionStates(states, source); diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java index d19e6aa5a98..2503b164d9c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java @@ -90,9 +90,8 @@ public class A2dpSinkServiceTest { mDevice4 = mAdapter.getRemoteDevice("44:44:44:44:44:44"); mDevice5 = mAdapter.getRemoteDevice("55:55:55:55:55:55"); mDevice6 = mAdapter.getRemoteDevice("66:66:66:66:66:66"); - BluetoothDevice[] bondedDevices = new BluetoothDevice[]{ - mDevice1, mDevice2, mDevice3, mDevice4, mDevice5, mDevice6 - }; + BluetoothDevice[] bondedDevices = + new BluetoothDevice[] {mDevice1, mDevice2, mDevice3, mDevice4, mDevice5, mDevice6}; doReturn(true).when(mDatabaseManager).setProfileConnectionPolicy(any(), anyInt(), anyInt()); @@ -124,8 +123,8 @@ public class A2dpSinkServiceTest { private void setupDeviceConnection(BluetoothDevice device) { assertThat(mLooper.nextMessage()).isNull(); - assertThat(mService.getConnectionState(device)).isEqualTo( - BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(device)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); assertThat(mLooper.nextMessage()).isNull(); assertThat(mService.connect(device)).isTrue(); @@ -134,8 +133,7 @@ public class A2dpSinkServiceTest { StackEvent.connectionStateChanged(device, StackEvent.CONNECTION_STATE_CONNECTED); mService.messageFromNative(nativeEvent); syncHandler(A2dpSinkStateMachine.STACK_EVENT); - assertThat(mService.getConnectionState(device)).isEqualTo( - BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getConnectionState(device)).isEqualTo(BluetoothProfile.STATE_CONNECTED); } /** @@ -149,54 +147,42 @@ public class A2dpSinkServiceTest { .thenReturn(priority); } - /** - * Test that initialization of the service completes and that we can get a instance - */ + /** Test that initialization of the service completes and that we can get a instance */ @Test public void testInitialize() { assertThat(A2dpSinkService.getA2dpSinkService()).isEqualTo(mService); } - /** - * Test that asking to connect with a null device fails - */ + /** Test that asking to connect with a null device fails */ @Test public void testConnectNullDevice() { assertThrows(IllegalArgumentException.class, () -> mService.connect(null)); } - /** - * Test that a CONNECTION_POLICY_ALLOWED device can connected - */ + /** Test that a CONNECTION_POLICY_ALLOWED device can connected */ @Test public void testConnectPolicyAllowedDevice() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); setupDeviceConnection(mDevice1); } - /** - * Test that a CONNECTION_POLICY_FORBIDDEN device is not allowed to connect - */ + /** Test that a CONNECTION_POLICY_FORBIDDEN device is not allowed to connect */ @Test public void testConnectPolicyForbiddenDevice() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); assertThat(mService.connect(mDevice1)).isFalse(); - assertThat(mService.getConnectionState(mDevice1)).isEqualTo( - BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(mDevice1)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); } - /** - * Test that a CONNECTION_POLICY_UNKNOWN device is allowed to connect - */ + /** Test that a CONNECTION_POLICY_UNKNOWN device is allowed to connect */ @Test public void testConnectPolicyUnknownDevice() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); setupDeviceConnection(mDevice1); } - /** - * Test that we can connect multiple devices - */ + /** Test that we can connect multiple devices */ @Test public void testConnectMultipleDevices() { doReturn(5).when(mAdapterService).getMaxConnectedAudioDevices(); @@ -215,9 +201,7 @@ public class A2dpSinkServiceTest { setupDeviceConnection(mDevice5); } - /** - * Test to make sure we can disconnect a connected device - */ + /** Test to make sure we can disconnect a connected device */ @Test public void testDisconnect() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); @@ -225,31 +209,25 @@ public class A2dpSinkServiceTest { assertThat(mService.disconnect(mDevice1)).isTrue(); syncHandler(A2dpSinkStateMachine.DISCONNECT); - assertThat(mService.getConnectionState(mDevice1)).isEqualTo( - BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(mDevice1)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); syncHandler(A2dpSinkStateMachine.CLEANUP, -1 /* SM_QUIT_CMD */); } - /** - * Assure disconnect() fails with a device that's not connected - */ + /** Assure disconnect() fails with a device that's not connected */ @Test public void testDisconnectDeviceDoesNotExist() { assertThat(mService.disconnect(mDevice1)).isFalse(); } - /** - * Assure disconnect() fails with an invalid device - */ + /** Assure disconnect() fails with an invalid device */ @Test public void testDisconnectNullDevice() { assertThrows(IllegalArgumentException.class, () -> mService.disconnect(null)); } - /** - * Assure dump() returns something and does not crash - */ + /** Assure dump() returns something and does not crash */ @Test public void testDump() { StringBuilder sb = new StringBuilder(); @@ -269,18 +247,14 @@ public class A2dpSinkServiceTest { assertThat(mService.getActiveDevice()).isEqualTo(mDevice1); } - /** - * Test that calls to set a null active device succeed in unsetting the active device - */ + /** Test that calls to set a null active device succeed in unsetting the active device */ @Test public void testSetActiveDeviceNullDevice() { assertThat(mService.setActiveDevice(null)).isTrue(); assertThat(mService.getActiveDevice()).isNull(); } - /** - * Make sure we can receive the set audio configuration - */ + /** Make sure we can receive the set audio configuration */ @Test public void testGetAudioConfiguration() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); @@ -291,8 +265,9 @@ public class A2dpSinkServiceTest { mService.messageFromNative(audioConfigChanged); syncHandler(A2dpSinkStateMachine.STACK_EVENT); - BluetoothAudioConfig expected = new BluetoothAudioConfig(TEST_SAMPLE_RATE, - TEST_CHANNEL_COUNT, AudioFormat.ENCODING_PCM_16BIT); + BluetoothAudioConfig expected = + new BluetoothAudioConfig( + TEST_SAMPLE_RATE, TEST_CHANNEL_COUNT, AudioFormat.ENCODING_PCM_16BIT); BluetoothAudioConfig config = mService.getAudioConfig(mDevice1); assertThat(config).isEqualTo(expected); } @@ -317,9 +292,7 @@ public class A2dpSinkServiceTest { assertThat(mService.getAudioConfig(mDevice1)).isNull(); } - /** - * Getting an audio config for a device that hasn't received one yet should return null - */ + /** Getting an audio config for a device that hasn't received one yet should return null */ @Test public void testGetAudioConfigWithConfigUnset() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); @@ -327,18 +300,13 @@ public class A2dpSinkServiceTest { assertThat(mService.getAudioConfig(mDevice1)).isNull(); } - /** - * Getting an audio config for a null device should return null - */ + /** Getting an audio config for a null device should return null */ @Test public void testGetAudioConfigNullDevice() { assertThat(mService.getAudioConfig(null)).isNull(); } - /** - * Test that a newly connected device ends up in the set returned by - * getConnectedDevices - */ + /** Test that a newly connected device ends up in the set returned by getConnectedDevices */ @Test public void testGetConnectedDevices() { ArrayList expected = new ArrayList(); @@ -362,8 +330,9 @@ public class A2dpSinkServiceTest { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); setupDeviceConnection(mDevice1); - List devices = mService.getDevicesMatchingConnectionStates( - new int[] {BluetoothProfile.STATE_CONNECTED}); + List devices = + mService.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED}); assertThat(devices).isEqualTo(expected); } @@ -381,48 +350,43 @@ public class A2dpSinkServiceTest { expected.add(mDevice5); expected.add(mDevice6); - List devices = mService.getDevicesMatchingConnectionStates( - new int[] {BluetoothProfile.STATE_DISCONNECTED}); + List devices = + mService.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_DISCONNECTED}); assertThat(devices).isEqualTo(expected); } - /** - * Test that GetConnectionPolicy() can get a device with policy "Allowed" - */ + /** Test that GetConnectionPolicy() can get a device with policy "Allowed" */ @Test public void testGetConnectionPolicyDeviceAllowed() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); - assertThat(mService.getConnectionPolicy(mDevice1)).isEqualTo( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + assertThat(mService.getConnectionPolicy(mDevice1)) + .isEqualTo(BluetoothProfile.CONNECTION_POLICY_ALLOWED); } - /** - * Test that GetConnectionPolicy() can get a device with policy "Forbidden" - */ + /** Test that GetConnectionPolicy() can get a device with policy "Forbidden" */ @Test public void testGetConnectionPolicyDeviceForbidden() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - assertThat(mService.getConnectionPolicy(mDevice1)).isEqualTo( - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + assertThat(mService.getConnectionPolicy(mDevice1)) + .isEqualTo(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } - /** - * Test that GetConnectionPolicy() can get a device with policy "Unknown" - */ + /** Test that GetConnectionPolicy() can get a device with policy "Unknown" */ @Test public void testGetConnectionPolicyDeviceUnknown() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - assertThat(mService.getConnectionPolicy(mDevice1)).isEqualTo( - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + assertThat(mService.getConnectionPolicy(mDevice1)) + .isEqualTo(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } - /** - * Test that SetConnectionPolicy() can change a device's policy to "Allowed" - */ + /** Test that SetConnectionPolicy() can change a device's policy to "Allowed" */ @Test public void testSetConnectionPolicyDeviceAllowed() { - assertThat(mService.setConnectionPolicy(mDevice1, - BluetoothProfile.CONNECTION_POLICY_ALLOWED)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED)) + .isTrue(); verify(mDatabaseManager) .setProfileConnectionPolicy( mDevice1, @@ -430,13 +394,13 @@ public class A2dpSinkServiceTest { BluetoothProfile.CONNECTION_POLICY_ALLOWED); } - /** - * Test that SetConnectionPolicy() can change a device's policy to "Forbidden" - */ + /** Test that SetConnectionPolicy() can change a device's policy to "Forbidden" */ @Test public void testSetConnectionPolicyDeviceForbiddenWhileNotConnected() { - assertThat(mService.setConnectionPolicy(mDevice1, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mDevice1, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)) + .isTrue(); verify(mDatabaseManager) .setProfileConnectionPolicy( mDevice1, @@ -445,16 +409,18 @@ public class A2dpSinkServiceTest { } /** - * Test that SetConnectionPolicy() can change a connected device's policy to "Forbidden" - * and that the new "Forbidden" policy causes a disconnect of the device. + * Test that SetConnectionPolicy() can change a connected device's policy to "Forbidden" and + * that the new "Forbidden" policy causes a disconnect of the device. */ @Test public void testSetConnectionPolicyDeviceForbiddenWhileConnected() { mockDevicePriority(mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED); setupDeviceConnection(mDevice1); - assertThat(mService.setConnectionPolicy(mDevice1, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mDevice1, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)) + .isTrue(); verify(mDatabaseManager) .setProfileConnectionPolicy( mDevice1, @@ -463,19 +429,19 @@ public class A2dpSinkServiceTest { syncHandler(A2dpSinkStateMachine.DISCONNECT); verify(mNativeInterface).disconnectA2dpSink(eq(mDevice1)); - assertThat(mService.getConnectionState(mDevice1)).isEqualTo( - BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(mDevice1)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); syncHandler(A2dpSinkStateMachine.CLEANUP, -1 /* SM_QUIT_CMD */); } - /** - * Test that SetConnectionPolicy() can change a device's policy to "Unknown" - */ + /** Test that SetConnectionPolicy() can change a device's policy to "Unknown" */ @Test public void testSetConnectionPolicyDeviceUnknown() { - assertThat(mService.setConnectionPolicy(mDevice1, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mDevice1, BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) + .isTrue(); verify(mDatabaseManager) .setProfileConnectionPolicy( mDevice1, @@ -483,15 +449,15 @@ public class A2dpSinkServiceTest { BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } - /** - * Test that SetConnectionPolicy is robust to DatabaseManager failures - */ + /** Test that SetConnectionPolicy is robust to DatabaseManager failures */ @Test public void testSetConnectionPolicyDatabaseWriteFails() { - when(mDatabaseManager.setProfileConnectionPolicy(any(), anyInt(), - anyInt())).thenReturn(false); - assertThat(mService.setConnectionPolicy(mDevice1, - BluetoothProfile.CONNECTION_POLICY_ALLOWED)).isFalse(); + when(mDatabaseManager.setProfileConnectionPolicy(any(), anyInt(), anyInt())) + .thenReturn(false); + assertThat( + mService.setConnectionPolicy( + mDevice1, BluetoothProfile.CONNECTION_POLICY_ALLOWED)) + .isFalse(); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java index aac7f7f6753..6e65d7ee546 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java @@ -101,13 +101,15 @@ public class A2dpSinkStateMachineTest { } private void sendConnectionEvent(int state) { - mStateMachine.sendMessage(A2dpSinkStateMachine.STACK_EVENT, + mStateMachine.sendMessage( + A2dpSinkStateMachine.STACK_EVENT, StackEvent.connectionStateChanged(mDevice, state)); syncHandler(A2dpSinkStateMachine.STACK_EVENT); } private void sendAudioConfigChangedEvent(int sampleRate, int channelCount) { - mStateMachine.sendMessage(A2dpSinkStateMachine.STACK_EVENT, + mStateMachine.sendMessage( + A2dpSinkStateMachine.STACK_EVENT, StackEvent.audioConfigChanged(mDevice, sampleRate, channelCount)); syncHandler(A2dpSinkStateMachine.STACK_EVENT); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java index fe49e05bf6e..c74fd3ef35f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java @@ -73,8 +73,7 @@ public class A2dpSinkStreamHandlerTest { @Rule public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule(); - @Mock - private AdapterService mAdapterService; + @Mock private AdapterService mAdapterService; @Before public void setUp() throws Exception { @@ -99,10 +98,10 @@ public class A2dpSinkStreamHandlerTest { .thenReturn(Context.AUDIO_SERVICE); when(mMockA2dpSink.getResources()).thenReturn(mMockResources); when(mMockResources.getInteger(anyInt())).thenReturn(DUCK_PERCENT); - when(mMockAudioManager.requestAudioFocus(any())).thenReturn( - AudioManager.AUDIOFOCUS_REQUEST_GRANTED); - when(mMockAudioManager.abandonAudioFocus(any())).thenReturn( - AudioManager.AUDIOFOCUS_REQUEST_GRANTED); + when(mMockAudioManager.requestAudioFocus(any())) + .thenReturn(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); + when(mMockAudioManager.abandonAudioFocus(any())) + .thenReturn(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); when(mMockAudioManager.generateAudioSessionId()).thenReturn(0); when(mMockA2dpSink.getMainLooper()).thenReturn(mHandlerThread.getLooper()); when(mMockA2dpSink.getPackageManager()).thenReturn(mMockPackageManager); @@ -210,8 +209,8 @@ public class A2dpSinkStreamHandlerTest { // Focus was gained, expect streaming to resume. testSnkPlay(); mStreamHandler.handleMessage( - mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, - AudioManager.AUDIOFOCUS_GAIN)); + mStreamHandler.obtainMessage( + A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, AudioManager.AUDIOFOCUS_GAIN)); verify(mMockAudioManager, times(1)).requestAudioFocus(any()); verify(mMockNativeInterface, times(1)).informAudioFocusState(1); verify(mMockNativeInterface, times(1)).informAudioTrackGain(1.0f); @@ -226,13 +225,14 @@ public class A2dpSinkStreamHandlerTest { // TransientMayDuck focus was gained, expect audio stream to duck. testSnkPlay(); mStreamHandler.handleMessage( - mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, + mStreamHandler.obtainMessage( + A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); verify(mMockNativeInterface, times(1)).informAudioTrackGain(DUCK_PERCENT / 100.0f); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mStreamHandler.getFocusState()).isEqualTo( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); + assertThat(mStreamHandler.getFocusState()) + .isEqualTo(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); assertThat(BluetoothMediaBrowserService.isActive()).isFalse(); } @@ -241,15 +241,16 @@ public class A2dpSinkStreamHandlerTest { // Focus was lost transiently, expect streaming to stop. testSnkPlay(); mStreamHandler.handleMessage( - mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, + mStreamHandler.obtainMessage( + A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)); verify(mMockAudioManager, times(0)).abandonAudioFocus(any()); verify(mMockNativeInterface, times(0)).informAudioFocusState(0); verify(mMockNativeInterface, times(1)).informAudioTrackGain(0); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mStreamHandler.getFocusState()).isEqualTo( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT); + assertThat(mStreamHandler.getFocusState()) + .isEqualTo(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT); assertThat(BluetoothMediaBrowserService.isActive()).isFalse(); } @@ -258,7 +259,8 @@ public class A2dpSinkStreamHandlerTest { // Focus was lost transiently, expect streaming to stop. testSnkPlay(); mStreamHandler.handleMessage( - mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, + mStreamHandler.obtainMessage( + A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)); verify(mMockAudioManager, times(0)).abandonAudioFocus(any()); verify(mMockNativeInterface, times(0)).informAudioFocusState(0); @@ -276,8 +278,8 @@ public class A2dpSinkStreamHandlerTest { testFocusLostTransient(); mStreamHandler.handleMessage( - mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, - AudioManager.AUDIOFOCUS_GAIN)); + mStreamHandler.obtainMessage( + A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, AudioManager.AUDIOFOCUS_GAIN)); verify(mMockAudioManager, times(0)).abandonAudioFocus(any()); verify(mMockNativeInterface, times(1)).informAudioTrackGain(1.0f); @@ -291,8 +293,8 @@ public class A2dpSinkStreamHandlerTest { // Focus was lost permanently, expect streaming to stop. testSnkPlay(); mStreamHandler.handleMessage( - mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, - AudioManager.AUDIOFOCUS_LOSS)); + mStreamHandler.obtainMessage( + A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, AudioManager.AUDIOFOCUS_LOSS)); verify(mMockAudioManager, times(1)).abandonAudioFocus(any()); verify(mMockNativeInterface, times(1)).informAudioFocusState(0); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java index c2426563b57..2ab0f73311a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java @@ -57,26 +57,36 @@ public final class BrowsablePlayerConnectorTest { @Mock MediaBrowser mMediaBrowser; MediaBrowser.ConnectionCallback mConnectionCallback; + @Before public void setUp() { mContext = InstrumentationRegistry.getTargetContext(); mTestLooper = new TestLooper(); - doAnswer(invocation -> { - mConnectionCallback = invocation.getArgument(2); - return null; - }).when(mMediaBrowser).testInit(any(), any(), any(), any()); - doAnswer(invocation -> { - mConnectionCallback.onConnected(); - return null; - }).when(mMediaBrowser).connect(); - doAnswer(invocation -> { - String id = invocation.getArgument(0); - android.media.browse.MediaBrowser.SubscriptionCallback callback - = invocation.getArgument(1); - callback.onChildrenLoaded(id, Collections.emptyList()); - return null; - }).when(mMediaBrowser).subscribe(any(), any()); + doAnswer( + invocation -> { + mConnectionCallback = invocation.getArgument(2); + return null; + }) + .when(mMediaBrowser) + .testInit(any(), any(), any(), any()); + doAnswer( + invocation -> { + mConnectionCallback.onConnected(); + return null; + }) + .when(mMediaBrowser) + .connect(); + doAnswer( + invocation -> { + String id = invocation.getArgument(0); + android.media.browse.MediaBrowser.SubscriptionCallback callback = + invocation.getArgument(1); + callback.onChildrenLoaded(id, Collections.emptyList()); + return null; + }) + .when(mMediaBrowser) + .subscribe(any(), any()); doReturn("testRoot").when(mMediaBrowser).getRoot(); MediaBrowserFactory.inject(mMediaBrowser); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java index dcf1b069d96..ae23dca6bb2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java @@ -80,15 +80,15 @@ public class BrowserPlayerWrapperTest { private MockContentResolver mTestContentResolver; private static final String TEST_AUTHORITY = "com.android.bluetooth.avrcp.test"; - private static final Uri TEST_CONTENT_URI = new Uri.Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(TEST_AUTHORITY) - .build(); + private static final Uri TEST_CONTENT_URI = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(TEST_AUTHORITY) + .build(); private static final String IMAGE_HANDLE_1 = "0000001"; - private static final Uri IMAGE_URI_1 = TEST_CONTENT_URI.buildUpon() - .appendQueryParameter("handle", IMAGE_HANDLE_1) - .build(); + private static final Uri IMAGE_URI_1 = + TEST_CONTENT_URI.buildUpon().appendQueryParameter("handle", IMAGE_HANDLE_1).build(); private static final String IMAGE_STRING_1 = IMAGE_URI_1.toString(); private Bitmap mTestBitmap = null; @@ -102,17 +102,20 @@ public class BrowserPlayerWrapperTest { mTestBitmap = loadImage(com.android.bluetooth.tests.R.raw.image_200_200); mTestContentResolver = new MockContentResolver(mTargetContext); - mTestContentResolver.addProvider(TEST_AUTHORITY, new MockContentProvider() { - @Override - public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) { - String handle = url.getQueryParameter("handle"); - if (IMAGE_URI_1.equals(url)) { - return mTestResources.openRawResourceFd( - com.android.bluetooth.tests.R.raw.image_200_200); - } - return null; - } - }); + mTestContentResolver.addProvider( + TEST_AUTHORITY, + new MockContentProvider() { + @Override + public AssetFileDescriptor openTypedAssetFile( + Uri url, String mimeType, Bundle opts) { + String handle = url.getQueryParameter("handle"); + if (IMAGE_URI_1.equals(url)) { + return mTestResources.openRawResourceFd( + com.android.bluetooth.tests.R.raw.image_200_200); + } + return null; + } + }); when(mMockContext.getContentResolver()).thenReturn(mTestContentResolver); when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(true); @@ -144,13 +147,20 @@ public class BrowserPlayerWrapperTest { return BitmapFactory.decodeStream(imageInputStream); } - private MediaDescription getMediaDescription(String id, String title, String artist, - String album, Bitmap bitmap, Uri uri, Bundle extras) { - MediaDescription.Builder builder = new MediaDescription.Builder() - .setMediaId(id) - .setTitle(title) - .setSubtitle(artist) - .setDescription(album); + private MediaDescription getMediaDescription( + String id, + String title, + String artist, + String album, + Bitmap bitmap, + Uri uri, + Bundle extras) { + MediaDescription.Builder builder = + new MediaDescription.Builder() + .setMediaId(id) + .setTitle(title) + .setSubtitle(artist) + .setDescription(album); if (bitmap != null) { builder.setIconBitmap(bitmap); } @@ -372,8 +382,11 @@ public class BrowserPlayerWrapperTest { subscriptionCb.onChildrenLoaded("test_folder", items); verify(mMockBrowser).unsubscribe(eq("test_folder")); - verify(mBrowseCb).run(eq(BrowsedPlayerWrapper.STATUS_SUCCESS), eq("test_folder"), - mWrapperBrowseCb.capture()); + verify(mBrowseCb) + .run( + eq(BrowsedPlayerWrapper.STATUS_SUCCESS), + eq("test_folder"), + mWrapperBrowseCb.capture()); // Verify returned ListItems List item_list = mWrapperBrowseCb.getValue(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java index 7f03b378ec3..f14df9e2ce6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java @@ -62,23 +62,24 @@ public class GPMWrapperTest { @Test public void isMetadataSynced_whenOutOfSync_returnsFalse() { long activeQueueItemId = 3; - PlaybackState state = new PlaybackState.Builder() - .setActiveQueueItemId(activeQueueItemId).build(); + PlaybackState state = + new PlaybackState.Builder().setActiveQueueItemId(activeQueueItemId).build(); when(mMediaController.getPlaybackState()).thenReturn(state); List queue = new ArrayList<>(); - MediaDescription description = new MediaDescription.Builder() - .setTitle("Title from queue item") - .build(); - MediaSession.QueueItem queueItem = new MediaSession.QueueItem( - description, activeQueueItemId); + MediaDescription description = + new MediaDescription.Builder().setTitle("Title from queue item").build(); + MediaSession.QueueItem queueItem = + new MediaSession.QueueItem(description, activeQueueItemId); queue.add(queueItem); when(mMediaController.getQueue()).thenReturn(queue); - MediaMetadata metadata = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_TITLE, - "Different Title from MediaMetadata") - .build(); + MediaMetadata metadata = + new MediaMetadata.Builder() + .putString( + MediaMetadata.METADATA_KEY_TITLE, + "Different Title from MediaMetadata") + .build(); when(mMediaController.getMetadata()).thenReturn(metadata); GPMWrapper wrapper = new GPMWrapper(mContext, mMediaController, null); @@ -91,22 +92,21 @@ public class GPMWrapperTest { String title = "test_title"; long activeQueueItemId = 3; - PlaybackState state = new PlaybackState.Builder() - .setActiveQueueItemId(activeQueueItemId).build(); + PlaybackState state = + new PlaybackState.Builder().setActiveQueueItemId(activeQueueItemId).build(); when(mMediaController.getPlaybackState()).thenReturn(state); List queue = new ArrayList<>(); - MediaDescription description = new MediaDescription.Builder() - .setTitle(title) - .build(); - MediaSession.QueueItem queueItem = new MediaSession.QueueItem( - description, activeQueueItemId); + MediaDescription description = new MediaDescription.Builder().setTitle(title).build(); + MediaSession.QueueItem queueItem = + new MediaSession.QueueItem(description, activeQueueItemId); queue.add(queueItem); when(mMediaController.getQueue()).thenReturn(queue); - MediaMetadata metadata = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_TITLE, title) - .build(); + MediaMetadata metadata = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, title) + .build(); when(mMediaController.getMetadata()).thenReturn(metadata); GPMWrapper wrapper = new GPMWrapper(mContext, mMediaController, null); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java index 4d7d339d86d..e485d08a16f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java @@ -62,21 +62,23 @@ public class ImageTest { private MockContentResolver mTestContentResolver; private static final String TEST_AUTHORITY = "com.android.bluetooth.avrcp.test"; - private static final Uri TEST_CONTENT_URI = new Uri.Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(TEST_AUTHORITY) - .build(); + private static final Uri TEST_CONTENT_URI = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(TEST_AUTHORITY) + .build(); private static final String IMAGE_HANDLE_1 = "0000001"; - private static final Uri IMAGE_URI_1 = TEST_CONTENT_URI.buildUpon() - .appendQueryParameter("handle", IMAGE_HANDLE_1) - .build(); + private static final Uri IMAGE_URI_1 = + TEST_CONTENT_URI.buildUpon().appendQueryParameter("handle", IMAGE_HANDLE_1).build(); private static final String IMAGE_STRING_1 = IMAGE_URI_1.toString(); private static final String IMAGE_HANDLE_SECURITY_ERROR = "sec_error"; - private static final Uri IMAGE_URI_SECURITY_ERROR = TEST_CONTENT_URI.buildUpon() - .appendQueryParameter("handle", IMAGE_HANDLE_SECURITY_ERROR) - .build(); + private static final Uri IMAGE_URI_SECURITY_ERROR = + TEST_CONTENT_URI + .buildUpon() + .appendQueryParameter("handle", IMAGE_HANDLE_SECURITY_ERROR) + .build(); private Bitmap mTestBitmap = null; @@ -89,19 +91,22 @@ public class ImageTest { mTestBitmap = loadImage(com.android.bluetooth.tests.R.raw.image_200_200); mTestContentResolver = new MockContentResolver(mTargetContext); - mTestContentResolver.addProvider(TEST_AUTHORITY, new MockContentProvider() { - @Override - public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) { - String handle = url.getQueryParameter("handle"); - if (IMAGE_URI_1.equals(url)) { - return mTestResources.openRawResourceFd( - com.android.bluetooth.tests.R.raw.image_200_200); - } else if (IMAGE_URI_SECURITY_ERROR.equals(url)) { - throw new SecurityException(); - } - return null; - } - }); + mTestContentResolver.addProvider( + TEST_AUTHORITY, + new MockContentProvider() { + @Override + public AssetFileDescriptor openTypedAssetFile( + Uri url, String mimeType, Bundle opts) { + String handle = url.getQueryParameter("handle"); + if (IMAGE_URI_1.equals(url)) { + return mTestResources.openRawResourceFd( + com.android.bluetooth.tests.R.raw.image_200_200); + } else if (IMAGE_URI_SECURITY_ERROR.equals(url)) { + throw new SecurityException(); + } + return null; + } + }); when(mMockContext.getContentResolver()).thenReturn(mTestContentResolver); when(mMockContext.getResources()).thenReturn(mMockResources); @@ -123,54 +128,60 @@ public class ImageTest { } private MediaMetadata getMediaMetadataWithoutArt() { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_TITLE, "BT Test Song") - .putString(MediaMetadata.METADATA_KEY_ARTIST, "BT Test Artist") - .putString(MediaMetadata.METADATA_KEY_ALBUM, "BT Test Album") - .putLong(MediaMetadata.METADATA_KEY_DURATION, 5000L); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, "BT Test Song") + .putString(MediaMetadata.METADATA_KEY_ARTIST, "BT Test Artist") + .putString(MediaMetadata.METADATA_KEY_ALBUM, "BT Test Album") + .putLong(MediaMetadata.METADATA_KEY_DURATION, 5000L); return builder.build(); } private MediaMetadata getMediaMetadataWithBitmap(String field, Bitmap image) { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_TITLE, "BT Test Song") - .putString(MediaMetadata.METADATA_KEY_ARTIST, "BT Test Artist") - .putString(MediaMetadata.METADATA_KEY_ALBUM, "BT Test Album") - .putLong(MediaMetadata.METADATA_KEY_DURATION, 5000L) - .putBitmap(field, image); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, "BT Test Song") + .putString(MediaMetadata.METADATA_KEY_ARTIST, "BT Test Artist") + .putString(MediaMetadata.METADATA_KEY_ALBUM, "BT Test Album") + .putLong(MediaMetadata.METADATA_KEY_DURATION, 5000L) + .putBitmap(field, image); return builder.build(); } private MediaMetadata getMediaMetadataWithUri(String field, String uri) { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_TITLE, "BT Test Song") - .putString(MediaMetadata.METADATA_KEY_ARTIST, "BT Test Artist") - .putString(MediaMetadata.METADATA_KEY_ALBUM, "BT Test Album") - .putLong(MediaMetadata.METADATA_KEY_DURATION, 5000L) - .putString(field, uri); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, "BT Test Song") + .putString(MediaMetadata.METADATA_KEY_ARTIST, "BT Test Artist") + .putString(MediaMetadata.METADATA_KEY_ALBUM, "BT Test Album") + .putLong(MediaMetadata.METADATA_KEY_DURATION, 5000L) + .putString(field, uri); return builder.build(); } private MediaDescription getMediaDescriptionWithoutArt() { - MediaDescription.Builder builder = new MediaDescription.Builder() - .setTitle("BT Test Song") - .setDescription("BT Test Description"); + MediaDescription.Builder builder = + new MediaDescription.Builder() + .setTitle("BT Test Song") + .setDescription("BT Test Description"); return builder.build(); } private MediaDescription getMediaDescriptionWithBitmap(Bitmap image) { - MediaDescription.Builder builder = new MediaDescription.Builder() - .setTitle("BT Test Song") - .setDescription("BT Test Description") - .setIconBitmap(image); + MediaDescription.Builder builder = + new MediaDescription.Builder() + .setTitle("BT Test Song") + .setDescription("BT Test Description") + .setIconBitmap(image); return builder.build(); } private MediaDescription getMediaDescriptionWithUri(Uri uri) { - MediaDescription.Builder builder = new MediaDescription.Builder() - .setTitle("BT Test Song") - .setDescription("BT Test Description") - .setIconUri(uri); + MediaDescription.Builder builder = + new MediaDescription.Builder() + .setTitle("BT Test Song") + .setDescription("BT Test Description") + .setIconUri(uri); return builder.build(); } @@ -187,8 +198,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a MediaMetadata object that contains cover artwork - * as an Art Bitmap + * Make sure you can create an Image from a MediaMetadata object that contains cover artwork as + * an Art Bitmap */ @Test public void testCreateImageFromMediaMetadataWithArt() { @@ -201,8 +212,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a MediaMetadata object that contains cover artwork - * as an Album Art Bitmap + * Make sure you can create an Image from a MediaMetadata object that contains cover artwork as + * an Album Art Bitmap */ @Test public void testCreateImageFromMediaMetadataWithAlbumArt() { @@ -215,8 +226,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a MediaMetadata object that contains cover artwork - * as a Display Icon Bitmap + * Make sure you can create an Image from a MediaMetadata object that contains cover artwork as + * a Display Icon Bitmap */ @Test public void testCreateImageFromMediaMetadataWithDisplayIcon() { @@ -229,8 +240,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a MediaMetadata object that contains cover artwork - * as an Art Uri + * Make sure you can create an Image from a MediaMetadata object that contains cover artwork as + * an Art Uri */ @Test public void testCreateImageFromMediaMetadataWithArtUri() { @@ -243,8 +254,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a MediaMetadata object that contains cover artwork - * as an Album Art Uri + * Make sure you can create an Image from a MediaMetadata object that contains cover artwork as + * an Album Art Uri */ @Test public void testCreateImageFromMediaMetadataWithAlbumArtUri() { @@ -257,14 +268,14 @@ public class ImageTest { } /** - * Make sure you can create an Image from a MediaMetadata object that contains cover artwork - * as a Display Icon Uri + * Make sure you can create an Image from a MediaMetadata object that contains cover artwork as + * a Display Icon Uri */ @Test public void testCreateImageFromMediaMetadataWithDisplayIconUri() { MediaMetadata metadata = - getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, - IMAGE_STRING_1); + getMediaMetadataWithUri( + MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, metadata); assertThat(mTestBitmap.sameAs(artwork.getImage())).isTrue(); assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_URI); @@ -277,8 +288,7 @@ public class ImageTest { */ @Test public void testCreateImageFromMediaMetadataWithArtUriDisabled() { - when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)) - .thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); MediaMetadata metadata = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, metadata); @@ -293,8 +303,7 @@ public class ImageTest { */ @Test public void testCreateImageFromMediaMetadataWithAlbumArtUriDisabled() { - when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)) - .thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); MediaMetadata metadata = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, metadata); @@ -309,11 +318,10 @@ public class ImageTest { */ @Test public void testCreateImageFromMediaMetadataWithDisplayIconUriDisabled() { - when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)) - .thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); MediaMetadata metadata = - getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, - IMAGE_STRING_1); + getMediaMetadataWithUri( + MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, metadata); assertThat(artwork.getImage()).isNull(); assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE); @@ -397,8 +405,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a Bundle that contains cover artwork as a Display - * Icon Bitmap + * Make sure you can create an Image from a Bundle that contains cover artwork as a Display Icon + * Bitmap */ @Test public void testCreateImageFromBundleWithDisplayIcon() { @@ -409,9 +417,7 @@ public class ImageTest { assertThat(artwork.getImageHandle()).isNull(); } - /** - * Make sure you can create an Image from a Bundle that contains cover artwork as an Art Uri - */ + /** Make sure you can create an Image from a Bundle that contains cover artwork as an Art Uri */ @Test public void testCreateImageFromBundleWithArtUri() { Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_STRING_1); @@ -435,8 +441,8 @@ public class ImageTest { } /** - * Make sure you can create an Image from a Bundle that contains cover artwork as a Display - * Icon Uri + * Make sure you can create an Image from a Bundle that contains cover artwork as a Display Icon + * Uri */ @Test public void testCreateImageFromBundleWithDisplayIconUri() { @@ -454,8 +460,7 @@ public class ImageTest { */ @Test public void testCreateImageFromBundleWithArtUriDisabled() { - when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)) - .thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, bundle); assertThat(artwork.getImage()).isNull(); @@ -469,8 +474,7 @@ public class ImageTest { */ @Test public void testCreateImageFromBundleWithAlbumArtUriDisabled() { - when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)) - .thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, bundle); assertThat(artwork.getImage()).isNull(); @@ -484,8 +488,7 @@ public class ImageTest { */ @Test public void testCreateImageFromBundleWithDisplayIconUriDisabled() { - when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)) - .thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_STRING_1); Image artwork = new Image(mMockContext, bundle); @@ -494,9 +497,7 @@ public class ImageTest { assertThat(artwork.getImageHandle()).isNull(); } - /** - * Make sure you can create an Image from a Bundle that contains no cover artwork - */ + /** Make sure you can create an Image from a Bundle that contains no cover artwork */ @Test public void testCreateImageFromBundleWithoutArtwork() { Bundle bundle = new Bundle(); @@ -506,9 +507,7 @@ public class ImageTest { assertThat(artwork.getImageHandle()).isNull(); } - /** - * Make sure you can create an image from a simple Uri - */ + /** Make sure you can create an image from a simple Uri */ @Test public void testCreateImageFromUri() { Image artwork = new Image(mMockContext, IMAGE_URI_1); @@ -517,9 +516,7 @@ public class ImageTest { assertThat(artwork.getImageHandle()).isNull(); } - /** - * Make sure you can create an image from a simple Bitmap Image - */ + /** Make sure you can create an image from a simple Bitmap Image */ @Test public void testCreateImageFromBitmap() { Image artwork = new Image(mMockContext, mTestBitmap); @@ -528,18 +525,14 @@ public class ImageTest { assertThat(artwork.getImageHandle()).isNull(); } - /** - * Make sure you can get the image handle associated with this object when there is none set - */ + /** Make sure you can get the image handle associated with this object when there is none set */ @Test public void testGetImageHandleWithEmptyHandle() { Image artwork = new Image(mMockContext, mTestBitmap); assertThat(artwork.getImageHandle()).isNull(); } - /** - * Make sure you can get and set the image handle associated with this object - */ + /** Make sure you can get and set the image handle associated with this object */ @Test public void testSetAndGetImageHandle() { Image artwork = new Image(mMockContext, mTestBitmap); @@ -559,9 +552,7 @@ public class ImageTest { assertThat(artwork.getImage()).isNull(); } - /** - * Make sure you can get a string representation of this Image - */ + /** Make sure you can get a string representation of this Image */ @Test public void testToString() { Image artwork = new Image(mMockContext, mTestBitmap); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java index 6b7af24254a..0cfc114f579 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java @@ -74,22 +74,22 @@ public class MediaPlayerListTest { } Assert.assertNotNull(Looper.myLooper()); - AudioManager mockAudioManager = mock(AudioManager.class); when(mMockContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager); when(mMockContext.getSystemServiceName(AudioManager.class)) - .thenReturn(Context.AUDIO_SERVICE); + .thenReturn(Context.AUDIO_SERVICE); - mMediaSessionManager = InstrumentationRegistry.getTargetContext() - .getSystemService(MediaSessionManager.class); + mMediaSessionManager = + InstrumentationRegistry.getTargetContext() + .getSystemService(MediaSessionManager.class); PackageManager mockPackageManager = mock(PackageManager.class); when(mMockContext.getSystemService(Context.MEDIA_SESSION_SERVICE)) - .thenReturn(mMediaSessionManager); + .thenReturn(mMediaSessionManager); when(mMockContext.getSystemServiceName(MediaSessionManager.class)) - .thenReturn(Context.MEDIA_SESSION_SERVICE); + .thenReturn(Context.MEDIA_SESSION_SERVICE); mMediaPlayerList = - new MediaPlayerList(Looper.myLooper(), InstrumentationRegistry.getTargetContext()); + new MediaPlayerList(Looper.myLooper(), InstrumentationRegistry.getTargetContext()); when(mMockContext.registerReceiver(any(), any())).thenReturn(null); when(mMockContext.getApplicationContext()).thenReturn(mMockContext); @@ -115,7 +115,6 @@ public class MediaPlayerListTest { public void tearDown() throws Exception { BrowsablePlayerConnector.setInstanceForTesting(null); - MediaControllerFactory.inject(null); MediaPlayerWrapperFactory.inject(null); mMediaPlayerList.cleanup(); @@ -129,10 +128,7 @@ public class MediaPlayerListTest { builder.setState(playbackState, 0, 1); ArrayList list = new ArrayList(); list.add(Util.empty_data()); - MediaData newData = new MediaData( - Util.empty_data(), - builder.build(), - list); + MediaData newData = new MediaData(Util.empty_data(), builder.build(), list); return newData; } @@ -141,7 +137,8 @@ public class MediaPlayerListTest { public void testUpdateMeidaDataForAudioPlaybackWhenAcitvePlayNotPlaying() { // Verify update media data with playing state doReturn(prepareMediaData(PlaybackState.STATE_PAUSED)) - .when(mMockPlayerWrapper).getCurrentMediaData(); + .when(mMockPlayerWrapper) + .getCurrentMediaData(); mMediaPlayerList.injectAudioPlaybacActive(true); verify(mMediaUpdateCallback).run(mMediaUpdateData.capture()); MediaData data = mMediaUpdateData.getValue(); @@ -173,7 +170,8 @@ public class MediaPlayerListTest { public void testNotUdpateMediaDataForAudioPlaybackWhenActivePlayerIsPlaying() { // Verify not update media data for Audio Playback when active player is playing doReturn(prepareMediaData(PlaybackState.STATE_PLAYING)) - .when(mMockPlayerWrapper).getCurrentMediaData(); + .when(mMockPlayerWrapper) + .getCurrentMediaData(); mMediaPlayerList.injectAudioPlaybacActive(true); mMediaPlayerList.injectAudioPlaybacActive(false); verify(mMediaUpdateCallback, never()).run(any()); @@ -182,7 +180,8 @@ public class MediaPlayerListTest { @Test public void testNotUdpateMediaDataForActivePlayerWhenAudioPlaybackIsActive() { doReturn(prepareMediaData(PlaybackState.STATE_PLAYING)) - .when(mMockPlayerWrapper).getCurrentMediaData(); + .when(mMockPlayerWrapper) + .getCurrentMediaData(); mMediaPlayerList.injectAudioPlaybacActive(true); verify(mMediaUpdateCallback, never()).run(any()); @@ -197,11 +196,13 @@ public class MediaPlayerListTest { MediaPlayerWrapper activeMediaPlayer = mMediaPlayerList.getActivePlayer(); // Create MediaSession with GLOBAL_PRIORITY flag. - MediaSession session = new MediaSession( - InstrumentationRegistry.getTargetContext(), - MediaPlayerListTest.class.getSimpleName()); - session.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY - | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); + MediaSession session = + new MediaSession( + InstrumentationRegistry.getTargetContext(), + MediaPlayerListTest.class.getSimpleName()); + session.setFlags( + MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY + | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); // Use MediaPlayerList onMediaKeyEventSessionChanged callback to send the new session. mMediaPlayerList.mMediaKeyEventSessionChangedListener.onMediaKeyEventSessionChanged( @@ -210,12 +211,11 @@ public class MediaPlayerListTest { // Retrieve the current available controllers ArrayList currentControllers = new ArrayList( - mMediaSessionManager.getActiveSessions(null)); + mMediaSessionManager.getActiveSessions(null)); // Add the new session currentControllers.add(session.getController()); // Use MediaPlayerList onActiveSessionsChanged callback to send the new session. - mMediaPlayerList.mActiveSessionsChangedListener.onActiveSessionsChanged( - currentControllers); + mMediaPlayerList.mActiveSessionsChangedListener.onActiveSessionsChanged(currentControllers); // Retrieve the new active MediaSession. MediaPlayerWrapper newActiveMediaPlayer = mMediaPlayerList.getActivePlayer(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java index 45039686838..719c65d6eb8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java @@ -94,8 +94,8 @@ public class MediaPlayerWrapperTest { @Before public void setUp() { - mTestResources = TestUtils.getTestApplicationResources( - InstrumentationRegistry.getTargetContext()); + mTestResources = + TestUtils.getTestApplicationResources(InstrumentationRegistry.getTargetContext()); mTestBitmap = loadImage(com.android.bluetooth.tests.R.raw.image_200_200); when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(true); @@ -375,7 +375,9 @@ public class MediaPlayerWrapperTest { // Assert that the metadata returned by getMetadata() is used instead of null verify(mTestCbs, times(1)).mediaUpdatedCallback(mMediaUpdateData.capture()); MediaData data = mMediaUpdateData.getValue(); - Assert.assertEquals("Returned metadata is incorrect", data.metadata, + Assert.assertEquals( + "Returned metadata is incorrect", + data.metadata, Util.toMetadata(mMockContext, mTestMetadata.build())); } @@ -473,15 +475,19 @@ public class MediaPlayerWrapperTest { MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); doReturn(null).when(mMockController).getMetadata(); - Assert.assertFalse(Util.toMetadata(mMockContext, mTestMetadata.build()).duration - .equals(wrapper.getCurrentQueue().get(0).duration)); + Assert.assertFalse( + Util.toMetadata(mMockContext, mTestMetadata.build()) + .duration + .equals(wrapper.getCurrentQueue().get(0).duration)); doReturn(mTestMetadata.build()).when(mMockController).getMetadata(); - Assert.assertEquals(Util.toMetadata(mMockContext, mTestMetadata.build()).duration, + Assert.assertEquals( + Util.toMetadata(mMockContext, mTestMetadata.build()).duration, wrapper.getCurrentQueue().get(0).duration); // The MediaController Metadata should still not be equal to the queue // as the track count is different and should not be overridden. - Assert.assertFalse(Util.toMetadata(mMockContext, mTestMetadata.build()) - .equals(wrapper.getCurrentQueue().get(0))); + Assert.assertFalse( + Util.toMetadata(mMockContext, mTestMetadata.build()) + .equals(wrapper.getCurrentQueue().get(0))); } /* @@ -536,7 +542,6 @@ public class MediaPlayerWrapperTest { doReturn(mTestState.build()).when(mMockController).getPlaybackState(); controllerCallbacks.onPlaybackStateChanged(mTestState.build()); - // Verify that there are no timeout messages pending and there were no timeouts Assert.assertFalse(wrapper.getTimeoutHandler().hasMessages(MSG_TIMEOUT)); verify(mFailHandler, never()).onTerribleFailure(any(), any(), anyBoolean()); @@ -771,7 +776,8 @@ public class MediaPlayerWrapperTest { "Returned PlaybackState isn't equal to given PlaybackState", data.state.toString(), s.build().toString()); - Assert.assertEquals("Returned Queue isn't equal to given Queue", + Assert.assertEquals( + "Returned Queue isn't equal to given Queue", data.queue, Util.toMetadataList(mMockContext, q)); } @@ -783,8 +789,8 @@ public class MediaPlayerWrapperTest { @Test public void pauseCurrent() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -796,8 +802,8 @@ public class MediaPlayerWrapperTest { @Test public void playCurrent() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -809,8 +815,8 @@ public class MediaPlayerWrapperTest { @Test public void playItemFromQueue() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); when(mMockController.getQueue()).thenReturn(new ArrayList<>()); MediaPlayerWrapper wrapper = @@ -824,8 +830,8 @@ public class MediaPlayerWrapperTest { @Test public void rewind() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -837,8 +843,8 @@ public class MediaPlayerWrapperTest { @Test public void seekTo() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -851,8 +857,8 @@ public class MediaPlayerWrapperTest { @Test public void setPlaybackSpeed() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -865,8 +871,8 @@ public class MediaPlayerWrapperTest { @Test public void skipToNext() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -878,8 +884,8 @@ public class MediaPlayerWrapperTest { @Test public void skipToPrevious() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); @@ -891,8 +897,8 @@ public class MediaPlayerWrapperTest { @Test public void stopCurrent() { - MediaController.TransportControls transportControls - = mock(MediaController.TransportControls.class); + MediaController.TransportControls transportControls = + mock(MediaController.TransportControls.class); when(mMockController.getTransportControls()).thenReturn(transportControls); MediaPlayerWrapper wrapper = MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java index 8b8940815e4..47d65269fa9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java @@ -65,15 +65,15 @@ public class MetadataTest { private MockContentResolver mTestContentResolver; private static final String TEST_AUTHORITY = "com.android.bluetooth.avrcp.test"; - private static final Uri TEST_CONTENT_URI = new Uri.Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(TEST_AUTHORITY) - .build(); + private static final Uri TEST_CONTENT_URI = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(TEST_AUTHORITY) + .build(); private static final String IMAGE_HANDLE_1 = "0000001"; - private static final Uri IMAGE_URI_1 = TEST_CONTENT_URI.buildUpon() - .appendQueryParameter("handle", IMAGE_HANDLE_1) - .build(); + private static final Uri IMAGE_URI_1 = + TEST_CONTENT_URI.buildUpon().appendQueryParameter("handle", IMAGE_HANDLE_1).build(); private static final String IMAGE_STRING_1 = IMAGE_URI_1.toString(); private static final Image DEFAULT_IMAGE = null; @@ -100,17 +100,20 @@ public class MetadataTest { mTestBitmap2 = loadImage(com.android.bluetooth.tests.R.raw.image_200_200_blue); mTestContentResolver = new MockContentResolver(mTargetContext); - mTestContentResolver.addProvider(TEST_AUTHORITY, new MockContentProvider() { - @Override - public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) { - String handle = url.getQueryParameter("handle"); - if (IMAGE_URI_1.equals(url)) { - return mTestResources.openRawResourceFd( - com.android.bluetooth.tests.R.raw.image_200_200); - } - return null; - } - }); + mTestContentResolver.addProvider( + TEST_AUTHORITY, + new MockContentProvider() { + @Override + public AssetFileDescriptor openTypedAssetFile( + Uri url, String mimeType, Bundle opts) { + String handle = url.getQueryParameter("handle"); + if (IMAGE_URI_1.equals(url)) { + return mTestResources.openRawResourceFd( + com.android.bluetooth.tests.R.raw.image_200_200); + } + return null; + } + }); when(mMockContext.getContentResolver()).thenReturn(mTestContentResolver); when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(true); @@ -136,52 +139,69 @@ public class MetadataTest { } private MediaMetadata getMediaMetadata() { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) - .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) - .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) - .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM) - .putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, Long.parseLong(SONG_TRACK_NUM)) - .putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS, Long.parseLong(SONG_NUM_TRACKS)) - .putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE) - .putLong(MediaMetadata.METADATA_KEY_DURATION, Long.parseLong(SONG_DURATION)); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) + .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) + .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) + .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM) + .putLong( + MediaMetadata.METADATA_KEY_TRACK_NUMBER, + Long.parseLong(SONG_TRACK_NUM)) + .putLong( + MediaMetadata.METADATA_KEY_NUM_TRACKS, + Long.parseLong(SONG_NUM_TRACKS)) + .putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE) + .putLong( + MediaMetadata.METADATA_KEY_DURATION, Long.parseLong(SONG_DURATION)); return builder.build(); } private MediaMetadata getMediaMetadataWithBitmap(String field, Bitmap image) { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) - .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) - .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) - .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM) - .putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, Long.parseLong(SONG_TRACK_NUM)) - .putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS, Long.parseLong(SONG_NUM_TRACKS)) - .putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE) - .putLong(MediaMetadata.METADATA_KEY_DURATION, Long.parseLong(SONG_DURATION)) - .putBitmap(field, image); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) + .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) + .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) + .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM) + .putLong( + MediaMetadata.METADATA_KEY_TRACK_NUMBER, + Long.parseLong(SONG_TRACK_NUM)) + .putLong( + MediaMetadata.METADATA_KEY_NUM_TRACKS, + Long.parseLong(SONG_NUM_TRACKS)) + .putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE) + .putLong(MediaMetadata.METADATA_KEY_DURATION, Long.parseLong(SONG_DURATION)) + .putBitmap(field, image); return builder.build(); } private MediaMetadata getMediaMetadataWithUri(String field, Uri uri) { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) - .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) - .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) - .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM) - .putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, Long.parseLong(SONG_TRACK_NUM)) - .putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS, Long.parseLong(SONG_NUM_TRACKS)) - .putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE) - .putLong(MediaMetadata.METADATA_KEY_DURATION, Long.parseLong(SONG_DURATION)) - .putString(field, uri.toString()); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) + .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) + .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) + .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM) + .putLong( + MediaMetadata.METADATA_KEY_TRACK_NUMBER, + Long.parseLong(SONG_TRACK_NUM)) + .putLong( + MediaMetadata.METADATA_KEY_NUM_TRACKS, + Long.parseLong(SONG_NUM_TRACKS)) + .putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE) + .putLong(MediaMetadata.METADATA_KEY_DURATION, Long.parseLong(SONG_DURATION)) + .putString(field, uri.toString()); return builder.build(); } private MediaDescription getMediaDescription(Bitmap bitmap, Uri uri, Bundle extras) { - MediaDescription.Builder builder = new MediaDescription.Builder() - .setMediaId(SONG_MEDIA_ID) - .setTitle(SONG_TITLE) - .setSubtitle(SONG_ARTIST) - .setDescription(SONG_ALBUM); + MediaDescription.Builder builder = + new MediaDescription.Builder() + .setMediaId(SONG_MEDIA_ID) + .setTitle(SONG_TITLE) + .setSubtitle(SONG_ARTIST) + .setDescription(SONG_ALBUM); if (bitmap != null) { builder.setIconBitmap(bitmap); } @@ -227,9 +247,17 @@ public class MetadataTest { return bundle; } - private void assertMetadata(String mediaId, String title, String artist, String album, - String trackNum, String numTracks, String genre, String duration, - Image image, Metadata metadata) { + private void assertMetadata( + String mediaId, + String title, + String artist, + String album, + String trackNum, + String numTracks, + String genre, + String duration, + Image image, + Metadata metadata) { assertThat(metadata.mediaId).isEqualTo(mediaId); assertThat(metadata.title).isEqualTo(title); assertThat(metadata.artist).isEqualTo(artist); @@ -241,157 +269,210 @@ public class MetadataTest { Assert.assertTrue(Image.sameAs(metadata.image, image)); } - /** - * Make sure the media ID we set is transferred to Metadata object we build - */ + /** Make sure the media ID we set is transferred to Metadata object we build */ @Test public void testBuildMetadataSetMediaId() { Metadata metadata = new Metadata.Builder().setMediaId(SONG_MEDIA_ID).build(); assertMetadata(SONG_MEDIA_ID, null, null, null, null, null, null, null, null, metadata); } - /** - * Make sure you can build a Metadata from a MediaMetadata that has no art - */ + /** Make sure you can build a Metadata from a MediaMetadata that has no art */ @Test public void testBuildMetadataFromMediaMetadata() { MediaMetadata m = getMediaMetadata(); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, null, metadata); - } - - /** - * Make sure you can build a Metadata from a MediaMetadata that has bitmap art - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + null, + metadata); + } + + /** Make sure you can build a Metadata from a MediaMetadata that has bitmap art */ @Test public void testBuildMetadataFromMediaMetadataWithArt() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure you can build a Metadata from a MediaMetadata that has bitmap album art - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure you can build a Metadata from a MediaMetadata that has bitmap album art */ @Test public void testBuildMetadataFromMediaMetadataWithAlbumArt() { MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure you can build a Metadata from a MediaMetadata that a display icon - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure you can build a Metadata from a MediaMetadata that a display icon */ @Test public void testBuildMetadataFromMediaMetadataWithDisplayIcon() { MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure you can build a Metadata from a MediaMetadata that has Uri based art - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure you can build a Metadata from a MediaMetadata that has Uri based art */ @Test public void testBuildMetadataFromMediaMetadataWithUriArt() { - MediaMetadata m = - getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaMetadata(m) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure you can build a Metadata from a MediaMetadata that has Uri based album art - */ + MediaMetadata m = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromMediaMetadata(m).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure you can build a Metadata from a MediaMetadata that has Uri based album art */ @Test public void testBuildMetadataFromMediaMetadataWithUriAlbumArt() { MediaMetadata m = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaMetadata(m) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure you can build a Metadata from a MediaMetadata that has a Uri based display icon - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromMediaMetadata(m).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure you can build a Metadata from a MediaMetadata that has a Uri based display icon */ @Test public void testBuildMetadataFromMediaMetadataWithUriDisplayIcon() { MediaMetadata m = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaMetadata(m) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure we're robust to build attempts that include Uri based art without a context - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromMediaMetadata(m).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure we're robust to build attempts that include Uri based art without a context */ @Test public void testBuildMetadataFromMediaMetadataWithUriNoContext() { - MediaMetadata m = - getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .fromMediaMetadata(m) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, null, metadata); + MediaMetadata m = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); + Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + null, + metadata); } /** - * Make sure building with a MediaMetadata that contains URI art when URI art is disabled - * yields no cover art. + * Make sure building with a MediaMetadata that contains URI art when URI art is disabled yields + * no cover art. */ @Test public void testBuildMetadataFromMediaMetadataWithUriAndUrisDisabled() { - when(mMockResources.getBoolean( - R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); - MediaMetadata m = - getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaMetadata(m) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, null, metadata); - } - - /** - * Make sure we're robust to building with a null MediaMetadata - */ + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); + MediaMetadata m = getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromMediaMetadata(m).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + null, + metadata); + } + + /** Make sure we're robust to building with a null MediaMetadata */ @Test public void testBuildMetadataFromNullMediaMetadata() { Metadata metadata = new Metadata.Builder().fromMediaMetadata(null).build(); assertMetadata(null, null, null, null, null, null, null, null, null, metadata); } - /** - * Make sure you can create a Metadata from a simple MediaDescription - */ + /** Make sure you can create a Metadata from a simple MediaDescription */ @Test public void testBuildMetadataFromMediaDescription() { MediaDescription description = getMediaDescription(null, null, null); Metadata metadata = new Metadata.Builder().fromMediaDescription(description).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); } /** @@ -402,34 +483,60 @@ public class MetadataTest { public void testBuildMetadataFromMediaDescriptionWithIconArt() { MediaDescription description = getMediaDescription(mTestBitmap, null, null); Metadata metadata = new Metadata.Builder().fromMediaDescription(description).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - mSongImage, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + mSongImage, + metadata); } /** - * Make sure you can create a Metadata from a MediaDescription that contains cover artwork as - * an icon Uri + * Make sure you can create a Metadata from a MediaDescription that contains cover artwork as an + * icon Uri */ @Test public void testBuildMetadataFromMediaDescriptionWithIconUri() { MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaDescription(description) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - mSongImage, metadata); - } - - /** - * Make sure we're robust to attempts to create Uri based images without a context set - */ + Metadata metadata = + new Metadata.Builder() + .useContext(mMockContext) + .fromMediaDescription(description) + .build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + mSongImage, + metadata); + } + + /** Make sure we're robust to attempts to create Uri based images without a context set */ @Test public void testBuildMetadataFromMediaDescriptionWithArtNullContext() { MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); Metadata metadata = new Metadata.Builder().fromMediaDescription(description).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); } /** @@ -441,13 +548,20 @@ public class MetadataTest { Bundle extras = getBundleWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); MediaDescription description = getMediaDescription(null, null, extras); Metadata metadata = new Metadata.Builder().fromMediaDescription(description).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make sure we're robust to null MediaDescriptions - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make sure we're robust to null MediaDescriptions */ @Test public void testBuildMetadataFromNullMediaDescription() { Metadata metadata = new Metadata.Builder().fromMediaDescription(null).build(); @@ -461,8 +575,17 @@ public class MetadataTest { public void testBuildMetadataFromBundle() { Bundle bundle = getBundle(); Metadata metadata = new Metadata.Builder().fromBundle(bundle).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, null, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + null, + metadata); } /** @@ -473,8 +596,17 @@ public class MetadataTest { public void testBuildMetadataFromBundleWithArt() { Bundle bundle = getBundleWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromBundle(bundle).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -485,8 +617,17 @@ public class MetadataTest { public void testBuildMetadataFromBundleWithAlbumArt() { Bundle bundle = getBundleWithBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromBundle(bundle).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -497,8 +638,17 @@ public class MetadataTest { public void testBuildMetadataFromBundleWithDisplayIcon() { Bundle bundle = getBundleWithBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON, mTestBitmap); Metadata metadata = new Metadata.Builder().fromBundle(bundle).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -508,12 +658,19 @@ public class MetadataTest { @Test public void testBuildMetadataFromBundleWithUriArt() { Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromBundle(bundle) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromBundle(bundle).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -523,12 +680,19 @@ public class MetadataTest { @Test public void testBuildMetadataFromBundleWithUriAlbumArt() { Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromBundle(bundle) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromBundle(bundle).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -538,12 +702,19 @@ public class MetadataTest { @Test public void testBuildMetadataFromBundleWithUriDisplayIcon() { Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromBundle(bundle) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromBundle(bundle).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -552,11 +723,18 @@ public class MetadataTest { @Test public void testBuildMetadataFromBundleWithUriNoContext() { Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .fromBundle(bundle) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, null, metadata); + Metadata metadata = new Metadata.Builder().fromBundle(bundle).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + null, + metadata); } /** @@ -565,20 +743,24 @@ public class MetadataTest { */ @Test public void testBuildMetadataFromBundleWithUriAndUrisDisabled() { - when(mMockResources.getBoolean( - R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_URI_1); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromBundle(bundle) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, null, metadata); - } - - /** - * Make sure we're robust to empty Bundles - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromBundle(bundle).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + null, + metadata); + } + + /** Make sure we're robust to empty Bundles */ @Test public void testBuildMetadataFromEmptyBundle() { Bundle bundle = new Bundle(); @@ -586,64 +768,88 @@ public class MetadataTest { assertMetadata(null, null, null, null, null, null, null, null, null, metadata); } - /** - * Make sure we're robust to null Bundles - */ + /** Make sure we're robust to null Bundles */ @Test public void testBuildMetadataFromNullBundle() { Metadata metadata = new Metadata.Builder().fromBundle(null).build(); assertMetadata(null, null, null, null, null, null, null, null, null, metadata); } - /** - * Make a Metadata with a simple MediaItem - */ + /** Make a Metadata with a simple MediaItem */ @Test public void testBuildMetadataFromMediaItem() { MediaDescription description = getMediaDescription(null, null, null); MediaItem item = getMediaItem(description); Metadata metadata = new Metadata.Builder().fromMediaItem(item).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); - } - - /** - * Make a Metadata with a MediaItem that has icon art - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); + } + + /** Make a Metadata with a MediaItem that has icon art */ @Test public void testBuildMetadataFromMediaItemWithIconArt() { MediaDescription description = getMediaDescription(mTestBitmap, null, null); MediaItem item = getMediaItem(description); Metadata metadata = new Metadata.Builder().fromMediaItem(item).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - mSongImage, metadata); - } - - /** - * Make a Metadata with a MediaItem that has an icon uri - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + mSongImage, + metadata); + } + + /** Make a Metadata with a MediaItem that has an icon uri */ @Test public void testBuildMetadataFromMediaItemWithIconUri() { MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); MediaItem item = getMediaItem(description); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaItem(item) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - mSongImage, metadata); - } - - /** - * Make a Metadata with a MediaItem that has an icon uri, but don't use a context - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromMediaItem(item).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + mSongImage, + metadata); + } + + /** Make a Metadata with a MediaItem that has an icon uri, but don't use a context */ @Test public void testBuildMetadataFromMediaItemWithIconUriNoContext() { MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); MediaItem item = getMediaItem(description); Metadata metadata = new Metadata.Builder().fromMediaItem(item).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); } /** @@ -652,125 +858,173 @@ public class MetadataTest { */ @Test public void testBuildMetadataFromMediaItemWithIconUriAndUrisDisabled() { - when(mMockResources.getBoolean( - R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); MediaItem item = getMediaItem(description); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromMediaItem(item) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); - } - - /** - * Make a Metadata with a MediaItem that has extras - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromMediaItem(item).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); + } + + /** Make a Metadata with a MediaItem that has extras */ @Test public void testBuildMetadataFromMediaItemWithExtras() { Bundle extras = getBundleWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); MediaDescription description = getMediaDescription(null, null, extras); MediaItem item = getMediaItem(description); Metadata metadata = new Metadata.Builder().fromMediaItem(item).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make a Metadata with a null MediaItem - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make a Metadata with a null MediaItem */ @Test public void testBuildMetadataFromNullMediaItem() { Metadata metadata = new Metadata.Builder().fromMediaItem(null).build(); assertMetadata(null, null, null, null, null, null, null, null, null, metadata); } - /** - * Make a Metadata from a simple QueueItem - */ + /** Make a Metadata from a simple QueueItem */ @Test public void testBuildMetadataFromQueueItem() { MediaDescription description = getMediaDescription(null, null, null); QueueItem queueItem = getQueueItem(description); Metadata metadata = new Metadata.Builder().fromQueueItem(queueItem).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); - } - - /** - * Make a Metadata from a QueueItem with icon art - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); + } + + /** Make a Metadata from a QueueItem with icon art */ @Test public void testBuildMetadataFromQueueItemWithIconArt() { MediaDescription description = getMediaDescription(mTestBitmap, null, null); QueueItem queueItem = getQueueItem(description); Metadata metadata = new Metadata.Builder().fromQueueItem(queueItem).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - mSongImage, metadata); - } - - /** - * Make a Metadata from a QueueItem with an icon uri - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + mSongImage, + metadata); + } + + /** Make a Metadata from a QueueItem with an icon uri */ @Test public void testBuildMetadataFromQueueItemWithIconUri() { MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); QueueItem queueItem = getQueueItem(description); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromQueueItem(queueItem) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - mSongImage, metadata); - } - - /** - * Make a Metadata from a QueueItem with an icon uri, but don't use a context - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromQueueItem(queueItem).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + mSongImage, + metadata); + } + + /** Make a Metadata from a QueueItem with an icon uri, but don't use a context */ @Test public void testBuildMetadataFromQueueItemWithIconUriNoContext() { MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); QueueItem queueItem = getQueueItem(description); Metadata metadata = new Metadata.Builder().fromQueueItem(queueItem).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); } /** - * Make sure building with a QueueItem that contains URI art when URI art is disabled yields - * no cover art. + * Make sure building with a QueueItem that contains URI art when URI art is disabled yields no + * cover art. */ @Test public void testBuildMetadataFromQueueItemWithIconUriandUrisDisabled() { - when(mMockResources.getBoolean( - R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); + when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(false); MediaDescription description = getMediaDescription(null, IMAGE_URI_1, null); QueueItem queueItem = getQueueItem(description); - Metadata metadata = new Metadata.Builder() - .useContext(mMockContext) - .fromQueueItem(queueItem) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, null, null, null, null, - null, metadata); - } - - /** - * Make a Metadata from a QueueItem with extras - */ + Metadata metadata = + new Metadata.Builder().useContext(mMockContext).fromQueueItem(queueItem).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + null, + null, + null, + null, + null, + metadata); + } + + /** Make a Metadata from a QueueItem with extras */ @Test public void testBuildMetadataFromQueueItemWithExtras() { Bundle extras = getBundleWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); MediaDescription description = getMediaDescription(null, null, extras); QueueItem queueItem = getQueueItem(description); Metadata metadata = new Metadata.Builder().fromQueueItem(queueItem).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); - } - - /** - * Make a Metadata with a null QueueItem - */ + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); + } + + /** Make a Metadata with a null QueueItem */ @Test public void testBuildMetadataFromNullQueueItem() { Metadata metadata = new Metadata.Builder().fromQueueItem(null).build(); @@ -783,9 +1037,17 @@ public class MetadataTest { @Test public void testBuildMetadataUseDefaults() { Metadata metadata = new Metadata.Builder().useDefaults().build(); - assertMetadata(Metadata.EMPTY_MEDIA_ID, Metadata.EMPTY_TITLE, Metadata.EMPTY_ARTIST, - Metadata.EMPTY_ALBUM, Metadata.EMPTY_TRACK_NUM, Metadata.EMPTY_NUM_TRACKS, - Metadata.EMPTY_GENRE, Metadata.EMPTY_DURATION, DEFAULT_IMAGE, metadata); + assertMetadata( + Metadata.EMPTY_MEDIA_ID, + Metadata.EMPTY_TITLE, + Metadata.EMPTY_ARTIST, + Metadata.EMPTY_ALBUM, + Metadata.EMPTY_TRACK_NUM, + Metadata.EMPTY_NUM_TRACKS, + Metadata.EMPTY_GENRE, + Metadata.EMPTY_DURATION, + DEFAULT_IMAGE, + metadata); } /** @@ -795,13 +1057,19 @@ public class MetadataTest { @Test public void testBuildMetadataUseDefaultsAndPartialFields() { MediaDescription description = getMediaDescription(null, null, null); - Metadata metadata = new Metadata.Builder() - .useDefaults() - .fromMediaDescription(description) - .build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, - Metadata.EMPTY_TRACK_NUM, Metadata.EMPTY_NUM_TRACKS, Metadata.EMPTY_GENRE, - Metadata.EMPTY_DURATION, DEFAULT_IMAGE, metadata); + Metadata metadata = + new Metadata.Builder().useDefaults().fromMediaDescription(description).build(); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + Metadata.EMPTY_TRACK_NUM, + Metadata.EMPTY_NUM_TRACKS, + Metadata.EMPTY_GENRE, + Metadata.EMPTY_DURATION, + DEFAULT_IMAGE, + metadata); } /** @@ -810,11 +1078,19 @@ public class MetadataTest { */ @Test public void testBuildMetadataUseDefaultsAndAllFields() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().useDefaults().fromMediaMetadata(m).build(); - assertMetadata(SONG_MEDIA_ID, SONG_TITLE, SONG_ARTIST, SONG_ALBUM, SONG_TRACK_NUM, - SONG_NUM_TRACKS, SONG_GENRE, SONG_DURATION, mSongImage, metadata); + assertMetadata( + SONG_MEDIA_ID, + SONG_TITLE, + SONG_ARTIST, + SONG_ALBUM, + SONG_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + SONG_DURATION, + mSongImage, + metadata); } /** @@ -829,15 +1105,23 @@ public class MetadataTest { bundle.putString(MediaMetadata.METADATA_KEY_GENRE, SONG_GENRE); bundle.putParcelable(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().useDefaults().fromBundle(bundle).build(); - assertMetadata(Metadata.EMPTY_MEDIA_ID, SONG_TITLE, Metadata.EMPTY_ARTIST, - Metadata.EMPTY_ALBUM, Metadata.EMPTY_TRACK_NUM, SONG_NUM_TRACKS, SONG_GENRE, - Metadata.EMPTY_DURATION, mSongImage, metadata); + assertMetadata( + Metadata.EMPTY_MEDIA_ID, + SONG_TITLE, + Metadata.EMPTY_ARTIST, + Metadata.EMPTY_ALBUM, + Metadata.EMPTY_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + Metadata.EMPTY_DURATION, + mSongImage, + metadata); } /** - * Build a Metadata using the defaults. Call useDefaults at the end after other fields have - * been extracted from the media framework objects. Ensure we don't overwrite existing values - * with defaults. Ensure that the metadata created is the same (by field) as the one where + * Build a Metadata using the defaults. Call useDefaults at the end after other fields have been + * extracted from the media framework objects. Ensure we don't overwrite existing values with + * defaults. Ensure that the metadata created is the same (by field) as the one where * useDefaults is called first. */ @Test @@ -849,21 +1133,34 @@ public class MetadataTest { bundle.putParcelable(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromBundle(bundle).useDefaults().build(); Metadata metadata2 = new Metadata.Builder().useDefaults().fromBundle(bundle).build(); - assertMetadata(Metadata.EMPTY_MEDIA_ID, SONG_TITLE, Metadata.EMPTY_ARTIST, - Metadata.EMPTY_ALBUM, Metadata.EMPTY_TRACK_NUM, SONG_NUM_TRACKS, SONG_GENRE, - Metadata.EMPTY_DURATION, mSongImage, metadata); - assertMetadata(Metadata.EMPTY_MEDIA_ID, SONG_TITLE, Metadata.EMPTY_ARTIST, - Metadata.EMPTY_ALBUM, Metadata.EMPTY_TRACK_NUM, SONG_NUM_TRACKS, SONG_GENRE, - Metadata.EMPTY_DURATION, mSongImage, metadata2); - } - - /** - * Make sure you can clone a Metadata - */ + assertMetadata( + Metadata.EMPTY_MEDIA_ID, + SONG_TITLE, + Metadata.EMPTY_ARTIST, + Metadata.EMPTY_ALBUM, + Metadata.EMPTY_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + Metadata.EMPTY_DURATION, + mSongImage, + metadata); + assertMetadata( + Metadata.EMPTY_MEDIA_ID, + SONG_TITLE, + Metadata.EMPTY_ARTIST, + Metadata.EMPTY_ALBUM, + Metadata.EMPTY_TRACK_NUM, + SONG_NUM_TRACKS, + SONG_GENRE, + Metadata.EMPTY_DURATION, + mSongImage, + metadata2); + } + + /** Make sure you can clone a Metadata */ @Test public void testClone() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); Metadata metadata2 = metadata.clone(); assertThat(metadata.mediaId).isEqualTo(metadata2.mediaId); @@ -878,74 +1175,57 @@ public class MetadataTest { assertThat(metadata).isEqualTo(metadata2); } - /** - * Make sure two Metadata objects are different if title doesn't match - */ + /** Make sure two Metadata objects are different if title doesn't match */ @Test public void testEqualsDifferentTitle() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); Metadata metadata2 = metadata.clone(); metadata2.title = null; assertThat(metadata).isNotEqualTo(metadata2); } - /** - * Make sure two Metadata objects are different if artist doesn't match - */ + /** Make sure two Metadata objects are different if artist doesn't match */ @Test public void testEqualsDifferentArtist() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); Metadata metadata2 = metadata.clone(); metadata2.artist = Metadata.EMPTY_ARTIST; assertThat(metadata).isNotEqualTo(metadata2); } - /** - * Make sure two Metadata objects are different if album doesn't match - */ + /** Make sure two Metadata objects are different if album doesn't match */ @Test public void testEqualsDifferentAlbum() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); Metadata metadata2 = metadata.clone(); metadata2.album = Metadata.EMPTY_ALBUM; assertThat(metadata).isNotEqualTo(metadata2); } - /** - * Make sure two Metadata objects are different if trackNum doesn't match - */ + /** Make sure two Metadata objects are different if trackNum doesn't match */ @Test public void testEqualsDifferentTrackNum() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); Metadata metadata2 = metadata.clone(); metadata2.trackNum = Metadata.EMPTY_TRACK_NUM; assertThat(metadata).isNotEqualTo(metadata2); } - /** - * Make sure two Metadata objects are different if numTracks doesn't match - */ + /** Make sure two Metadata objects are different if numTracks doesn't match */ @Test public void testEqualsDifferentNumTracks() { - MediaMetadata m = - getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); + MediaMetadata m = getMediaMetadataWithBitmap(MediaMetadata.METADATA_KEY_ART, mTestBitmap); Metadata metadata = new Metadata.Builder().fromMediaMetadata(m).build(); Metadata metadata2 = metadata.clone(); metadata2.numTracks = Metadata.EMPTY_NUM_TRACKS; assertThat(metadata).isNotEqualTo(metadata2); } - /** - * Make sure you can get any non-null string representation of Metadata - */ + /** Make sure you can get any non-null string representation of Metadata */ @Test public void testToString() { Metadata metadata = new Metadata.Builder().build(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java index cbae50e01a3..27ec1fcd9fa 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java @@ -47,8 +47,10 @@ public class UtilTest { @Test public void getDisplayName() throws Exception { PackageManager manager = mContext.getPackageManager(); - String displayName = manager.getApplicationLabel( - manager.getApplicationInfo(mContext.getPackageName(), 0)).toString(); + String displayName = + manager.getApplicationLabel( + manager.getApplicationInfo(mContext.getPackageName(), 0)) + .toString(); assertThat(Util.getDisplayName(mContext, mContext.getPackageName())).isEqualTo(displayName); String invalidPackage = "invalidPackage"; @@ -57,8 +59,8 @@ public class UtilTest { @Test public void toMetadata_withMediaItem() { - Metadata metadata = Util.toMetadata(mContext, - new MediaBrowser.MediaItem(createDescription(), 0)); + Metadata metadata = + Util.toMetadata(mContext, new MediaBrowser.MediaItem(createDescription(), 0)); assertThat(metadata.mediaId).isEqualTo(SONG_MEDIA_ID); assertThat(metadata.title).isEqualTo(SONG_TITLE); assertThat(metadata.artist).isEqualTo(SONG_ARTIST); @@ -69,8 +71,8 @@ public class UtilTest { public void toMetadata_withQueueItem() { // This will change the media ID to NOW_PLAYING_PREFIX ('NowPlayingId') + the given id long queueId = 1; - Metadata metadata = Util.toMetadata(mContext, - new MediaSession.QueueItem(createDescription(), queueId)); + Metadata metadata = + Util.toMetadata(mContext, new MediaSession.QueueItem(createDescription(), queueId)); assertThat(metadata.mediaId).isEqualTo(Util.NOW_PLAYING_PREFIX + queueId); assertThat(metadata.title).isEqualTo(SONG_TITLE); assertThat(metadata.artist).isEqualTo(SONG_ARTIST); @@ -79,11 +81,12 @@ public class UtilTest { @Test public void toMetadata_withMediaMetadata() { - MediaMetadata.Builder builder = new MediaMetadata.Builder() - .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) - .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) - .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) - .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM); + MediaMetadata.Builder builder = + new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, SONG_MEDIA_ID) + .putString(MediaMetadata.METADATA_KEY_TITLE, SONG_TITLE) + .putString(MediaMetadata.METADATA_KEY_ARTIST, SONG_ARTIST) + .putString(MediaMetadata.METADATA_KEY_ALBUM, SONG_ALBUM); // This will change the media ID to "currsong". Metadata metadata = Util.toMetadata(mContext, builder.build()); assertThat(metadata.mediaId).isEqualTo("currsong"); @@ -123,16 +126,16 @@ public class UtilTest { assertThat(PlayStatus.playbackStateToAvrcpState(PlaybackState.STATE_ERROR)) .isEqualTo(PlayStatus.ERROR); - assertThat(PlayStatus.playbackStateToAvrcpState(-100)) - .isEqualTo(PlayStatus.ERROR); + assertThat(PlayStatus.playbackStateToAvrcpState(-100)).isEqualTo(PlayStatus.ERROR); } MediaDescription createDescription() { - MediaDescription.Builder builder = new MediaDescription.Builder() - .setMediaId(SONG_MEDIA_ID) - .setTitle(SONG_TITLE) - .setSubtitle(SONG_ARTIST) - .setDescription(SONG_ALBUM); + MediaDescription.Builder builder = + new MediaDescription.Builder() + .setMediaId(SONG_MEDIA_ID) + .setTitle(SONG_TITLE) + .setSubtitle(SONG_ARTIST) + .setDescription(SONG_ALBUM); return builder.build(); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java index ded83dec58b..26d732b28e5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java @@ -58,43 +58,45 @@ public class AvrcpBipObexServerTest { private static final byte HEADER_ID_IMG_HANDLE = 0x30; private static final byte HEADER_ID_IMG_DESCRIPTOR = 0x71; - private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] { - (byte) 0x71, - (byte) 0x63, - (byte) 0xDD, - (byte) 0x54, - (byte) 0x4A, - (byte) 0x7E, - (byte) 0x11, - (byte) 0xE2, - (byte) 0xB4, - (byte) 0x7C, - (byte) 0x00, - (byte) 0x50, - (byte) 0xC2, - (byte) 0x49, - (byte) 0x00, - (byte) 0x48 - }; - - private static final byte[] NOT_BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] { - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00, - (byte) 0x00 - }; + private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = + new byte[] { + (byte) 0x71, + (byte) 0x63, + (byte) 0xDD, + (byte) 0x54, + (byte) 0x4A, + (byte) 0x7E, + (byte) 0x11, + (byte) 0xE2, + (byte) 0xB4, + (byte) 0x7C, + (byte) 0x00, + (byte) 0x50, + (byte) 0xC2, + (byte) 0x49, + (byte) 0x00, + (byte) 0x48 + }; + + private static final byte[] NOT_BLUETOOTH_UUID_AVRCP_COVER_ART = + new byte[] { + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00 + }; private static final String IMAGE_HANDLE_1 = "0000001"; private static final String IMAGE_HANDLE_UNSTORED = "0000256"; @@ -114,8 +116,8 @@ public class AvrcpBipObexServerTest { @Before public void setUp() throws Exception { - mTestResources = TestUtils.getTestApplicationResources( - InstrumentationRegistry.getTargetContext()); + mTestResources = + TestUtils.getTestApplicationResources(InstrumentationRegistry.getTargetContext()); mCoverArt = loadCoverArt(com.android.bluetooth.tests.R.raw.image_200_200); @@ -156,11 +158,8 @@ public class AvrcpBipObexServerTest { /** * Creates a mocked operation that can be used by our server as a client request * - * Our server will use: - * - getReceivedHeader - * - sendHeaders - * - getMaxPacketSize - * - openOutputStream + *

Our server will use: - getReceivedHeader - sendHeaders - getMaxPacketSize - + * openOutputStream */ private Operation makeOperation(HeaderSet requestHeaders, OutputStream os) throws Exception { Operation op = mock(Operation.class); @@ -174,12 +173,11 @@ public class AvrcpBipObexServerTest { return new BipImageDescriptor.Builder() .setEncoding(encoding) .setFixedDimensions(width, height) - .build().serialize(); + .build() + .serialize(); } - /** - * Make sure we let a connection through with a valid UUID - */ + /** Make sure we let a connection through with a valid UUID */ @Test public void testConnectWithValidUuidHeader() throws Exception { mRequest.setHeader(HeaderSet.TARGET, BLUETOOTH_UUID_AVRCP_COVER_ART); @@ -188,9 +186,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_OK); } - /** - * Make sure we deny a connection when there is an invalid UUID - */ + /** Make sure we deny a connection when there is an invalid UUID */ @Test public void testConnectWithInvalidUuidHeader() throws Exception { mRequest.setHeader(HeaderSet.TARGET, NOT_BLUETOOTH_UUID_AVRCP_COVER_ART); @@ -199,27 +195,21 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE); } - /** - * Make sure onDisconnect notifies the callbacks in the proper way - */ + /** Make sure onDisconnect notifies the callbacks in the proper way */ @Test public void testDisonnect() { mAvrcpBipObexServer.onDisconnect(mRequest, mReply); verify(mCallback, times(1)).onDisconnected(); } - /** - * Make sure onClose notifies the callbacks in the proper way - */ + /** Make sure onClose notifies the callbacks in the proper way */ @Test public void testOnClose() { mAvrcpBipObexServer.onClose(); verify(mCallback, times(1)).onClose(); } - /** - * Make sure onGet handles null headers gracefully - */ + /** Make sure onGet handles null headers gracefully */ @Test public void testOnGetNoHeaders() throws Exception { Operation op = makeOperation(null, mOutputStream); @@ -227,9 +217,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST); } - /** - * Make sure onGet handles bad type gracefully - */ + /** Make sure onGet handles bad type gracefully */ @Test public void testOnGetBadType() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_BAD); @@ -238,9 +226,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST); } - /** - * Make sure onGet handles no type gracefully - */ + /** Make sure onGet handles no type gracefully */ @Test public void testOnGetNoType() throws Exception { mRequest.setHeader(HeaderSet.TYPE, null); @@ -249,9 +235,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST); } - /** - * Make sure a getImageThumbnail request with a valid handle works - */ + /** Make sure a getImageThumbnail request with a valid handle works */ @Test public void testGetLinkedThumbnailWithValidHandle() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_LINKED_THUMBNAIL); @@ -262,9 +246,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_OK); } - /** - * Make sure a getImageThumbnail request with a unstored handle returns OBEX_HTTP_NOT_FOUND - */ + /** Make sure a getImageThumbnail request with a unstored handle returns OBEX_HTTP_NOT_FOUND */ @Test public void testGetLinkedThumbnailWithValidUnstoredHandle() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_LINKED_THUMBNAIL); @@ -313,9 +295,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_OK); } - /** - * Make sure a getImageProperties request with a unstored handle returns OBEX_HTTP_NOT_FOUND - */ + /** Make sure a getImageProperties request with a unstored handle returns OBEX_HTTP_NOT_FOUND */ @Test public void testGetImagePropertiesWithValidUnstoredHandle() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_IMAGE_PROPERTIES); @@ -351,9 +331,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST); } - /** - * Make sure a GetImage request with a null descriptor returns a native image - */ + /** Make sure a GetImage request with a null descriptor returns a native image */ @Test public void testGetImageWithValidHandleAndNullDescriptor() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_IMAGE); @@ -365,9 +343,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_OK); } - /** - * Make sure a GetImage request with a valid descriptor returns an image - */ + /** Make sure a GetImage request with a valid descriptor returns an image */ @Test public void testGetImageWithValidHandleAndValidDescriptor() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_IMAGE); @@ -386,7 +362,8 @@ public class AvrcpBipObexServerTest { public void testGetImageWithValidHandleAndInvalidDescriptor() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_IMAGE); mRequest.setHeader(HEADER_ID_IMG_HANDLE, IMAGE_HANDLE_1); - mRequest.setHeader(HEADER_ID_IMG_DESCRIPTOR, + mRequest.setHeader( + HEADER_ID_IMG_DESCRIPTOR, makeDescriptor(BipEncoding.WBMP /* No Android support, won't work */, 200, 200)); setCoverArtAvailableAtHandle(IMAGE_HANDLE_1, mCoverArt); Operation op = makeOperation(mRequest, mOutputStream); @@ -394,9 +371,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE); } - /** - * Make sure a GetImage request with a unstored handle returns OBEX_HTTP_NOT_FOUND - */ + /** Make sure a GetImage request with a unstored handle returns OBEX_HTTP_NOT_FOUND */ @Test public void testGetImageWithValidUnstoredHandle() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_IMAGE); @@ -420,9 +395,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_PRECON_FAILED); } - /** - * Make sure a getImage request with a null handle returns OBEX_HTTP_BAD_REQUEST - */ + /** Make sure a getImage request with a null handle returns OBEX_HTTP_BAD_REQUEST */ @Test public void testGetImageWithNullHandle() throws Exception { mRequest.setHeader(HeaderSet.TYPE, TYPE_GET_IMAGE); @@ -433,9 +406,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST); } - /** - * Make sure onPut is not a supported action - */ + /** Make sure onPut is not a supported action */ @Test public void testOnPut() { Operation op = null; @@ -443,9 +414,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED); } - /** - * Make sure onAbort is not a supported action - */ + /** Make sure onAbort is not a supported action */ @Test public void testOnAbort() { HeaderSet request = null; @@ -454,9 +423,7 @@ public class AvrcpBipObexServerTest { assertThat(responseCode).isEqualTo(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED); } - /** - * Make sure onSetPath is not a supported action - */ + /** Make sure onSetPath is not a supported action */ @Test public void testOnSetPath() { HeaderSet request = null; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java index d69fae650d9..ff2eb37a87d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java @@ -43,8 +43,8 @@ public class AvrcpCoverArtStorageTest { @Before public void setUp() throws Exception { - mTestResources = TestUtils.getTestApplicationResources( - InstrumentationRegistry.getTargetContext()); + mTestResources = + TestUtils.getTestApplicationResources(InstrumentationRegistry.getTargetContext()); mAvrcpCoverArtStorage = new AvrcpCoverArtStorage(2); } @@ -63,9 +63,7 @@ public class AvrcpCoverArtStorageTest { return new CoverArt(image); } - /** - * Make sure you can store and get an image handle for an image - */ + /** Make sure you can store and get an image handle for an image */ @Test public void testStoreImage() { CoverArt artwork = getCoverArt(com.android.bluetooth.tests.R.raw.image_200_200); @@ -74,9 +72,7 @@ public class AvrcpCoverArtStorageTest { assertThat(mAvrcpCoverArtStorage.getImage(handle)).isEqualTo(artwork); } - /** - * Make sure an attempt to store an image that is already stored yields the previous handle - */ + /** Make sure an attempt to store an image that is already stored yields the previous handle */ @Test public void testStoreImageThatIsAlreadyStored() { CoverArt artwork = getCoverArt(com.android.bluetooth.tests.R.raw.image_200_200); @@ -85,9 +81,7 @@ public class AvrcpCoverArtStorageTest { assertThat(mAvrcpCoverArtStorage.storeImage(artwork)).isEqualTo(handle); } - /** - * Make sure you can store and get an image handle for a second image thats not yet stored - */ + /** Make sure you can store and get an image handle for a second image thats not yet stored */ @Test public void testStoreSecondImage() { CoverArt artwork_green = getCoverArt(com.android.bluetooth.tests.R.raw.image_200_200); @@ -104,7 +98,7 @@ public class AvrcpCoverArtStorageTest { /** * Make sure you can store and get an image handle for a third image thats not yet stored. * - * Since the cache size is set to 2 for these tests, this third image should force the least + *

Since the cache size is set to 2 for these tests, this third image should force the least * recently used image to be removed. This test has the LRU image as the first one entered. */ @Test @@ -136,7 +130,7 @@ public class AvrcpCoverArtStorageTest { /** * Make sure you can store and get an image handle for a third image thats not yet stored. * - * Since the cache size is set to 2 for these tests, this third image should force the least + *

Since the cache size is set to 2 for these tests, this third image should force the least * recently used image to be removed. This test has the LRU image as the second one entered. */ @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpPassthroughTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpPassthroughTest.java index a88a849c697..8dbaf5833b0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpPassthroughTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpPassthroughTest.java @@ -12,120 +12,115 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public final class AvrcpPassthroughTest { - @Test - public void toKeyCode() { - AvrcpPassthrough ap = new AvrcpPassthrough(); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_UP)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_UP); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_DOWN)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_DOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_LEFT)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_LEFT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RIGHT)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_RIGHT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RIGHT_UP)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_UP_RIGHT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RIGHT_DOWN)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_DOWN_RIGHT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_LEFT_UP)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_UP_LEFT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_LEFT_DOWN)) - .isEqualTo(KeyEvent.KEYCODE_DPAD_DOWN_LEFT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_0)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_0); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_1)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_1); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_2)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_2); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_3)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_3); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_4)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_4); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_5)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_5); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_6)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_6); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_7)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_7); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_8)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_8); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_9)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_9); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_DOT)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_DOT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_ENTER)) - .isEqualTo(KeyEvent.KEYCODE_NUMPAD_ENTER); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_CLEAR)) - .isEqualTo(KeyEvent.KEYCODE_CLEAR); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_CHAN_DOWN)) - .isEqualTo(KeyEvent.KEYCODE_CHANNEL_DOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PREV_CHAN)) - .isEqualTo(KeyEvent.KEYCODE_LAST_CHANNEL); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_INPUT_SEL)) - .isEqualTo(KeyEvent.KEYCODE_TV_INPUT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_DISP_INFO)) - .isEqualTo(KeyEvent.KEYCODE_INFO); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_HELP)) - .isEqualTo(KeyEvent.KEYCODE_HELP); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PAGE_UP)) - .isEqualTo(KeyEvent.KEYCODE_PAGE_UP); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PAGE_DOWN)) - .isEqualTo(KeyEvent.KEYCODE_PAGE_DOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_POWER)) - .isEqualTo(KeyEvent.KEYCODE_POWER); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_VOL_UP)) - .isEqualTo(KeyEvent.KEYCODE_VOLUME_UP); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_VOL_DOWN)) - .isEqualTo(KeyEvent.KEYCODE_VOLUME_DOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_MUTE)) - .isEqualTo(KeyEvent.KEYCODE_MUTE); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PLAY)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_PLAY); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_STOP)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_STOP); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PAUSE)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_PAUSE); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RECORD)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_RECORD); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_REWIND)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_REWIND); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_FAST_FOR)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_EJECT)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_EJECT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_FORWARD)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_NEXT); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_BACKWARD)) - .isEqualTo(KeyEvent.KEYCODE_MEDIA_PREVIOUS); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F1)) - .isEqualTo(KeyEvent.KEYCODE_F1); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F2)) - .isEqualTo(KeyEvent.KEYCODE_F2); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F3)) - .isEqualTo(KeyEvent.KEYCODE_F3); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F4)) - .isEqualTo(KeyEvent.KEYCODE_F4); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F5)) - .isEqualTo(KeyEvent.KEYCODE_F5); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SELECT)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_ROOT_MENU)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SETUP_MENU)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_CONT_MENU)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_FAV_MENU)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_EXIT)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SOUND_SEL)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_ANGLE)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SUBPICT)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_VENDOR)) - .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); - } + @Test + public void toKeyCode() { + AvrcpPassthrough ap = new AvrcpPassthrough(); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_UP)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_UP); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_DOWN)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_DOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_LEFT)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_LEFT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RIGHT)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_RIGHT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RIGHT_UP)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_UP_RIGHT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RIGHT_DOWN)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_DOWN_RIGHT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_LEFT_UP)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_UP_LEFT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_LEFT_DOWN)) + .isEqualTo(KeyEvent.KEYCODE_DPAD_DOWN_LEFT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_0)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_0); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_1)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_1); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_2)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_2); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_3)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_3); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_4)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_4); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_5)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_5); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_6)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_6); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_7)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_7); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_8)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_8); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_9)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_9); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_DOT)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_DOT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_ENTER)) + .isEqualTo(KeyEvent.KEYCODE_NUMPAD_ENTER); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_CLEAR)) + .isEqualTo(KeyEvent.KEYCODE_CLEAR); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_CHAN_DOWN)) + .isEqualTo(KeyEvent.KEYCODE_CHANNEL_DOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PREV_CHAN)) + .isEqualTo(KeyEvent.KEYCODE_LAST_CHANNEL); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_INPUT_SEL)) + .isEqualTo(KeyEvent.KEYCODE_TV_INPUT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_DISP_INFO)) + .isEqualTo(KeyEvent.KEYCODE_INFO); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_HELP)) + .isEqualTo(KeyEvent.KEYCODE_HELP); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PAGE_UP)) + .isEqualTo(KeyEvent.KEYCODE_PAGE_UP); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PAGE_DOWN)) + .isEqualTo(KeyEvent.KEYCODE_PAGE_DOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_POWER)) + .isEqualTo(KeyEvent.KEYCODE_POWER); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_VOL_UP)) + .isEqualTo(KeyEvent.KEYCODE_VOLUME_UP); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_VOL_DOWN)) + .isEqualTo(KeyEvent.KEYCODE_VOLUME_DOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_MUTE)) + .isEqualTo(KeyEvent.KEYCODE_MUTE); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PLAY)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_PLAY); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_STOP)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_STOP); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_PAUSE)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_PAUSE); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_RECORD)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_RECORD); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_REWIND)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_REWIND); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_FAST_FOR)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_EJECT)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_EJECT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_FORWARD)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_NEXT); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_BACKWARD)) + .isEqualTo(KeyEvent.KEYCODE_MEDIA_PREVIOUS); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F1)).isEqualTo(KeyEvent.KEYCODE_F1); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F2)).isEqualTo(KeyEvent.KEYCODE_F2); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F3)).isEqualTo(KeyEvent.KEYCODE_F3); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F4)).isEqualTo(KeyEvent.KEYCODE_F4); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_F5)).isEqualTo(KeyEvent.KEYCODE_F5); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SELECT)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_ROOT_MENU)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SETUP_MENU)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_CONT_MENU)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_FAV_MENU)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_EXIT)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SOUND_SEL)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_ANGLE)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_SUBPICT)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + assertThat(ap.toKeyCode(BluetoothAvrcp.PASSTHROUGH_ID_VENDOR)) + .isEqualTo(KeyEvent.KEYCODE_UNKNOWN); + } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java index b367484c443..5ace4413c81 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java @@ -53,11 +53,9 @@ public class AvrcpVolumeManagerTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - AvrcpNativeInterface mNativeInterface; + @Mock AvrcpNativeInterface mNativeInterface; - @Mock - AudioManager mAudioManager; + @Mock AudioManager mAudioManager; Context mContext; BluetoothDevice mRemoteDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java index 4c37d8a3df1..42f4aac0ab2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java @@ -58,8 +58,8 @@ public class CoverArtTest { @Before public void setUp() throws Exception { - mTestResources = TestUtils.getTestApplicationResources( - InstrumentationRegistry.getTargetContext()); + mTestResources = + TestUtils.getTestApplicationResources(InstrumentationRegistry.getTargetContext()); m200by200Image = loadImage(com.android.bluetooth.tests.R.raw.image_200_200); m200by200ImageBlue = loadImage(com.android.bluetooth.tests.R.raw.image_200_200_blue); @@ -129,18 +129,14 @@ public class CoverArtTest { return (200 == image.getHeight() && 200 == image.getWidth()); } - /** - * Make sure you can create an image from an Image object - */ + /** Make sure you can create an image from an Image object */ @Test public void testCreateCoverArtFromImage() { CoverArt artwork = new CoverArt(mImage); assertThat(artwork.getImage()).isNotNull(); } - /** - * Make sure you get an image hash from a valid image - */ + /** Make sure you get an image hash from a valid image */ @Test public void testGetImageHash() { CoverArt artwork = new CoverArt(mImage); @@ -148,9 +144,7 @@ public class CoverArtTest { assertThat(hash).isNotNull(); } - /** - * Make sure you get the same image hash from several calls to the same object - */ + /** Make sure you get the same image hash from several calls to the same object */ @Test public void testGetImageHashSameForMultipleCalls() { CoverArt artwork = new CoverArt(mImage); @@ -160,9 +154,7 @@ public class CoverArtTest { assertThat(artwork.getImageHash()).isEqualTo(hash); // extra call 2 } - /** - * Make sure you get the same image hash from separate objects created from the same image - */ + /** Make sure you get the same image hash from separate objects created from the same image */ @Test public void testGetImageHashSameForSameImages() { CoverArt artwork = new CoverArt(mImage); @@ -190,9 +182,7 @@ public class CoverArtTest { assertThat(hash).isNotEqualTo(hash2); } - /** - * Make sure you get an image when asking for the native image - */ + /** Make sure you get an image when asking for the native image */ @Test public void testGetNativeImage() { CoverArt artwork = new CoverArt(mImage); @@ -200,9 +190,7 @@ public class CoverArtTest { assertThat(image).isNotNull(); } - /** - * Make sure you getThumbnailImage returns an image as a 200 by 200 JPEG - */ + /** Make sure you getThumbnailImage returns an image as a 200 by 200 JPEG */ @Test public void testGetThumbnailImage() { CoverArt artwork = new CoverArt(mImage); @@ -212,9 +200,7 @@ public class CoverArtTest { assertThat(isThumbnailFormat(image)).isTrue(); } - /** - * Make sure you can set the image handle associated with this object - */ + /** Make sure you can set the image handle associated with this object */ @Test public void testGetAndSetImageHandle() { CoverArt artwork = new CoverArt(mImage); @@ -224,8 +210,8 @@ public class CoverArtTest { } /** - * Make sure a getImageProperties() yields a set of image properties. The thumbnail format - * MUST be contained in that set + * Make sure a getImageProperties() yields a set of image properties. The thumbnail format MUST + * be contained in that set */ @Test public void testGetImageProperties() { @@ -236,9 +222,7 @@ public class CoverArtTest { assertThat(containsThumbnailFormat(properties)).isTrue(); } - /** - * Make sure a getImage() yield an image in the format you asked for - */ + /** Make sure a getImage() yield an image in the format you asked for */ @Test public void testGetImageWithValidDescriptor() { CoverArt artwork = new CoverArt(mImage); @@ -247,9 +231,7 @@ public class CoverArtTest { assertThat(image).isNotNull(); } - /** - * Make sure a getImage() yields the image in the thumbnail format - */ + /** Make sure a getImage() yields the image in the thumbnail format */ @Test public void testGetImageWithThumbnailDescriptor() { CoverArt artwork = new CoverArt(mImage); @@ -260,9 +242,7 @@ public class CoverArtTest { assertThat(isThumbnailFormat(image)).isTrue(); } - /** - * Make sure a getImage() yields a null - */ + /** Make sure a getImage() yields a null */ @Test public void testGetImageWithInvalidDescriptor() { CoverArt artwork = new CoverArt(mImage); @@ -271,9 +251,7 @@ public class CoverArtTest { assertThat(image).isNull(); } - /** - * Make sure a getImage() yields the native image - */ + /** Make sure a getImage() yields the native image */ @Test public void testGetImageWithoutDescriptor() { CoverArt artwork = new CoverArt(mImage); @@ -282,18 +260,14 @@ public class CoverArtTest { assertThat(Arrays.equals(nativeImage, image)).isTrue(); } - /** - * Make sure we can get a valid string representation of the CoverArt - */ + /** Make sure we can get a valid string representation of the CoverArt */ @Test public void testGetSize() { CoverArt artwork = new CoverArt(mImage); assertThat(artwork.size() > 0).isTrue(); } - /** - * Make sure we can get a valid string representation of the CoverArt - */ + /** Make sure we can get a valid string representation of the CoverArt */ @Test public void testToString() { CoverArt artwork = new CoverArt(mImage); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java index ee6481b1970..016041a284c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java @@ -76,12 +76,12 @@ public class AvrcpBipClientTest { mAdapter = BluetoothAdapter.getDefaultAdapter(); mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); - AvrcpCoverArtManager.Callback callback = (device, event) -> { - }; + AvrcpCoverArtManager.Callback callback = (device, event) -> {}; mArtManager = new AvrcpCoverArtManager(mService, callback); - mClient = new AvrcpBipClient(mTestDevice, TEST_PSM, - mArtManager.new BipClientCallback(mTestDevice)); + mClient = + new AvrcpBipClient( + mTestDevice, TEST_PSM, mArtManager.new BipClientCallback(mTestDevice)); } @After @@ -96,22 +96,26 @@ public class AvrcpBipClientTest { @Test public void constructor() { - AvrcpBipClient client = new AvrcpBipClient(mTestDevice, TEST_PSM, - mArtManager.new BipClientCallback(mTestDevice)); + AvrcpBipClient client = + new AvrcpBipClient( + mTestDevice, TEST_PSM, mArtManager.new BipClientCallback(mTestDevice)); assertThat(client.getL2capPsm()).isEqualTo(TEST_PSM); } @Test public void constructor_withNullDevice() { - assertThrows(NullPointerException.class, () -> new AvrcpBipClient(null, TEST_PSM, - mArtManager.new BipClientCallback(mTestDevice))); + assertThrows( + NullPointerException.class, + () -> + new AvrcpBipClient( + null, TEST_PSM, mArtManager.new BipClientCallback(mTestDevice))); } @Test public void constructor_withNullCallback() { - assertThrows(NullPointerException.class, () -> new AvrcpBipClient(mTestDevice, TEST_PSM, - null)); + assertThrows( + NullPointerException.class, () -> new AvrcpBipClient(mTestDevice, TEST_PSM, null)); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java index 4acc0810f48..e4371d723f8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java @@ -40,8 +40,7 @@ public class AvrcpControllerServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AvrcpControllerService mService; + @Mock private AvrcpControllerService mService; BluetoothDevice mRemoteDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java index cb327ea7a10..5ff2f75fdfe 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java @@ -65,7 +65,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class AvrcpControllerServiceTest { private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00"; - private static final byte[] REMOTE_DEVICE_ADDRESS_AS_ARRAY = new byte[]{0, 0, 0, 0, 0, 0}; + private static final byte[] REMOTE_DEVICE_ADDRESS_AS_ARRAY = new byte[] {0, 0, 0, 0, 0, 0}; private static final String REMOTE_DEVICE_ADDRESS_2 = "11:11:11:11:11:11"; private static final byte[] REMOTE_DEVICE_ADDRESS_AS_ARRAY_2 = new byte[] {11, 11, 11, 11, 11, 11}; @@ -162,8 +162,7 @@ public class AvrcpControllerServiceTest { @Test public void getConnectedDevices() { - when(mAdapterService.getBondedDevices()).thenReturn( - new BluetoothDevice[]{mRemoteDevice}); + when(mAdapterService.getBondedDevices()).thenReturn(new BluetoothDevice[] {mRemoteDevice}); when(mStateMachine.getState()).thenReturn(BluetoothProfile.STATE_CONNECTED); assertThat(mService.getConnectedDevices()).contains(mRemoteDevice); @@ -215,9 +214,9 @@ public class AvrcpControllerServiceTest { } /** - * Pre-conditions: No node in BrowseTree for specified media ID - * Test: Call AvrcpControllerService.getContents() - * Expected Output: BrowseResult object with status ERROR_MEDIA_ID_INVALID + * Pre-conditions: No node in BrowseTree for specified media ID Test: Call + * AvrcpControllerService.getContents() Expected Output: BrowseResult object with status + * ERROR_MEDIA_ID_INVALID */ @Test public void testGetContentsNoNode_returnInvalidMediaIdStatus() { @@ -230,8 +229,8 @@ public class AvrcpControllerServiceTest { /** * Pre-conditions: No device is connected - parent media ID is at the root of the BrowseTree - * Test: Call AvrcpControllerService.getContents() - * Expected Output: BrowseResult object with status NO_DEVICE_CONNECTED + * Test: Call AvrcpControllerService.getContents() Expected Output: BrowseResult object with + * status NO_DEVICE_CONNECTED */ @Test public void getContentsNoDeviceConnected_returnNoDeviceConnectedStatus() { @@ -242,9 +241,8 @@ public class AvrcpControllerServiceTest { } /** - * Pre-conditions: At least one device is connected - * Test: Call AvrcpControllerService.getContents() - * Expected Output: BrowseResult object with status SUCCESS + * Pre-conditions: At least one device is connected Test: Call + * AvrcpControllerService.getContents() Expected Output: BrowseResult object with status SUCCESS */ @Test public void getContentsOneDeviceConnected_returnSuccessStatus() { @@ -256,13 +254,12 @@ public class AvrcpControllerServiceTest { } /** - * Pre-conditions: Node for specified media ID is not cached - * Test: {@link BrowseTree.BrowseNode#getContents} returns {@code null} when the node has no - * children/items and the node is not cached. - * When {@link AvrcpControllerService#getContents} receives a node that is not cached, - * it should interpret the status as `DOWNLOAD_PENDING`. - * Expected Output: BrowseResult object with status DOWNLOAD_PENDING; verify that a download - * request has been sent by checking if mStateMachine.requestContents() is called + * Pre-conditions: Node for specified media ID is not cached Test: {@link + * BrowseTree.BrowseNode#getContents} returns {@code null} when the node has no children/items + * and the node is not cached. When {@link AvrcpControllerService#getContents} receives a node + * that is not cached, it should interpret the status as `DOWNLOAD_PENDING`. Expected Output: + * BrowseResult object with status DOWNLOAD_PENDING; verify that a download request has been + * sent by checking if mStateMachine.requestContents() is called */ @Test public void getContentsNodeNotCached_returnDownloadPendingStatus() { @@ -280,9 +277,8 @@ public class AvrcpControllerServiceTest { } /** - * Pre-conditions: Parent media ID that is not BrowseTree.ROOT; isCached returns true - * Test: Call AvrcpControllerService.getContents() - * Expected Output: BrowseResult object with status SUCCESS + * Pre-conditions: Parent media ID that is not BrowseTree.ROOT; isCached returns true Test: Call + * AvrcpControllerService.getContents() Expected Output: BrowseResult object with status SUCCESS */ @Test public void getContentsNoErrorConditions_returnsSuccessStatus() { @@ -381,8 +377,9 @@ public class AvrcpControllerServiceTest { mService.getRcPsm(mRemoteDevice, psm); - verify(mStateMachine).sendMessage( - AvrcpControllerStateMachine.MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM, psm); + verify(mStateMachine) + .sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM, psm); } @Test @@ -435,8 +432,11 @@ public class AvrcpControllerServiceTest { mService.onPlayPositionChanged(mRemoteDevice, songLen, currSongPos); - verify(mStateMachine).sendMessage( - AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_POS_CHANGED, songLen, currSongPos); + verify(mStateMachine) + .sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_POS_CHANGED, + songLen, + currSongPos); } @Test @@ -445,9 +445,10 @@ public class AvrcpControllerServiceTest { mService.onPlayStatusChanged(mRemoteDevice, status); - verify(mStateMachine).sendMessage( - AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_STATUS_CHANGED, - PlaybackStateCompat.STATE_REWINDING); + verify(mStateMachine) + .sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_STATUS_CHANGED, + PlaybackStateCompat.STATE_REWINDING); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java index e4f9cd82d6d..bd559d901c2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java @@ -96,7 +96,7 @@ public class AvrcpControllerStateMachineTest { private ArgumentCaptor mIntentArgument = ArgumentCaptor.forClass(Intent.class); - private byte[] mTestAddress = new byte[]{01, 01, 01, 01, 01, 01}; + private byte[] mTestAddress = new byte[] {01, 01, 01, 01, 01, 01}; private BluetoothDevice mTestDevice = null; private AvrcpControllerStateMachine mAvrcpStateMachine = null; @@ -121,9 +121,11 @@ public class AvrcpControllerStateMachineTest { when(mMockResources.getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus)) .thenReturn(true); doReturn(mMockResources).when(mAvrcpControllerService).getResources(); - doReturn(mAudioManager).when(mAvrcpControllerService) + doReturn(mAudioManager) + .when(mAvrcpControllerService) .getSystemService(Context.AUDIO_SERVICE); - doReturn(Context.AUDIO_SERVICE).when(mAvrcpControllerService) + doReturn(Context.AUDIO_SERVICE) + .when(mAvrcpControllerService) .getSystemServiceName(AudioManager.class); doReturn(mCoverArtManager).when(mAvrcpControllerService).getCoverArtManager(); mAvrcpControllerService.sBrowseTree = new BrowseTree(null); @@ -155,9 +157,7 @@ public class AvrcpControllerStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Create a state machine to test - */ + /** Create a state machine to test */ private AvrcpControllerStateMachine makeStateMachine(BluetoothDevice device) { AvrcpControllerStateMachine sm = new AvrcpControllerStateMachine( @@ -166,9 +166,7 @@ public class AvrcpControllerStateMachineTest { return sm; } - /** - * Destroy a state machine you created to test - */ + /** Destroy a state machine you created to test */ private void destroyStateMachine(AvrcpControllerStateMachine sm) { if (sm == null || sm.getState() == BluetoothProfile.STATE_DISCONNECTED) return; @@ -182,9 +180,7 @@ public class AvrcpControllerStateMachineTest { verify(mAvrcpControllerService).removeStateMachine(eq(sm)); } - /** - * Set up which device the AvrcpControllerService will report as active - */ + /** Set up which device the AvrcpControllerService will report as active */ private void setActiveDevice(BluetoothDevice device) { doReturn(device).when(mAvrcpControllerService).getActiveDevice(); if (mTestDevice.equals(device)) { @@ -195,13 +191,10 @@ public class AvrcpControllerStateMachineTest { } } - /** - * Send an audio focus changed event to the state machine under test - */ + /** Send an audio focus changed event to the state machine under test */ private void sendAudioFocusUpdate(int state) { when(mA2dpSinkService.getFocusState()).thenReturn(state); - mAvrcpStateMachine.sendMessage( - AvrcpControllerStateMachine.AUDIO_FOCUS_STATE_CHANGE, state); + mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.AUDIO_FOCUS_STATE_CHANGE, state); } /** @@ -211,24 +204,32 @@ public class AvrcpControllerStateMachineTest { */ private int setUpConnectedState(boolean control, boolean browsing) { - Assert.assertThat(mAvrcpStateMachine.getCurrentState(), + Assert.assertThat( + mAvrcpStateMachine.getCurrentState(), IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); mAvrcpStateMachine.connect(StackEvent.connectionStateChanged(control, browsing)); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); - verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcast( - mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertThat(mAvrcpStateMachine.getCurrentState(), + verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcast(mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + Assert.assertThat( + mAvrcpStateMachine.getCurrentState(), IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Connected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_CONNECTED); return BluetoothProfile.STATE_CONNECTED; } - private AvrcpItem makeTrack(String title, String artist, String album, long trackNum, - long totalTracks, String genre, long duration, String imageHandle) { + private AvrcpItem makeTrack( + String title, + String artist, + String album, + long trackNum, + long totalTracks, + String genre, + long duration, + String imageHandle) { AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.setItemType(AvrcpItem.TYPE_MEDIA); builder.setType(AvrcpItem.MEDIA_AUDIO); @@ -267,37 +268,30 @@ public class AvrcpControllerStateMachineTest { } /** - * Send a message to the state machine that the track has changed. Must be connected to - * do this. + * Send a message to the state machine that the track has changed. Must be connected to do this. */ private void setCurrentTrack(AvrcpItem track) { - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED, - track); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED, track); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); Assert.assertEquals(mAvrcpStateMachine.getCurrentTrack(), track); } - /** - * Set the current play status (Play, Pause, etc.) of the device - */ + /** Set the current play status (Play, Pause, etc.) of the device */ private void setPlaybackState(int state) { mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_STATUS_CHANGED, state); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); } - /** - * Set the current playback position of the device - */ + /** Set the current playback position of the device */ private void setPlaybackPosition(int position, int duration) { mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_POS_CHANGED, duration, position); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); } - /** - * Make an AvrcpItem suitable for being included in the Now Playing list for the test device - */ + /** Make an AvrcpItem suitable for being included in the Now Playing list for the test device */ private AvrcpItem makeNowPlayingItem(long uid, String name) { AvrcpItem.Builder aib = new AvrcpItem.Builder(); aib.setDevice(mTestDevice); @@ -310,9 +304,7 @@ public class AvrcpControllerStateMachineTest { return aib.build(); } - /** - * Get the current Now Playing list for the test device - */ + /** Get the current Now Playing list for the test device */ private List getNowPlayingList() { BrowseTree.BrowseNode nowPlaying = mAvrcpStateMachine.findNode("NOW_PLAYING"); List nowPlayingList = new ArrayList(); @@ -322,9 +314,7 @@ public class AvrcpControllerStateMachineTest { return nowPlayingList; } - /** - * Set the current Now Playing list for the test device - */ + /** Set the current Now Playing list for the test device */ private void setNowPlayingList(List nowPlayingList) { BrowseTree.BrowseNode nowPlaying = mAvrcpStateMachine.findNode("NOW_PLAYING"); mAvrcpStateMachine.requestContents(nowPlaying); @@ -356,13 +346,14 @@ public class AvrcpControllerStateMachineTest { return s.toString(); } - /** - * Assert that the Now Playing list is a particular value - */ + /** Assert that the Now Playing list is a particular value */ private void assertNowPlayingList(List expected) { List current = getNowPlayingList(); - String err = "Now playing list incorrect, expected=" - + avrcpItemListToString(expected) + ", actual=" + avrcpItemListToString(current); + String err = + "Now playing list incorrect, expected=" + + avrcpItemListToString(expected) + + ", actual=" + + avrcpItemListToString(current); Assert.assertEquals(err, expected.size(), current.size()); for (int i = 0; i < expected.size(); i++) { Assert.assertEquals(err, expected.get(i), current.get(i)); @@ -370,8 +361,8 @@ public class AvrcpControllerStateMachineTest { } /** - * Test to confirm that the state machine is capable of cycling through the 4 - * connection states, and that upon completion, it cleans up afterwards. + * Test to confirm that the state machine is capable of cycling through the 4 connection states, + * and that upon completion, it cleans up afterwards. */ @Test public void testDisconnect() { @@ -380,9 +371,9 @@ public class AvrcpControllerStateMachineTest { } /** - * Test to confirm that the state machine is capable of cycling through the 4 - * connection states with no crashes, even if the {@link AvrcpControllerService} is stopped and - * the {@code sBrowseTree} is null. This could happen if BT is disabled as the profile is being + * Test to confirm that the state machine is capable of cycling through the 4 connection states + * with no crashes, even if the {@link AvrcpControllerService} is stopped and the {@code + * sBrowseTree} is null. This could happen if BT is disabled as the profile is being * disconnected. */ @Test @@ -396,75 +387,79 @@ public class AvrcpControllerStateMachineTest { private void testDisconnectInternal(int numBroadcastsSent) { mAvrcpStateMachine.disconnect(); numBroadcastsSent += 2; - verify(mAvrcpControllerService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcast( - mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertEquals(mTestDevice, mIntentArgument.getValue().getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED, + verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcast(mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + Assert.assertEquals( + mTestDevice, + mIntentArgument.getValue().getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); + Assert.assertEquals( + BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED, mIntentArgument.getValue().getAction()); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mAvrcpStateMachine.getCurrentState(), + Assert.assertThat( + mAvrcpStateMachine.getCurrentState(), IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_DISCONNECTED); verify(mAvrcpControllerService).removeStateMachine(eq(mAvrcpStateMachine)); } - /** - * Test to confirm that a control only device can be established (no browsing) - */ + /** Test to confirm that a control only device can be established (no browsing) */ @Test public void testControlOnly() { int numBroadcastsSent = setUpConnectedState(true, false); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); Assert.assertNotNull(transportControls); - Assert.assertEquals(PlaybackStateCompat.STATE_NONE, + Assert.assertEquals( + PlaybackStateCompat.STATE_NONE, BluetoothMediaBrowserService.getPlaybackState().getState()); mAvrcpStateMachine.disconnect(); numBroadcastsSent += 2; - verify(mAvrcpControllerService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcast( - mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertEquals(mTestDevice, mIntentArgument.getValue().getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED, + verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcast(mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + Assert.assertEquals( + mTestDevice, + mIntentArgument.getValue().getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); + Assert.assertEquals( + BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED, mIntentArgument.getValue().getAction()); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mAvrcpStateMachine.getCurrentState(), + Assert.assertThat( + mAvrcpStateMachine.getCurrentState(), IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_DISCONNECTED); verify(mAvrcpControllerService).removeStateMachine(eq(mAvrcpStateMachine)); } - /** - * Test to confirm that a browsing only device can be established (no control) - */ + /** Test to confirm that a browsing only device can be established (no control) */ @Test @FlakyTest public void testBrowsingOnly() { Assert.assertEquals(0, mAvrcpControllerService.sBrowseTree.mRootNode.getChildrenCount()); int numBroadcastsSent = setUpConnectedState(false, true); Assert.assertEquals(1, mAvrcpControllerService.sBrowseTree.mRootNode.getChildrenCount()); - Assert.assertEquals(PlaybackStateCompat.STATE_NONE, + Assert.assertEquals( + PlaybackStateCompat.STATE_NONE, BluetoothMediaBrowserService.getPlaybackState().getState()); mAvrcpStateMachine.disconnect(); numBroadcastsSent += 2; - verify(mAvrcpControllerService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcast( - mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertEquals(mTestDevice, mIntentArgument.getValue().getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED, + verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcast(mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + Assert.assertEquals( + mTestDevice, + mIntentArgument.getValue().getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); + Assert.assertEquals( + BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED, mIntentArgument.getValue().getAction()); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mAvrcpStateMachine.getCurrentState(), + Assert.assertThat( + mAvrcpStateMachine.getCurrentState(), IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_DISCONNECTED); verify(mAvrcpControllerService).removeStateMachine(eq(mAvrcpStateMachine)); @@ -496,17 +491,13 @@ public class AvrcpControllerStateMachineTest { assertThat((results.getID()).substring(UUID_START, UUID_LENGTH)).isEqualTo(rootName); } - /** - * Test to make sure the state machine is tracking the correct device - */ + /** Test to make sure the state machine is tracking the correct device */ @Test public void testGetDevice() { Assert.assertEquals(mAvrcpStateMachine.getDevice(), mTestDevice); } - /** - * Test that dumpsys will generate information about connected devices - */ + /** Test that dumpsys will generate information about connected devices */ @Test public void testDump() { StringBuilder sb = new StringBuilder(); @@ -514,16 +505,14 @@ public class AvrcpControllerStateMachineTest { Assert.assertNotNull(sb.toString()); } - /** - * Test media browser play command - */ + /** Test media browser play command */ @Test public void testPlay() throws Exception { setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Play + // Play transportControls.play(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -537,16 +526,14 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser pause command - */ + /** Test media browser pause command */ @Test public void testPause() throws Exception { setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Pause + // Pause transportControls.pause(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -560,16 +547,14 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser stop command - */ + /** Test media browser stop command */ @Test public void testStop() throws Exception { setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Stop + // Stop transportControls.stop(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -583,16 +568,14 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser next command - */ + /** Test media browser next command */ @Test public void testNext() throws Exception { setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Next + // Next transportControls.skipToNext(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -606,16 +589,14 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser previous command - */ + /** Test media browser previous command */ @Test public void testPrevious() throws Exception { setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Previous + // Previous transportControls.skipToPrevious(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -629,9 +610,7 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser fast forward command - */ + /** Test media browser fast forward command */ @Test @FlakyTest public void testFastForward() throws Exception { @@ -639,14 +618,14 @@ public class AvrcpControllerStateMachineTest { MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //FastForward + // FastForward transportControls.fastForward(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_FF), eq(KEY_DOWN)); - //Finish FastForwarding + // Finish FastForwarding transportControls.play(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -655,23 +634,21 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser rewind command - */ + /** Test media browser rewind command */ @Test public void testRewind() throws Exception { setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Rewind + // Rewind transportControls.rewind(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_REWIND), eq(KEY_DOWN)); - //Finish Rewinding + // Finish Rewinding transportControls.play(); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .sendPassThroughCommand( @@ -680,9 +657,7 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test media browser skip to queue item - */ + /** Test media browser skip to queue item */ @Test public void testSkipToQueueInvalid() throws Exception { byte scope = 1; @@ -692,49 +667,45 @@ public class AvrcpControllerStateMachineTest { MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Play an invalid item below start + // Play an invalid item below start transportControls.skipToQueueItem(minSize - 1); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(0)) .playItem(eq(mTestAddress), eq(scope), anyLong(), anyInt()); - //Play an invalid item beyond end + // Play an invalid item beyond end transportControls.skipToQueueItem(maxSize + 1); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(0)) .playItem(eq(mTestAddress), eq(scope), anyLong(), anyInt()); } - /** - * Test media browser shuffle command - */ + /** Test media browser shuffle command */ @Test public void testShuffle() throws Exception { - byte[] shuffleSetting = new byte[]{3}; - byte[] shuffleMode = new byte[]{2}; + byte[] shuffleSetting = new byte[] {3}; + byte[] shuffleMode = new byte[] {2}; setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Shuffle + // Shuffle transportControls.setShuffleMode(1); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .setPlayerApplicationSettingValues( eq(mTestAddress), eq((byte) 1), eq(shuffleSetting), eq(shuffleMode)); } - /** - * Test media browser repeat command - */ + /** Test media browser repeat command */ @Test public void testRepeat() throws Exception { - byte[] repeatSetting = new byte[]{2}; - byte[] repeatMode = new byte[]{3}; + byte[] repeatSetting = new byte[] {2}; + byte[] repeatMode = new byte[] {3}; setUpConnectedState(true, true); MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); - //Shuffle + // Shuffle transportControls.setRepeatMode(2); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .setPlayerApplicationSettingValues( @@ -742,10 +713,9 @@ public class AvrcpControllerStateMachineTest { } /** - * Test media browsing - * Verify that a browse tree is created with the proper root - * Verify that a player can be fetched and added to the browse tree - * Verify that the contents of a player are fetched upon request + * Test media browsing Verify that a browse tree is created with the proper root Verify that a + * player can be fetched and added to the browse tree Verify that the contents of a player are + * fetched upon request */ @Test @FlakyTest @@ -754,31 +724,32 @@ public class AvrcpControllerStateMachineTest { final String playerName = "Player 1"; BrowseTree.BrowseNode results = mAvrcpStateMachine.mBrowseTree.mRootNode; - //Request fetch the list of players + // Request fetch the list of players BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(results.getID()); mAvrcpStateMachine.requestContents(results); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .getPlayerList(eq(mTestAddress), eq(0), eq(19)); - //Provide back a player object + // Provide back a player object byte[] playerFeatures = - new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; + new byte[] {0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; AvrcpPlayer playerOne = makePlayer(mTestDevice, 1, playerName, playerFeatures, 1); List testPlayers = new ArrayList<>(); testPlayers.add(playerOne); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, - testPlayers); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); - //Verify that the player object is available. + // Verify that the player object is available. playerNodes = mAvrcpStateMachine.findNode(results.getID()); Assert.assertEquals(true, results.isCached()); - Assert.assertEquals("MediaItem{mFlags=1, mDescription=" + playerName + ", null, null}", + Assert.assertEquals( + "MediaItem{mFlags=1, mDescription=" + playerName + ", null, null}", results.getChildren().get(0).getMediaItem().toString()); - //Fetch contents of that player object - BrowseTree.BrowseNode playerOneNode = mAvrcpStateMachine.findNode( - results.getChildren().get(0).getID()); + // Fetch contents of that player object + BrowseTree.BrowseNode playerOneNode = + mAvrcpStateMachine.findNode(results.getChildren().get(0).getID()); mAvrcpStateMachine.requestContents(playerOneNode); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .setBrowsedPlayer(eq(mTestAddress), eq(1)); @@ -790,7 +761,7 @@ public class AvrcpControllerStateMachineTest { /** * Test our reaction to an available players changed event * - * Verify that we issue a command to fetch the new available players + *

Verify that we issue a command to fetch the new available players */ @Test public void testAvailablePlayersChanged() { @@ -807,8 +778,8 @@ public class AvrcpControllerStateMachineTest { } /** - * Test how we handle receiving an available players list that contains the player we know to - * be the addressed player + * Test how we handle receiving an available players list that contains the player we know to be + * the addressed player */ @Test public void testAvailablePlayersReceived_AddressedPlayerExists() { @@ -836,14 +807,14 @@ public class AvrcpControllerStateMachineTest { // Send available players set that contains our addressed player byte[] playerFeatures = - new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; + new byte[] {0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; AvrcpPlayer playerOne = makePlayer(mTestDevice, 1, "Player 1", playerFeatures, 1); AvrcpPlayer playerTwo = makePlayer(mTestDevice, 2, "Player 2", playerFeatures, 1); List testPlayers = new ArrayList<>(); testPlayers.add(playerOne); testPlayers.add(playerTwo); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, - testPlayers); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers); // Wait for them to be processed TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); @@ -887,14 +858,14 @@ public class AvrcpControllerStateMachineTest { // Send available players set that does not contain the addressed player byte[] playerFeatures = - new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; + new byte[] {0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; AvrcpPlayer playerOne = makePlayer(mTestDevice, 1, "Player 1", playerFeatures, 1); AvrcpPlayer playerTwo = makePlayer(mTestDevice, 2, "Player 2", playerFeatures, 1); List testPlayers = new ArrayList<>(); testPlayers.add(playerOne); testPlayers.add(playerTwo); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, - testPlayers); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers); // Wait for them to be processed TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); @@ -921,8 +892,8 @@ public class AvrcpControllerStateMachineTest { } /** - * Test addressed media player changing to a player we know about - * Verify when the addressed media player changes browsing data updates + * Test addressed media player changing to a player we know about Verify when the addressed + * media player changes browsing data updates */ @Test public void testAddressedPlayerChangedToNewKnownPlayer() { @@ -930,24 +901,24 @@ public class AvrcpControllerStateMachineTest { // Get the root of the device BrowseTree.BrowseNode results = mAvrcpStateMachine.mBrowseTree.mRootNode; - //Request fetch the list of players + // Request fetch the list of players BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(results.getID()); mAvrcpStateMachine.requestContents(results); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .getPlayerList(eq(mTestAddress), eq(0), eq(19)); - //Provide back two player objects, IDs 1 and 2 + // Provide back two player objects, IDs 1 and 2 byte[] playerFeatures = - new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; + new byte[] {0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; AvrcpPlayer playerOne = makePlayer(mTestDevice, 1, "Player 1", playerFeatures, 1); AvrcpPlayer playerTwo = makePlayer(mTestDevice, 2, "Player 2", playerFeatures, 1); List testPlayers = new ArrayList<>(); testPlayers.add(playerOne); testPlayers.add(playerTwo); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, - testPlayers); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers); - //Set something arbitrary for the current Now Playing list + // Set something arbitrary for the current Now Playing list List nowPlayingList = new ArrayList(); nowPlayingList.add(makeNowPlayingItem(1, "Song 1")); nowPlayingList.add(makeNowPlayingItem(2, "Song 2")); @@ -955,7 +926,7 @@ public class AvrcpControllerStateMachineTest { clearInvocations(mAvrcpControllerService); clearInvocations(mNativeInterface); - //Change players and verify that BT attempts to update the results + // Change players and verify that BT attempts to update the results mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 2); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); @@ -965,7 +936,7 @@ public class AvrcpControllerStateMachineTest { SparseArray players = mAvrcpStateMachine.getAvailablePlayers(); Assert.assertTrue(players.contains(mAvrcpStateMachine.getAddressedPlayerId())); - //Make sure the Now Playing list is now cleared + // Make sure the Now Playing list is now cleared assertNowPlayingList(new ArrayList()); // Verify that a player change to a player with Now Playing support causes a refresh. @@ -980,9 +951,9 @@ public class AvrcpControllerStateMachineTest { } /** - * Test addressed media player change to a player we don't know about - * Verify when the addressed media player changes browsing data updates - * Verify that the contents of a player are fetched upon request + * Test addressed media player change to a player we don't know about Verify when the addressed + * media player changes browsing data updates Verify that the contents of a player are fetched + * upon request */ @Test public void testAddressedPlayerChangedToUnknownPlayer() { @@ -991,31 +962,31 @@ public class AvrcpControllerStateMachineTest { // Get the root of the device BrowseTree.BrowseNode rootNode = mAvrcpStateMachine.mBrowseTree.mRootNode; - //Request fetch the list of players + // Request fetch the list of players BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(rootNode.getID()); mAvrcpStateMachine.requestContents(rootNode); - //Provide back a player object + // Provide back a player object byte[] playerFeatures = - new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; + new byte[] {0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; AvrcpPlayer playerOne = makePlayer(mTestDevice, 1, "Player 1", playerFeatures, 1); List testPlayers = new ArrayList<>(); testPlayers.add(playerOne); mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers); - //Set something arbitrary for the current Now Playing list + // Set something arbitrary for the current Now Playing list List nowPlayingList = new ArrayList(); nowPlayingList.add(makeNowPlayingItem(1, "Song 1")); nowPlayingList.add(makeNowPlayingItem(2, "Song 2")); setNowPlayingList(nowPlayingList); - //Change players + // Change players mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 4); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); - //Make sure the Now Playing list is now cleared and we requested metadata + // Make sure the Now Playing list is now cleared and we requested metadata assertNowPlayingList(new ArrayList()); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .getCurrentMetadata(eq(mTestAddress)); @@ -1027,7 +998,7 @@ public class AvrcpControllerStateMachineTest { * Test what we do when we receive an addressed player change to a player with the same ID as * the current addressed play. * - * Verify we assume nothing and re-fetch the current metadata and playback status. + *

Verify we assume nothing and re-fetch the current metadata and playback status. */ @Test public void testAddressedPlayerChangedToSamePlayerId() { @@ -1046,20 +1017,20 @@ public class AvrcpControllerStateMachineTest { // Get the root of the device BrowseTree.BrowseNode rootNode = mAvrcpStateMachine.mBrowseTree.mRootNode; - //Request fetch the list of players + // Request fetch the list of players BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(rootNode.getID()); mAvrcpStateMachine.requestContents(rootNode); // Send available players set that contains our addressed player byte[] playerFeatures = - new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; + new byte[] {0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0}; AvrcpPlayer playerOne = makePlayer(mTestDevice, 1, "Player 1", playerFeatures, 1); AvrcpPlayer playerTwo = makePlayer(mTestDevice, 2, "Player 2", playerFeatures, 1); List testPlayers = new ArrayList<>(); testPlayers.add(playerOne); testPlayers.add(playerTwo); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, - testPlayers); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers); // Wait until idle so Now Playing List is queried for again, resolve it again TestUtils.waitForLooperToBeIdle(mAvrcpStateMachine.getHandler().getLooper()); @@ -1084,9 +1055,7 @@ public class AvrcpControllerStateMachineTest { .getPlaybackState(eq(mTestAddress)); } - /** - * Test that the Now Playing playlist is updated when it changes. - */ + /** Test that the Now Playing playlist is updated when it changes. */ @Test public void testNowPlaying() { setUpConnectedState(true, true); @@ -1095,9 +1064,7 @@ public class AvrcpControllerStateMachineTest { .getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); } - /** - * Test that AVRCP events such as playback commands can execute while performing browsing. - */ + /** Test that AVRCP events such as playback commands can execute while performing browsing. */ @Test public void testPlayWhileBrowsing() { setUpConnectedState(true, true); @@ -1106,7 +1073,7 @@ public class AvrcpControllerStateMachineTest { // Get the root of the device BrowseTree.BrowseNode results = mAvrcpStateMachine.mBrowseTree.mRootNode; - //Request fetch the list of players + // Request fetch the list of players BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(results.getID()); mAvrcpStateMachine.requestContents(results); @@ -1125,9 +1092,7 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test that Absolute Volume Registration is working - */ + /** Test that Absolute Volume Registration is working */ @Test public void testRegisterAbsVolumeNotification() { byte label = 42; @@ -1187,9 +1152,7 @@ public class AvrcpControllerStateMachineTest { .sendAbsVolRsp(any(), eq(127), eq((int) label)); } - /** - * Test playback does not request focus when another app is playing music. - */ + /** Test playback does not request focus when another app is playing music. */ @Test public void testPlaybackWhileMusicPlaying() { when(mMockResources.getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus)) @@ -1209,9 +1172,7 @@ public class AvrcpControllerStateMachineTest { verify(mA2dpSinkService, never()).requestAudioFocus(mTestDevice, true); } - /** - * Test playback requests focus while nothing is playing music. - */ + /** Test playback requests focus while nothing is playing music. */ @Test public void testPlaybackWhileIdle() { when(mA2dpSinkService.getFocusState()).thenReturn(AudioManager.AUDIOFOCUS_NONE); @@ -1225,10 +1186,10 @@ public class AvrcpControllerStateMachineTest { } /** - * Test receiving a playback status of playing while we're in an error state - * as it relates to getting audio focus. + * Test receiving a playback status of playing while we're in an error state as it relates to + * getting audio focus. * - * Verify we send a pause command and never attempt to request audio focus + *

Verify we send a pause command and never attempt to request audio focus */ @Test public void testPlaybackWhileErrorState() { @@ -1249,7 +1210,7 @@ public class AvrcpControllerStateMachineTest { /** * Test receiving a playback status of playing while we have focus * - * Verify we do not send a pause command and never attempt to request audio focus + *

Verify we do not send a pause command and never attempt to request audio focus */ @Test public void testPlaybackWhilePlayingState() { @@ -1268,26 +1229,20 @@ public class AvrcpControllerStateMachineTest { verify(mA2dpSinkService, never()).requestAudioFocus(mTestDevice, true); } - /** - * Test that isActive() reports the proper value when we're active - */ + /** Test that isActive() reports the proper value when we're active */ @Test public void testIsActive_deviceActive() { Assert.assertTrue(mAvrcpStateMachine.isActive()); } - /** - * Test that isActive() reports the proper value when we're inactive - */ + /** Test that isActive() reports the proper value when we're inactive */ @Test public void testIsActive_deviceInactive() { setActiveDevice(null); Assert.assertFalse(mAvrcpStateMachine.isActive()); } - /** - * Test becoming active from the inactive state - */ + /** Test becoming active from the inactive state */ @Test public void testBecomeActive() { // Note device starts as active in setUp() and state cascades come the CONNECTED state @@ -1344,9 +1299,7 @@ public class AvrcpControllerStateMachineTest { Assert.assertEquals("title 2", queue.get(1).getDescription().getTitle().toString()); } - /** - * Test becoming inactive from the active state - */ + /** Test becoming inactive from the active state */ @Test public void testBecomeInactive() { // Note device starts as active in setUp() @@ -1428,9 +1381,7 @@ public class AvrcpControllerStateMachineTest { Assert.assertEquals(1, playbackState.getActiveQueueItemId()); } - /** - * Test receiving a track change update when we're not the active device - */ + /** Test receiving a track change update when we're not the active device */ @Test public void testTrackChangeWhileNotActiveDevice() { setUpConnectedState(true, true); @@ -1455,9 +1406,7 @@ public class AvrcpControllerStateMachineTest { Assert.assertNull(metadata); // track starts as null and shouldn't change } - /** - * Test receiving a playback status of playing when we're not the active device - */ + /** Test receiving a playback status of playing when we're not the active device */ @Test public void testPlaybackWhileNotActiveDevice() { setUpConnectedState(true, true); @@ -1480,13 +1429,12 @@ public class AvrcpControllerStateMachineTest { eq(AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE), eq(KEY_DOWN)); verify(mA2dpSinkService, never()).requestAudioFocus(mTestDevice, true); - Assert.assertEquals(PlaybackStateCompat.STATE_ERROR, + Assert.assertEquals( + PlaybackStateCompat.STATE_ERROR, BluetoothMediaBrowserService.getPlaybackState().getState()); } - /** - * Test receiving a play position update when we're not the active device - */ + /** Test receiving a play position update when we're not the active device */ @Test public void testPlayPositionChangeWhileNotActiveDevice() { setUpConnectedState(true, true); @@ -1512,9 +1460,7 @@ public class AvrcpControllerStateMachineTest { Assert.assertEquals(0, playbackState.getPosition()); } - /** - * Test receiving a now playing list update when we're not the active device - */ + /** Test receiving a now playing list update when we're not the active device */ @Test public void testNowPlayingListChangeWhileNotActiveDevice() { setUpConnectedState(true, true); @@ -1616,9 +1562,7 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test receiving an audio focus loss event. A pause should be sent if we were playing - */ + /** Test receiving an audio focus loss event. A pause should be sent if we were playing */ @Test public void testOnAudioFocusLossWhilePlaying_pauseSent() { setUpConnectedState(true, true); @@ -1639,9 +1583,7 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test receiving an audio focus loss event. A pause should not be sent if we were paused - */ + /** Test receiving an audio focus loss event. A pause should not be sent if we were paused */ @Test public void testOnAudioFocusLossWhilePause_pauseNotSent() { setUpConnectedState(true, true); @@ -1687,9 +1629,7 @@ public class AvrcpControllerStateMachineTest { eq(KEY_UP)); } - /** - * Test receiving an audio focus changed event following a transient loss where - */ + /** Test receiving an audio focus changed event following a transient loss where */ @Test public void testOnAudioFocusGainFromTransientLossWhilePlayingWithPause_playNotSent() { testOnAudioFocusTransientLossWhilePlaying_pauseSent(); @@ -1822,7 +1762,8 @@ public class AvrcpControllerStateMachineTest { // Verify download attempt and send some elements over, verify next set is requested verify(mNativeInterface, times(1)).getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(nowPlayingList.subList(0, 20))); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); verify(mNativeInterface, times(1)).getNowPlayingList(eq(mTestAddress), eq(20), eq(39)); @@ -1833,15 +1774,18 @@ public class AvrcpControllerStateMachineTest { // Send requested items, they're likely from the new list at this point, but it shouldn't // matter what they are because we should toss them out and restart our download next. - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(nowPlayingList.subList(20, 25))); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); verify(mNativeInterface, times(2)).getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(0, 20))); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(20, 25))); mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE); @@ -1887,7 +1831,8 @@ public class AvrcpControllerStateMachineTest { verify(mNativeInterface, times(1)).getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); mAvrcpStateMachine.nowPlayingContentChanged(); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(nowPlayingList.subList(0, 20))); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); @@ -1896,9 +1841,11 @@ public class AvrcpControllerStateMachineTest { verify(mNativeInterface, times(2)).getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); // Send whole list - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(0, 20))); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(20, 25))); mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE); @@ -1942,7 +1889,8 @@ public class AvrcpControllerStateMachineTest { // Verify download attempt and send some elements over, verify next set is requested verify(mNativeInterface, times(1)).getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(nowPlayingList.subList(0, 20))); TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); verify(mNativeInterface, times(1)).getNowPlayingList(eq(mTestAddress), eq(20), eq(39)); @@ -1954,15 +1902,18 @@ public class AvrcpControllerStateMachineTest { // Send requested items, they're likely from the new list at this point, but it shouldn't // matter what they are because we should toss them out and restart our download next. - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(nowPlayingList.subList(20, 25))); TestUtils.waitForLooperToBeIdle(mAvrcpStateMachine.getHandler().getLooper()); verify(mNativeInterface, times(2)).getNowPlayingList(eq(mTestAddress), eq(0), eq(19)); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(0, 20))); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(20, 25))); mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE); @@ -2014,7 +1965,8 @@ public class AvrcpControllerStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); // Now, send the items in and let it process - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(nowPlayingList.subList(0, 20))); TestUtils.waitForLooperToBeIdle(mAvrcpStateMachine.getHandler().getLooper()); @@ -2022,9 +1974,11 @@ public class AvrcpControllerStateMachineTest { // Send requested items, they're likely from the new list at this point, but it shouldn't // matter what they are because we should toss them out and restart our download next. - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(0, 20))); - mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, new ArrayList(updatedNowPlayingList.subList(20, 25))); mAvrcpStateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE); @@ -2047,7 +2001,7 @@ public class AvrcpControllerStateMachineTest { setUpConnectedState(true, true); sendAudioFocusUpdate(AudioManager.AUDIOFOCUS_GAIN); - //Set something arbitrary for the current Now Playing list + // Set something arbitrary for the current Now Playing list List nowPlayingList = new ArrayList(); nowPlayingList.add(makeNowPlayingItem(1, "Song 1")); setNowPlayingList(nowPlayingList); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java index ddddbd08fe2..7514f3a5215 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java @@ -48,14 +48,13 @@ import java.io.FileNotFoundException; public class AvrcpCoverArtProviderTest { private static final String TEST_MODE = "test_mode"; - private final byte[] mTestAddress = new byte[]{01, 01, 01, 01, 01, 01}; + private final byte[] mTestAddress = new byte[] {01, 01, 01, 01, 01, 01}; private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice = null; private AvrcpCoverArtProvider mArtProvider; - @Rule - public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private Uri mUri; @@ -111,8 +110,12 @@ public class AvrcpCoverArtProviderTest { @Test public void getImageUri_withValidImageUuid() { String uuid = "1111"; - Uri expectedUri = AvrcpCoverArtProvider.CONTENT_URI.buildUpon().appendQueryParameter( - "device", mTestDevice.getAddress()).appendQueryParameter("uuid", uuid).build(); + Uri expectedUri = + AvrcpCoverArtProvider.CONTENT_URI + .buildUpon() + .appendQueryParameter("device", mTestDevice.getAddress()) + .appendQueryParameter("uuid", uuid) + .build(); assertThat(AvrcpCoverArtProvider.getImageUri(mTestDevice, uuid)).isEqualTo(expectedUri); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java index 903a4277d94..f11054f05ca 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java @@ -37,9 +37,7 @@ import org.junit.runner.RunWith; import java.io.InputStream; -/** - * A test suite for the AvrcpCoverArtStorage class. - */ +/** A test suite for the AvrcpCoverArtStorage class. */ @RunWith(AndroidJUnit4.class) public final class AvrcpCoverArtStorageTest { private Context mTargetContext; @@ -58,11 +56,11 @@ public final class AvrcpCoverArtStorageTest { mTestResources = TestUtils.getTestApplicationResources(mTargetContext); mDevice1 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("AA:BB:CC:DD:EE:FF"); mDevice2 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("BB:CC:DD:EE:FF:AA"); - InputStream is = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_200_200); + InputStream is = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_200_200); mImage1 = BitmapFactory.decodeStream(is); - InputStream is2 = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_600_600); + InputStream is2 = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_600_600); mImage2 = BitmapFactory.decodeStream(is2); mAvrcpCoverArtStorage = new AvrcpCoverArtStorage(mTargetContext); @@ -332,8 +330,15 @@ public final class AvrcpCoverArtStorageTest { @Test public void toString_returnsDeviceInfo() { String expectedString = - "CoverArtStorage:\n" + " " + mDevice1 + " (" + 1 + "):" + "\n " - + mHandle1 + "\n"; + "CoverArtStorage:\n" + + " " + + mDevice1 + + " (" + + 1 + + "):" + + "\n " + + mHandle1 + + "\n"; mAvrcpCoverArtStorage.addImage(mDevice1, mHandle1, mImage1); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java index a3f0715021e..55257a5365e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java @@ -33,16 +33,14 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -/** - * A test suite for the AvrcpItem class. - */ +/** A test suite for the AvrcpItem class. */ @RunWith(AndroidJUnit4.class) public final class AvrcpItemTest { private BluetoothDevice mDevice; private static final String UUID = "AVRCP-ITEM-TEST-UUID"; - // Attribute ID Values from AVRCP Specification + // Attribute ID Values from AVRCP Specification private static final int MEDIA_ATTRIBUTE_TITLE = 0x01; private static final int MEDIA_ATTRIBUTE_ARTIST_NAME = 0x02; private static final int MEDIA_ATTRIBUTE_ALBUM_NAME = 0x03; @@ -121,27 +119,22 @@ public final class AvrcpItemTest { String playingTime = "301"; String artHandle = "0000001"; - int[] attrIds = new int[]{ - MEDIA_ATTRIBUTE_TITLE, - MEDIA_ATTRIBUTE_ARTIST_NAME, - MEDIA_ATTRIBUTE_ALBUM_NAME, - MEDIA_ATTRIBUTE_TRACK_NUMBER, - MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, - MEDIA_ATTRIBUTE_GENRE, - MEDIA_ATTRIBUTE_PLAYING_TIME, - MEDIA_ATTRIBUTE_COVER_ART_HANDLE - }; - - String[] attrMap = new String[]{ - title, - artist, - album, - trackNumber, - totalTracks, - genre, - playingTime, - artHandle - }; + int[] attrIds = + new int[] { + MEDIA_ATTRIBUTE_TITLE, + MEDIA_ATTRIBUTE_ARTIST_NAME, + MEDIA_ATTRIBUTE_ALBUM_NAME, + MEDIA_ATTRIBUTE_TRACK_NUMBER, + MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, + MEDIA_ATTRIBUTE_GENRE, + MEDIA_ATTRIBUTE_PLAYING_TIME, + MEDIA_ATTRIBUTE_COVER_ART_HANDLE + }; + + String[] attrMap = + new String[] { + title, artist, album, trackNumber, totalTracks, genre, playingTime, artHandle + }; AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.fromAvrcpAttributeArray(attrIds, attrMap); @@ -173,35 +166,37 @@ public final class AvrcpItemTest { String playingTime = "301"; String artHandle = "0000001"; - int[] attrIds = new int[]{ - MEDIA_ATTRIBUTE_TITLE, - MEDIA_ATTRIBUTE_ARTIST_NAME, - MEDIA_ATTRIBUTE_ALBUM_NAME, - MEDIA_ATTRIBUTE_TRACK_NUMBER, - MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, - MEDIA_ATTRIBUTE_GENRE, - MEDIA_ATTRIBUTE_PLAYING_TIME, - MEDIA_ATTRIBUTE_COVER_ART_HANDLE, - 75, - 76, - 77, - 78 - }; - - String[] attrMap = new String[]{ - title, - artist, - album, - trackNumber, - totalTracks, - genre, - playingTime, - artHandle, - "ignore me", - "ignore me", - "ignore me", - "ignore me" - }; + int[] attrIds = + new int[] { + MEDIA_ATTRIBUTE_TITLE, + MEDIA_ATTRIBUTE_ARTIST_NAME, + MEDIA_ATTRIBUTE_ALBUM_NAME, + MEDIA_ATTRIBUTE_TRACK_NUMBER, + MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, + MEDIA_ATTRIBUTE_GENRE, + MEDIA_ATTRIBUTE_PLAYING_TIME, + MEDIA_ATTRIBUTE_COVER_ART_HANDLE, + 75, + 76, + 77, + 78 + }; + + String[] attrMap = + new String[] { + title, + artist, + album, + trackNumber, + totalTracks, + genre, + playingTime, + artHandle, + "ignore me", + "ignore me", + "ignore me", + "ignore me" + }; AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.fromAvrcpAttributeArray(attrIds, attrMap); @@ -233,27 +228,22 @@ public final class AvrcpItemTest { String playingTime = "301"; String artHandle = "000001"; // length 6 and not 7 - int[] attrIds = new int[]{ - MEDIA_ATTRIBUTE_TITLE, - MEDIA_ATTRIBUTE_ARTIST_NAME, - MEDIA_ATTRIBUTE_ALBUM_NAME, - MEDIA_ATTRIBUTE_TRACK_NUMBER, - MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, - MEDIA_ATTRIBUTE_GENRE, - MEDIA_ATTRIBUTE_PLAYING_TIME, - MEDIA_ATTRIBUTE_COVER_ART_HANDLE - }; - - String[] attrMap = new String[]{ - title, - artist, - album, - trackNumber, - totalTracks, - genre, - playingTime, - artHandle - }; + int[] attrIds = + new int[] { + MEDIA_ATTRIBUTE_TITLE, + MEDIA_ATTRIBUTE_ARTIST_NAME, + MEDIA_ATTRIBUTE_ALBUM_NAME, + MEDIA_ATTRIBUTE_TRACK_NUMBER, + MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, + MEDIA_ATTRIBUTE_GENRE, + MEDIA_ATTRIBUTE_PLAYING_TIME, + MEDIA_ATTRIBUTE_COVER_ART_HANDLE + }; + + String[] attrMap = + new String[] { + title, artist, album, trackNumber, totalTracks, genre, playingTime, artHandle + }; AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.fromAvrcpAttributeArray(attrIds, attrMap); @@ -285,27 +275,22 @@ public final class AvrcpItemTest { String playingTime = "301"; String artHandle = ""; - int[] attrIds = new int[]{ - MEDIA_ATTRIBUTE_TITLE, - MEDIA_ATTRIBUTE_ARTIST_NAME, - MEDIA_ATTRIBUTE_ALBUM_NAME, - MEDIA_ATTRIBUTE_TRACK_NUMBER, - MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, - MEDIA_ATTRIBUTE_GENRE, - MEDIA_ATTRIBUTE_PLAYING_TIME, - MEDIA_ATTRIBUTE_COVER_ART_HANDLE - }; - - String[] attrMap = new String[]{ - title, - artist, - album, - trackNumber, - totalTracks, - genre, - playingTime, - artHandle - }; + int[] attrIds = + new int[] { + MEDIA_ATTRIBUTE_TITLE, + MEDIA_ATTRIBUTE_ARTIST_NAME, + MEDIA_ATTRIBUTE_ALBUM_NAME, + MEDIA_ATTRIBUTE_TRACK_NUMBER, + MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, + MEDIA_ATTRIBUTE_GENRE, + MEDIA_ATTRIBUTE_PLAYING_TIME, + MEDIA_ATTRIBUTE_COVER_ART_HANDLE + }; + + String[] attrMap = + new String[] { + title, artist, album, trackNumber, totalTracks, genre, playingTime, artHandle + }; AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.fromAvrcpAttributeArray(attrIds, attrMap); @@ -337,27 +322,22 @@ public final class AvrcpItemTest { String playingTime = "301"; String artHandle = null; - int[] attrIds = new int[]{ - MEDIA_ATTRIBUTE_TITLE, - MEDIA_ATTRIBUTE_ARTIST_NAME, - MEDIA_ATTRIBUTE_ALBUM_NAME, - MEDIA_ATTRIBUTE_TRACK_NUMBER, - MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, - MEDIA_ATTRIBUTE_GENRE, - MEDIA_ATTRIBUTE_PLAYING_TIME, - MEDIA_ATTRIBUTE_COVER_ART_HANDLE - }; - - String[] attrMap = new String[]{ - title, - artist, - album, - trackNumber, - totalTracks, - genre, - playingTime, - artHandle - }; + int[] attrIds = + new int[] { + MEDIA_ATTRIBUTE_TITLE, + MEDIA_ATTRIBUTE_ARTIST_NAME, + MEDIA_ATTRIBUTE_ALBUM_NAME, + MEDIA_ATTRIBUTE_TRACK_NUMBER, + MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, + MEDIA_ATTRIBUTE_GENRE, + MEDIA_ATTRIBUTE_PLAYING_TIME, + MEDIA_ATTRIBUTE_COVER_ART_HANDLE + }; + + String[] attrMap = + new String[] { + title, artist, album, trackNumber, totalTracks, genre, playingTime, artHandle + }; AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.fromAvrcpAttributeArray(attrIds, attrMap); @@ -389,27 +369,22 @@ public final class AvrcpItemTest { String playingTime = "301"; String artHandle = "123abcd"; - int[] attrIds = new int[]{ - MEDIA_ATTRIBUTE_TITLE, - MEDIA_ATTRIBUTE_ARTIST_NAME, - MEDIA_ATTRIBUTE_ALBUM_NAME, - MEDIA_ATTRIBUTE_TRACK_NUMBER, - MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, - MEDIA_ATTRIBUTE_GENRE, - MEDIA_ATTRIBUTE_PLAYING_TIME, - MEDIA_ATTRIBUTE_COVER_ART_HANDLE - }; - - String[] attrMap = new String[]{ - title, - artist, - album, - trackNumber, - totalTracks, - genre, - playingTime, - artHandle - }; + int[] attrIds = + new int[] { + MEDIA_ATTRIBUTE_TITLE, + MEDIA_ATTRIBUTE_ARTIST_NAME, + MEDIA_ATTRIBUTE_ALBUM_NAME, + MEDIA_ATTRIBUTE_TRACK_NUMBER, + MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER, + MEDIA_ATTRIBUTE_GENRE, + MEDIA_ATTRIBUTE_PLAYING_TIME, + MEDIA_ATTRIBUTE_COVER_ART_HANDLE + }; + + String[] attrMap = + new String[] { + title, artist, album, trackNumber, totalTracks, genre, playingTime, artHandle + }; AvrcpItem.Builder builder = new AvrcpItem.Builder(); builder.fromAvrcpAttributeArray(attrIds, attrMap); @@ -479,26 +454,27 @@ public final class AvrcpItemTest { MediaMetadataCompat metadata = item.toMediaMetadata(); Assert.assertEquals(UUID, metadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID)); - Assert.assertEquals(title, - metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)); + Assert.assertEquals( + title, metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)); Assert.assertEquals(title, metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE)); Assert.assertEquals(artist, metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST)); Assert.assertEquals(album, metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM)); - Assert.assertEquals(trackNumber, - metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER)); - Assert.assertEquals(totalTracks, - metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS)); + Assert.assertEquals( + trackNumber, metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER)); + Assert.assertEquals( + totalTracks, metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS)); Assert.assertEquals(genre, metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE)); - Assert.assertEquals(playingTime, - metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)); - Assert.assertEquals(uri, + Assert.assertEquals( + playingTime, metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)); + Assert.assertEquals( + uri, Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI))); - Assert.assertEquals(uri, - Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ART_URI))); - Assert.assertEquals(uri, - Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI))); - Assert.assertEquals(null, - metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON)); + Assert.assertEquals( + uri, Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ART_URI))); + Assert.assertEquals( + uri, Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI))); + Assert.assertEquals( + null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON)); Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ART)); Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART)); Assert.assertFalse(metadata.containsKey(MediaMetadataCompat.METADATA_KEY_BT_FOLDER_TYPE)); @@ -533,28 +509,29 @@ public final class AvrcpItemTest { MediaMetadataCompat metadata = item.toMediaMetadata(); Assert.assertEquals(UUID, metadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID)); - Assert.assertEquals(title, - metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)); + Assert.assertEquals( + title, metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)); Assert.assertEquals(title, metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE)); Assert.assertEquals(artist, metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST)); Assert.assertEquals(null, metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM)); - Assert.assertEquals(totalTracks, - metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS)); + Assert.assertEquals( + totalTracks, metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS)); Assert.assertEquals(genre, metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE)); - Assert.assertEquals(playingTime, - metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)); - Assert.assertEquals(uri, + Assert.assertEquals( + playingTime, metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)); + Assert.assertEquals( + uri, Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI))); - Assert.assertEquals(uri, - Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ART_URI))); - Assert.assertEquals(uri, - Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI))); - Assert.assertEquals(null, - metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON)); + Assert.assertEquals( + uri, Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ART_URI))); + Assert.assertEquals( + uri, Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI))); + Assert.assertEquals( + null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON)); Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ART)); Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART)); - Assert.assertEquals(type, - metadata.getLong(MediaMetadataCompat.METADATA_KEY_BT_FOLDER_TYPE)); + Assert.assertEquals( + type, metadata.getLong(MediaMetadataCompat.METADATA_KEY_BT_FOLDER_TYPE)); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java index 5740a8086dc..33eeb5d2b24 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java @@ -40,14 +40,13 @@ public class AvrcpPlayerTest { private static final int TEST_PLAY_TIME = 1; private final AvrcpItem mAvrcpItem = new AvrcpItem.Builder().build(); - private final byte[] mTestAddress = new byte[]{01, 01, 01, 01, 01, 01}; + private final byte[] mTestAddress = new byte[] {01, 01, 01, 01, 01, 01}; private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice = null; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private PlayerApplicationSettings mPlayerApplicationSettings; + @Mock private PlayerApplicationSettings mPlayerApplicationSettings; @Before public void setUp() { @@ -73,8 +72,8 @@ public class AvrcpPlayerTest { assertThat(avrcpPlayer.supportsFeature(TEST_FEATURE)).isTrue(); assertThat(avrcpPlayer.getPlayStatus()).isEqualTo(TEST_PLAY_STATUS); assertThat(avrcpPlayer.getCurrentTrack()).isEqualTo(mAvrcpItem); - assertThat(avrcpPlayer.getPlaybackState().getActions()).isEqualTo( - PlaybackStateCompat.ACTION_PREPARE | PlaybackStateCompat.ACTION_PLAY); + assertThat(avrcpPlayer.getPlaybackState().getActions()) + .isEqualTo(PlaybackStateCompat.ACTION_PREPARE | PlaybackStateCompat.ACTION_PLAY); } @Test @@ -106,13 +105,14 @@ public class AvrcpPlayerTest { @Test public void setSupportedPlayerApplicationSettings() { - when(mPlayerApplicationSettings.supportsSetting( - PlayerApplicationSettings.REPEAT_STATUS)).thenReturn(true); - when(mPlayerApplicationSettings.supportsSetting( - PlayerApplicationSettings.SHUFFLE_STATUS)).thenReturn(true); + when(mPlayerApplicationSettings.supportsSetting(PlayerApplicationSettings.REPEAT_STATUS)) + .thenReturn(true); + when(mPlayerApplicationSettings.supportsSetting(PlayerApplicationSettings.SHUFFLE_STATUS)) + .thenReturn(true); AvrcpPlayer avrcpPlayer = new AvrcpPlayer.Builder().build(); long expectedActions = - PlaybackStateCompat.ACTION_PREPARE | PlaybackStateCompat.ACTION_SET_REPEAT_MODE + PlaybackStateCompat.ACTION_PREPARE + | PlaybackStateCompat.ACTION_SET_REPEAT_MODE | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE; avrcpPlayer.setSupportedPlayerApplicationSettings(mPlayerApplicationSettings); @@ -124,8 +124,8 @@ public class AvrcpPlayerTest { public void supportsSetting() { int settingType = 1; int settingValue = 1; - when(mPlayerApplicationSettings.supportsSetting(settingType, settingValue)).thenReturn( - true); + when(mPlayerApplicationSettings.supportsSetting(settingType, settingValue)) + .thenReturn(true); AvrcpPlayer avrcpPlayer = new AvrcpPlayer.Builder().build(); avrcpPlayer.setSupportedPlayerApplicationSettings(mPlayerApplicationSettings); @@ -142,21 +142,29 @@ public class AvrcpPlayerTest { setSupportedFeature(supportedFeatures, AvrcpPlayer.FEATURE_FAST_FORWARD); setSupportedFeature(supportedFeatures, AvrcpPlayer.FEATURE_FORWARD); setSupportedFeature(supportedFeatures, AvrcpPlayer.FEATURE_PREVIOUS); - long expectedActions = PlaybackStateCompat.ACTION_PREPARE | PlaybackStateCompat.ACTION_STOP - | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_REWIND - | PlaybackStateCompat.ACTION_FAST_FORWARD | PlaybackStateCompat.ACTION_SKIP_TO_NEXT - | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS; + long expectedActions = + PlaybackStateCompat.ACTION_PREPARE + | PlaybackStateCompat.ACTION_STOP + | PlaybackStateCompat.ACTION_PAUSE + | PlaybackStateCompat.ACTION_REWIND + | PlaybackStateCompat.ACTION_FAST_FORWARD + | PlaybackStateCompat.ACTION_SKIP_TO_NEXT + | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS; - AvrcpPlayer avrcpPlayer = new AvrcpPlayer.Builder().setSupportedFeatures( - supportedFeatures).build(); + AvrcpPlayer avrcpPlayer = + new AvrcpPlayer.Builder().setSupportedFeatures(supportedFeatures).build(); assertThat(avrcpPlayer.getPlaybackState().getActions()).isEqualTo(expectedActions); } @Test public void toString_returnsInfo() { - AvrcpPlayer avrcpPlayer = new AvrcpPlayer.Builder().setPlayerId(TEST_PLAYER_ID).setName( - TEST_NAME).setCurrentTrack(mAvrcpItem).build(); + AvrcpPlayer avrcpPlayer = + new AvrcpPlayer.Builder() + .setPlayerId(TEST_PLAYER_ID) + .setName(TEST_NAME) + .setCurrentTrack(mAvrcpItem) + .build(); assertThat(avrcpPlayer.toString()).isNotNull(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java index cabdc9a18d2..c384dab35a2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java @@ -40,7 +40,7 @@ public class BrowseNodeTest { private static final String TEST_UUID = "1111"; private static final String TEST_NAME = "item"; - private final byte[] mTestAddress = new byte[]{01, 01, 01, 01, 01, 01}; + private final byte[] mTestAddress = new byte[] {01, 01, 01, 01, 01, 01}; private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice = null; private BrowseTree mBrowseTree; @@ -56,9 +56,14 @@ public class BrowseNodeTest { @Test public void constructor_withAvrcpPlayer() { - BrowseNode browseNode = mBrowseTree.new BrowseNode(new AvrcpPlayer.Builder().setDevice( - mTestDevice).setPlayerId(TEST_PLAYER_ID).setSupportedFeature( - AvrcpPlayer.FEATURE_BROWSING).build()); + BrowseNode browseNode = + mBrowseTree + .new BrowseNode( + new AvrcpPlayer.Builder() + .setDevice(mTestDevice) + .setPlayerId(TEST_PLAYER_ID) + .setSupportedFeature(AvrcpPlayer.FEATURE_BROWSING) + .build()); assertThat(browseNode.isPlayer()).isTrue(); assertThat(browseNode.getBluetoothID()).isEqualTo(TEST_PLAYER_ID); @@ -77,8 +82,8 @@ public class BrowseNodeTest { @Test public void addChildren() { - AvrcpPlayer childAvrcpPlayer = new AvrcpPlayer.Builder().setPlayerId( - TEST_PLAYER_ID).build(); + AvrcpPlayer childAvrcpPlayer = + new AvrcpPlayer.Builder().setPlayerId(TEST_PLAYER_ID).build(); AvrcpItem childAvrcpItem = new AvrcpItem.Builder().setUuid(TEST_UUID).build(); List children = new ArrayList<>(); children.add(childAvrcpPlayer); @@ -104,15 +109,15 @@ public class BrowseNodeTest { assertThat(mBrowseTree.mNowPlayingNode.isChild(browseNode)).isTrue(); assertThat(browseNode.getParent()).isEqualTo(mBrowseTree.mNowPlayingNode); - assertThat(browseNode.getScope()).isEqualTo( - AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING); + assertThat(browseNode.getScope()) + .isEqualTo(AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING); assertThat(mBrowseTree.getNodesUsingCoverArt(coverArtUuid).get(0)).isEqualTo(TEST_UUID); } @Test public void removeChild() { - BrowseNode browseNode = mBrowseTree.new BrowseNode( - new AvrcpItem.Builder().setUuid(TEST_UUID).build()); + BrowseNode browseNode = + mBrowseTree.new BrowseNode(new AvrcpItem.Builder().setUuid(TEST_UUID).build()); mRootNode.addChild(browseNode); assertThat(mRootNode.getChildrenCount()).isEqualTo(1); @@ -135,8 +140,8 @@ public class BrowseNodeTest { @Test public void setCached() { - BrowseNode browseNode = mBrowseTree.new BrowseNode( - new AvrcpItem.Builder().setUuid(TEST_UUID).build()); + BrowseNode browseNode = + mBrowseTree.new BrowseNode(new AvrcpItem.Builder().setUuid(TEST_UUID).build()); mRootNode.addChild(browseNode); assertThat(mRootNode.getChildrenCount()).isEqualTo(1); @@ -148,12 +153,12 @@ public class BrowseNodeTest { @Test public void getters() { - BrowseNode browseNode = mBrowseTree.new BrowseNode( - new AvrcpItem.Builder().setUuid(TEST_UUID).build()); + BrowseNode browseNode = + mBrowseTree.new BrowseNode(new AvrcpItem.Builder().setUuid(TEST_UUID).build()); assertThat(browseNode.getFolderUID()).isEqualTo(TEST_UUID); - assertThat(browseNode.getPlayerID()).isEqualTo( - Integer.parseInt((TEST_UUID).replace(BrowseTree.PLAYER_PREFIX, ""))); + assertThat(browseNode.getPlayerID()) + .isEqualTo(Integer.parseInt((TEST_UUID).replace(BrowseTree.PLAYER_PREFIX, ""))); } @Test @@ -165,18 +170,18 @@ public class BrowseNodeTest { @Test public void equals_withSameId() { - BrowseNode browseNodeOne = mBrowseTree.new BrowseNode( - new AvrcpItem.Builder().setUuid(TEST_UUID).build()); - BrowseNode browseNodeTwo = mBrowseTree.new BrowseNode( - new AvrcpItem.Builder().setUuid(TEST_UUID).build()); + BrowseNode browseNodeOne = + mBrowseTree.new BrowseNode(new AvrcpItem.Builder().setUuid(TEST_UUID).build()); + BrowseNode browseNodeTwo = + mBrowseTree.new BrowseNode(new AvrcpItem.Builder().setUuid(TEST_UUID).build()); assertThat(browseNodeOne).isEqualTo(browseNodeTwo); } @Test public void isDescendant() { - BrowseNode browseNode = mBrowseTree.new BrowseNode( - new AvrcpItem.Builder().setUuid(TEST_UUID).build()); + BrowseNode browseNode = + mBrowseTree.new BrowseNode(new AvrcpItem.Builder().setUuid(TEST_UUID).build()); mRootNode.addChild(browseNode); assertThat(mRootNode.isDescendant(browseNode)).isTrue(); @@ -184,27 +189,40 @@ public class BrowseNodeTest { @Test public void toTreeString_returnFormattedString() { - final String expected = " [Id: 1111 Name: item Size: 2]\n" - + " [Id: child1 Name: child1 Size: 1]\n" - + " [Id: child3 Name: child3 Size: 0]\n" - + " [Id: child2 Name: child2 Size: 0]\n"; - - BrowseNode browseNode = mBrowseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid(TEST_UUID) - .setDisplayableName(TEST_NAME) - .build()); - BrowseNode childNode1 = mBrowseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid("child1") - .setDisplayableName("child1") - .build()); - BrowseNode childNode2 = mBrowseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid("child2") - .setDisplayableName("child2") - .build()); - BrowseNode childNode3 = mBrowseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid("child3") - .setDisplayableName("child3") - .build()); + final String expected = + " [Id: 1111 Name: item Size: 2]\n" + + " [Id: child1 Name: child1 Size: 1]\n" + + " [Id: child3 Name: child3 Size: 0]\n" + + " [Id: child2 Name: child2 Size: 0]\n"; + + BrowseNode browseNode = + mBrowseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid(TEST_UUID) + .setDisplayableName(TEST_NAME) + .build()); + BrowseNode childNode1 = + mBrowseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid("child1") + .setDisplayableName("child1") + .build()); + BrowseNode childNode2 = + mBrowseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid("child2") + .setDisplayableName("child2") + .build()); + BrowseNode childNode3 = + mBrowseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid("child3") + .setDisplayableName("child3") + .build()); childNode1.addChild(childNode3); browseNode.addChild(childNode1); browseNode.addChild(childNode2); @@ -216,12 +234,15 @@ public class BrowseNodeTest { @Test public void toString_returnsId() { - BrowseNode browseNode = mBrowseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid(TEST_UUID) - .setDisplayableName(TEST_NAME) - .build()); - - assertThat(browseNode.toString()).isEqualTo( - "[Id: " + TEST_UUID + " Name: " + TEST_NAME + " Size: 0]"); + BrowseNode browseNode = + mBrowseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid(TEST_UUID) + .setDisplayableName(TEST_NAME) + .build()); + + assertThat(browseNode.toString()) + .isEqualTo("[Id: " + TEST_UUID + " Name: " + TEST_NAME + " Size: 0]"); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java index 330be020f04..e801439f0bd 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java @@ -38,7 +38,7 @@ public class BrowseTreeTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - private final byte[] mTestAddress = new byte[]{01, 01, 01, 01, 01, 01}; + private final byte[] mTestAddress = new byte[] {01, 01, 01, 01, 01, 01}; private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice = null; @@ -74,13 +74,18 @@ public class BrowseTreeTest { @Test public void getTrackFromNowPlayingList() { BrowseTree browseTree = new BrowseTree(mTestDevice); - BrowseNode trackInNowPlayingList = browseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid(ILLEGAL_ID).setTitle(ILLEGAL_ID).setBrowsable(true).build()); + BrowseNode trackInNowPlayingList = + browseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid(ILLEGAL_ID) + .setTitle(ILLEGAL_ID) + .setBrowsable(true) + .build()); browseTree.mNowPlayingNode.addChild(trackInNowPlayingList); - assertThat(browseTree.getTrackFromNowPlayingList(0)).isEqualTo( - trackInNowPlayingList); + assertThat(browseTree.getTrackFromNowPlayingList(0)).isEqualTo(trackInNowPlayingList); } @Test @@ -156,8 +161,8 @@ public class BrowseTreeTest { BrowseTree browseTree = new BrowseTree(mTestDevice); assertThat(browseTree.setCurrentBrowsedPlayer(ILLEGAL_ID, 0, 0)).isFalse(); - assertThat( - browseTree.setCurrentBrowsedPlayer(BrowseTree.NOW_PLAYING_PREFIX, 2, 1)).isTrue(); + assertThat(browseTree.setCurrentBrowsedPlayer(BrowseTree.NOW_PLAYING_PREFIX, 2, 1)) + .isTrue(); assertThat(browseTree.getCurrentBrowsedPlayer()).isEqualTo(browseTree.mNowPlayingNode); } @@ -204,8 +209,8 @@ public class BrowseTreeTest { browseTree.onConnected(mTestDevice); - assertThat(BrowseTree.getEldestChild(browseTree.mNowPlayingNode, - browseTree.mRootNode)).isNull(); + assertThat(BrowseTree.getEldestChild(browseTree.mNowPlayingNode, browseTree.mRootNode)) + .isNull(); } @Test @@ -214,34 +219,42 @@ public class BrowseTreeTest { browseTree.onConnected(mTestDevice); - assertThat(BrowseTree.getEldestChild(browseTree.mRootNode, - browseTree.mRootNode.getChild(0))).isEqualTo(browseTree.mRootNode.getChild(0)); + assertThat( + BrowseTree.getEldestChild( + browseTree.mRootNode, browseTree.mRootNode.getChild(0))) + .isEqualTo(browseTree.mRootNode.getChild(0)); } @Test public void getNextStepFolder() { BrowseTree browseTree = new BrowseTree(null); - BrowseNode nodeOutOfMap = browseTree.new BrowseNode(new AvrcpItem.Builder() - .setUuid(ILLEGAL_ID).setTitle(ILLEGAL_ID).setBrowsable(true).build()); + BrowseNode nodeOutOfMap = + browseTree + .new BrowseNode( + new AvrcpItem.Builder() + .setUuid(ILLEGAL_ID) + .setTitle(ILLEGAL_ID) + .setBrowsable(true) + .build()); browseTree.onConnected(mTestDevice); assertThat(browseTree.getNextStepToFolder(null)).isNull(); - assertThat(browseTree.getNextStepToFolder(browseTree.mRootNode)).isEqualTo( - browseTree.mRootNode); - assertThat(browseTree.getNextStepToFolder(browseTree.mRootNode.getChild(0))).isEqualTo( - browseTree.mRootNode.getChild(0)); + assertThat(browseTree.getNextStepToFolder(browseTree.mRootNode)) + .isEqualTo(browseTree.mRootNode); + assertThat(browseTree.getNextStepToFolder(browseTree.mRootNode.getChild(0))) + .isEqualTo(browseTree.mRootNode.getChild(0)); assertThat(browseTree.getNextStepToFolder(nodeOutOfMap)).isNull(); browseTree.setCurrentBrowsedPlayer(BrowseTree.NOW_PLAYING_PREFIX, 2, 1); - assertThat(browseTree.getNextStepToFolder(browseTree.mRootNode.getChild(0))).isEqualTo( - browseTree.mNavigateUpNode); + assertThat(browseTree.getNextStepToFolder(browseTree.mRootNode.getChild(0))) + .isEqualTo(browseTree.mNavigateUpNode); } @Test public void toString_returnsSizeInfo() { BrowseTree browseTree = new BrowseTree(mTestDevice); - assertThat(browseTree.toString()).isEqualTo( - "[BrowseTree size=" + browseTree.mBrowseMap.size() + "]"); + assertThat(browseTree.toString()) + .isEqualTo("[BrowseTree size=" + browseTree.mBrowseMap.size() + "]"); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java index b311ddcf3bc..6f232a7883a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java @@ -37,8 +37,8 @@ public class PlayerApplicationSettingsTest { btAvrcpAttributeList[1] = 1; btAvrcpAttributeList[2] = PlayerApplicationSettings.JNI_REPEAT_STATUS_ALL_TRACK_REPEAT; - PlayerApplicationSettings settings = PlayerApplicationSettings.makeSupportedSettings( - btAvrcpAttributeList); + PlayerApplicationSettings settings = + PlayerApplicationSettings.makeSupportedSettings(btAvrcpAttributeList); assertThat(settings.supportsSetting(PlayerApplicationSettings.REPEAT_STATUS)).isTrue(); } @@ -49,11 +49,11 @@ public class PlayerApplicationSettingsTest { btAvrcpAttributeList[0] = PlayerApplicationSettings.REPEAT_STATUS; btAvrcpAttributeList[1] = PlayerApplicationSettings.JNI_REPEAT_STATUS_GROUP_REPEAT; - PlayerApplicationSettings settings = PlayerApplicationSettings.makeSettings( - btAvrcpAttributeList); + PlayerApplicationSettings settings = + PlayerApplicationSettings.makeSettings(btAvrcpAttributeList); - assertThat(settings.getSetting(PlayerApplicationSettings.REPEAT_STATUS)).isEqualTo( - PlaybackStateCompat.REPEAT_MODE_GROUP); + assertThat(settings.getSetting(PlayerApplicationSettings.REPEAT_STATUS)) + .isEqualTo(PlaybackStateCompat.REPEAT_MODE_GROUP); } @Test @@ -61,84 +61,98 @@ public class PlayerApplicationSettingsTest { byte[] btAvrcpAttributeList = new byte[2]; btAvrcpAttributeList[0] = PlayerApplicationSettings.REPEAT_STATUS; btAvrcpAttributeList[1] = PlayerApplicationSettings.JNI_REPEAT_STATUS_GROUP_REPEAT; - PlayerApplicationSettings settings = PlayerApplicationSettings.makeSettings( - btAvrcpAttributeList); + PlayerApplicationSettings settings = + PlayerApplicationSettings.makeSettings(btAvrcpAttributeList); PlayerApplicationSettings settingsFromSetSupport = new PlayerApplicationSettings(); settingsFromSetSupport.setSupport(settings); - assertThat(settingsFromSetSupport.getSetting( - PlayerApplicationSettings.REPEAT_STATUS)).isEqualTo( - PlaybackStateCompat.REPEAT_MODE_GROUP); + assertThat(settingsFromSetSupport.getSetting(PlayerApplicationSettings.REPEAT_STATUS)) + .isEqualTo(PlaybackStateCompat.REPEAT_MODE_GROUP); } @Test public void mapAttribIdValtoAvrcpPlayerSetting() { - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.REPEAT_STATUS, - PlayerApplicationSettings.JNI_REPEAT_STATUS_ALL_TRACK_REPEAT)).isEqualTo( - PlaybackStateCompat.REPEAT_MODE_ALL); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.REPEAT_STATUS, - PlayerApplicationSettings.JNI_REPEAT_STATUS_GROUP_REPEAT)).isEqualTo( - PlaybackStateCompat.REPEAT_MODE_GROUP); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.REPEAT_STATUS, - PlayerApplicationSettings.JNI_REPEAT_STATUS_OFF)).isEqualTo( - PlaybackStateCompat.REPEAT_MODE_NONE); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.REPEAT_STATUS, - PlayerApplicationSettings.JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT)).isEqualTo( - PlaybackStateCompat.REPEAT_MODE_ONE); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.SHUFFLE_STATUS, - PlayerApplicationSettings.JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE)).isEqualTo( - PlaybackStateCompat.SHUFFLE_MODE_ALL); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.SHUFFLE_STATUS, - PlayerApplicationSettings.JNI_SHUFFLE_STATUS_GROUP_SHUFFLE)).isEqualTo( - PlaybackStateCompat.SHUFFLE_MODE_GROUP); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.SHUFFLE_STATUS, - PlayerApplicationSettings.JNI_SHUFFLE_STATUS_OFF)).isEqualTo( - PlaybackStateCompat.SHUFFLE_MODE_NONE); - assertThat(PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( - PlayerApplicationSettings.JNI_STATUS_INVALID, - PlayerApplicationSettings.JNI_STATUS_INVALID)).isEqualTo( - PlayerApplicationSettings.JNI_STATUS_INVALID); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.REPEAT_STATUS, + PlayerApplicationSettings.JNI_REPEAT_STATUS_ALL_TRACK_REPEAT)) + .isEqualTo(PlaybackStateCompat.REPEAT_MODE_ALL); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.REPEAT_STATUS, + PlayerApplicationSettings.JNI_REPEAT_STATUS_GROUP_REPEAT)) + .isEqualTo(PlaybackStateCompat.REPEAT_MODE_GROUP); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.REPEAT_STATUS, + PlayerApplicationSettings.JNI_REPEAT_STATUS_OFF)) + .isEqualTo(PlaybackStateCompat.REPEAT_MODE_NONE); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.REPEAT_STATUS, + PlayerApplicationSettings.JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT)) + .isEqualTo(PlaybackStateCompat.REPEAT_MODE_ONE); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.SHUFFLE_STATUS, + PlayerApplicationSettings.JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE)) + .isEqualTo(PlaybackStateCompat.SHUFFLE_MODE_ALL); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.SHUFFLE_STATUS, + PlayerApplicationSettings.JNI_SHUFFLE_STATUS_GROUP_SHUFFLE)) + .isEqualTo(PlaybackStateCompat.SHUFFLE_MODE_GROUP); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.SHUFFLE_STATUS, + PlayerApplicationSettings.JNI_SHUFFLE_STATUS_OFF)) + .isEqualTo(PlaybackStateCompat.SHUFFLE_MODE_NONE); + assertThat( + PlayerApplicationSettings.mapAttribIdValtoAvrcpPlayerSetting( + PlayerApplicationSettings.JNI_STATUS_INVALID, + PlayerApplicationSettings.JNI_STATUS_INVALID)) + .isEqualTo(PlayerApplicationSettings.JNI_STATUS_INVALID); } @Test public void mapAvrcpPlayerSettingstoBTattribVal() { - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.REPEAT_STATUS, - PlaybackStateCompat.REPEAT_MODE_NONE)).isEqualTo( - PlayerApplicationSettings.JNI_REPEAT_STATUS_OFF); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.REPEAT_STATUS, - PlaybackStateCompat.REPEAT_MODE_ONE)).isEqualTo( - PlayerApplicationSettings.JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.REPEAT_STATUS, - PlaybackStateCompat.REPEAT_MODE_ALL)).isEqualTo( - PlayerApplicationSettings.JNI_REPEAT_STATUS_ALL_TRACK_REPEAT); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.REPEAT_STATUS, - PlaybackStateCompat.REPEAT_MODE_GROUP)).isEqualTo( - PlayerApplicationSettings.JNI_REPEAT_STATUS_GROUP_REPEAT); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.SHUFFLE_STATUS, - PlaybackStateCompat.SHUFFLE_MODE_NONE)).isEqualTo( - PlayerApplicationSettings.JNI_SHUFFLE_STATUS_OFF); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.SHUFFLE_STATUS, - PlaybackStateCompat.SHUFFLE_MODE_ALL)).isEqualTo( - PlayerApplicationSettings.JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( - PlayerApplicationSettings.SHUFFLE_STATUS, - PlaybackStateCompat.SHUFFLE_MODE_GROUP)).isEqualTo( - PlayerApplicationSettings.JNI_SHUFFLE_STATUS_GROUP_SHUFFLE); - assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal(-1, -1)).isEqualTo( - PlayerApplicationSettings.JNI_STATUS_INVALID); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.REPEAT_STATUS, + PlaybackStateCompat.REPEAT_MODE_NONE)) + .isEqualTo(PlayerApplicationSettings.JNI_REPEAT_STATUS_OFF); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.REPEAT_STATUS, + PlaybackStateCompat.REPEAT_MODE_ONE)) + .isEqualTo(PlayerApplicationSettings.JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.REPEAT_STATUS, + PlaybackStateCompat.REPEAT_MODE_ALL)) + .isEqualTo(PlayerApplicationSettings.JNI_REPEAT_STATUS_ALL_TRACK_REPEAT); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.REPEAT_STATUS, + PlaybackStateCompat.REPEAT_MODE_GROUP)) + .isEqualTo(PlayerApplicationSettings.JNI_REPEAT_STATUS_GROUP_REPEAT); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.SHUFFLE_STATUS, + PlaybackStateCompat.SHUFFLE_MODE_NONE)) + .isEqualTo(PlayerApplicationSettings.JNI_SHUFFLE_STATUS_OFF); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.SHUFFLE_STATUS, + PlaybackStateCompat.SHUFFLE_MODE_ALL)) + .isEqualTo(PlayerApplicationSettings.JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE); + assertThat( + PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal( + PlayerApplicationSettings.SHUFFLE_STATUS, + PlaybackStateCompat.SHUFFLE_MODE_GROUP)) + .isEqualTo(PlayerApplicationSettings.JNI_SHUFFLE_STATUS_GROUP_SHUFFLE); + assertThat(PlayerApplicationSettings.mapAvrcpPlayerSettingstoBTattribVal(-1, -1)) + .isEqualTo(PlayerApplicationSettings.JNI_STATUS_INVALID); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java index 3f3083bb872..82fe7c61624 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java @@ -33,14 +33,14 @@ public class StackEventTest { boolean remoteControlConnected = true; boolean browsingConnected = true; - StackEvent stackEvent = StackEvent.connectionStateChanged(remoteControlConnected, - browsingConnected); + StackEvent stackEvent = + StackEvent.connectionStateChanged(remoteControlConnected, browsingConnected); assertThat(stackEvent.mType).isEqualTo(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); assertThat(stackEvent.mRemoteControlConnected).isTrue(); assertThat(stackEvent.mBrowsingConnected).isTrue(); - assertThat(stackEvent.toString()).isEqualTo( - "EVENT_TYPE_CONNECTION_STATE_CHANGED " + remoteControlConnected); + assertThat(stackEvent.toString()) + .isEqualTo("EVENT_TYPE_CONNECTION_STATE_CHANGED " + remoteControlConnected); } @Test @@ -62,4 +62,4 @@ public class StackEventTest { assertThat(stackEvent.toString()).isEqualTo("Unknown"); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java index feb63087e3f..7e4ccf87f98 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java @@ -26,9 +26,7 @@ import java.util.Calendar; import java.util.Date; import java.util.TimeZone; -/** - * A test suite for the BipAttachmentFormat class - */ +/** A test suite for the BipAttachmentFormat class */ @RunWith(AndroidJUnit4.class) public class BipAttachmentFormatTest { @@ -46,12 +44,20 @@ public class BipAttachmentFormatTest { return makeDate(month, day, year, hours, min, sec, null); } - private void testParse(String contentType, String charset, String name, String size, - String created, String modified, Date expectedCreated, boolean isCreatedUtc, - Date expectedModified, boolean isModifiedUtc) { + private void testParse( + String contentType, + String charset, + String name, + String size, + String created, + String modified, + Date expectedCreated, + boolean isCreatedUtc, + Date expectedModified, + boolean isModifiedUtc) { int expectedSize = (size != null ? Integer.parseInt(size) : -1); - BipAttachmentFormat attachment = new BipAttachmentFormat(contentType, charset, name, - size, created, modified); + BipAttachmentFormat attachment = + new BipAttachmentFormat(contentType, charset, name, size, created, modified); Assert.assertEquals(contentType, attachment.getContentType()); Assert.assertEquals(charset, attachment.getCharset()); Assert.assertEquals(name, attachment.getName()); @@ -72,10 +78,15 @@ public class BipAttachmentFormatTest { } } - private void testCreate(String contentType, String charset, String name, int size, - Date created, Date modified) { - BipAttachmentFormat attachment = new BipAttachmentFormat(contentType, charset, name, - size, created, modified); + private void testCreate( + String contentType, + String charset, + String name, + int size, + Date created, + Date modified) { + BipAttachmentFormat attachment = + new BipAttachmentFormat(contentType, charset, name, size, created, modified); Assert.assertEquals(contentType, attachment.getContentType()); Assert.assertEquals(charset, attachment.getCharset()); Assert.assertEquals(name, attachment.getName()); @@ -104,52 +115,141 @@ public class BipAttachmentFormatTest { Date dateUtc = makeDate(1, 1, 1990, 12, 34, 56, utc); // Well defined fields - testParse("text/plain", "ISO-8859-1", "thisisatextfile.txt", "2048", "19900101T123456", - "19900101T123456", date, false, date, false); + testParse( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "2048", + "19900101T123456", + "19900101T123456", + date, + false, + date, + false); // Well defined fields with UTC date - testParse("text/plain", "ISO-8859-1", "thisisatextfile.txt", "2048", "19900101T123456Z", - "19900101T123456Z", dateUtc, true, dateUtc, true); + testParse( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "2048", + "19900101T123456Z", + "19900101T123456Z", + dateUtc, + true, + dateUtc, + true); // Change up the content type and file name - testParse("audio/basic", "ISO-8859-1", "thisisawavfile.wav", "1024", "19900101T123456", - "19900101T123456", date, false, date, false); + testParse( + "audio/basic", + "ISO-8859-1", + "thisisawavfile.wav", + "1024", + "19900101T123456", + "19900101T123456", + date, + false, + date, + false); // Use a null modified date - testParse("text/plain", "ISO-8859-1", "thisisatextfile.txt", "2048", "19900101T123456", - null, date, false, null, false); + testParse( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "2048", + "19900101T123456", + null, + date, + false, + null, + false); // Use a null created date - testParse("text/plain", "ISO-8859-1", "thisisatextfile.txt", "2048", null, - "19900101T123456", null, false, date, false); + testParse( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "2048", + null, + "19900101T123456", + null, + false, + date, + false); // Use all null dates - testParse("text/plain", "ISO-8859-1", "thisisatextfile.txt", "123", null, null, null, false, - null, false); + testParse( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "123", + null, + null, + null, + false, + null, + false); // Use a null size - testParse("text/plain", "ISO-8859-1", "thisisatextfile.txt", null, null, null, null, false, - null, false); + testParse( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + null, + null, + null, + null, + false, + null, + false); // Use a null charset - testParse("text/plain", null, "thisisatextfile.txt", "2048", null, null, null, false, null, + testParse( + "text/plain", + null, + "thisisatextfile.txt", + "2048", + null, + null, + null, + false, + null, false); // Use only required fields - testParse("text/plain", null, "thisisatextfile.txt", null, null, null, null, false, null, + testParse( + "text/plain", + null, + "thisisatextfile.txt", + null, + null, + null, + null, + false, + null, false); } @Test(expected = ParseException.class) public void testParseNullContentType() { - testParse(null, "ISO-8859-1", "thisisatextfile.txt", null, null, null, null, false, null, + testParse( + null, + "ISO-8859-1", + "thisisatextfile.txt", + null, + null, + null, + null, + false, + null, false); } @Test(expected = ParseException.class) public void testParseNullName() { - testParse("text/plain", "ISO-8859-1", null, null, null, null, null, false, null, - false); + testParse("text/plain", "ISO-8859-1", null, null, null, null, null, false, null, false); } @Test @@ -189,54 +289,75 @@ public class BipAttachmentFormatTest { Date dateUtc = makeDate(1, 1, 1990, 12, 34, 56, utc); BipAttachmentFormat attachment = null; - String expected = ""; + String expected = + ""; - String expectedUtc = ""; + String expectedUtc = + ""; - String expectedNoDates = ""; + String expectedNoDates = + ""; - String expectedNoSizeNoDates = ""; + String expectedNoSizeNoDates = + ""; - String expectedNoCharsetNoDates = ""; + String expectedNoCharsetNoDates = + ""; - String expectedRequiredOnly = ""; + String expectedRequiredOnly = + ""; // Create by parsing, all fields - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - "2048", "19900101T123456", "19900101T123456"); + attachment = + new BipAttachmentFormat( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "2048", + "19900101T123456", + "19900101T123456"); Assert.assertEquals(expected, attachment.toString()); // Create by parsing, all fields with utc dates - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - "2048", "19900101T123456Z", "19900101T123456Z"); + attachment = + new BipAttachmentFormat( + "text/plain", + "ISO-8859-1", + "thisisatextfile.txt", + "2048", + "19900101T123456Z", + "19900101T123456Z"); Assert.assertEquals(expectedUtc, attachment.toString()); // Create by parsing, no timestamps - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - "2048", null, null); + attachment = + new BipAttachmentFormat( + "text/plain", "ISO-8859-1", "thisisatextfile.txt", "2048", null, null); Assert.assertEquals(expectedNoDates, attachment.toString()); // Create by parsing, no size, no dates - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - null, null, null); + attachment = + new BipAttachmentFormat( + "text/plain", "ISO-8859-1", "thisisatextfile.txt", null, null, null); Assert.assertEquals(expectedNoSizeNoDates, attachment.toString()); // Create by parsing, no charset, no dates - attachment = new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", "2048", - null, null); + attachment = + new BipAttachmentFormat( + "text/plain", null, "thisisatextfile.txt", "2048", null, null); Assert.assertEquals(expectedNoCharsetNoDates, attachment.toString()); // Create by parsing, content type only - attachment = new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", null, null, - null); + attachment = + new BipAttachmentFormat( + "text/plain", null, "thisisatextfile.txt", null, null, null); Assert.assertEquals(expectedRequiredOnly, attachment.toString()); } @@ -247,61 +368,69 @@ public class BipAttachmentFormatTest { Date date = makeDate(1, 1, 1990, 12, 34, 56, utc); BipAttachmentFormat attachment = null; - String expected = ""; + String expected = + ""; - String expectedNoDates = ""; + String expectedNoDates = + ""; - String expectedNoSizeNoDates = ""; + String expectedNoSizeNoDates = + ""; - String expectedNoCharsetNoDates = ""; + String expectedNoCharsetNoDates = + ""; - String expectedRequiredOnly = ""; + String expectedRequiredOnly = + ""; // Create with objects, all fields. Now we Use UTC since all Date objects eventually become // UTC anyway and this will be timezone agnostic - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - 2048, date, date); + attachment = + new BipAttachmentFormat( + "text/plain", "ISO-8859-1", "thisisatextfile.txt", 2048, date, date); Assert.assertEquals(expected, attachment.toString()); // Create with objects, no dates - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - 2048, null, null); + attachment = + new BipAttachmentFormat( + "text/plain", "ISO-8859-1", "thisisatextfile.txt", 2048, null, null); Assert.assertEquals(expectedNoDates, attachment.toString()); // Create with objects, no size and no dates - attachment = new BipAttachmentFormat("text/plain", "ISO-8859-1", "thisisatextfile.txt", - -1, null, null); + attachment = + new BipAttachmentFormat( + "text/plain", "ISO-8859-1", "thisisatextfile.txt", -1, null, null); Assert.assertEquals(expectedNoSizeNoDates, attachment.toString()); // Create with objects, no charset, no dates - attachment = new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", 2048, null, - null); + attachment = + new BipAttachmentFormat( + "text/plain", null, "thisisatextfile.txt", 2048, null, null); Assert.assertEquals(expectedNoCharsetNoDates, attachment.toString()); // Create with objects, content type only - attachment = new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", -1, null, - null); + attachment = + new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", -1, null, null); Assert.assertEquals(expectedRequiredOnly, attachment.toString()); } @Test public void testEquals_withSameInstance() { - BipAttachmentFormat attachment = new BipAttachmentFormat("text/plain", null, - "thisisatextfile.txt", -1, null, null); + BipAttachmentFormat attachment = + new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", -1, null, null); Assert.assertTrue(attachment.equals(attachment)); } @Test public void testEquals_withDifferentClass() { - BipAttachmentFormat attachment = new BipAttachmentFormat("text/plain", null, - "thisisatextfile.txt", -1, null, null); + BipAttachmentFormat attachment = + new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", -1, null, null); String notAttachment = "notAttachment"; Assert.assertFalse(attachment.equals(notAttachment)); @@ -309,10 +438,10 @@ public class BipAttachmentFormatTest { @Test public void testEquals_withSameInfo() { - BipAttachmentFormat attachment = new BipAttachmentFormat("text/plain", null, - "thisisatextfile.txt", -1, null, null); - BipAttachmentFormat attachmentEqual = new BipAttachmentFormat("text/plain", null, - "thisisatextfile.txt", -1, null, null); + BipAttachmentFormat attachment = + new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", -1, null, null); + BipAttachmentFormat attachmentEqual = + new BipAttachmentFormat("text/plain", null, "thisisatextfile.txt", -1, null, null); Assert.assertTrue(attachment.equals(attachmentEqual)); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java index 958e1c439a0..91c6b594983 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java @@ -27,9 +27,7 @@ import java.util.Date; import java.util.Locale; import java.util.TimeZone; -/** - * A test suite for the BipDateTime class - */ +/** A test suite for the BipDateTime class */ @RunWith(AndroidJUnit4.class) public class BipDatetimeTest { @@ -47,14 +45,18 @@ public class BipDatetimeTest { return makeDate(month, day, year, hours, min, sec, null); } - private String makeTzAdjustedString(int month, int day, int year, int hours, int min, - int sec) { + private String makeTzAdjustedString(int month, int day, int year, int hours, int min, int sec) { Calendar cal = Calendar.getInstance(); cal.setTime(makeDate(month, day, year, hours, min, sec)); cal.setTimeZone(TimeZone.getDefault()); - return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d", cal.get(Calendar.YEAR), - cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE), - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), + return String.format( + Locale.US, + "%04d%02d%02dT%02d%02d%02d", + cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH) + 1, + cal.get(Calendar.DATE), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); } @@ -74,19 +76,40 @@ public class BipDatetimeTest { @Test public void testCreateFromValidString() { - testParse("20000101T000000", makeDate(1, 1, 2000, 0, 0, 0), false, + testParse( + "20000101T000000", + makeDate(1, 1, 2000, 0, 0, 0), + false, makeTzAdjustedString(1, 1, 2000, 0, 0, 0)); - testParse("20000101T060115", makeDate(1, 1, 2000, 6, 1, 15), false, + testParse( + "20000101T060115", + makeDate(1, 1, 2000, 6, 1, 15), + false, makeTzAdjustedString(1, 1, 2000, 6, 1, 15)); - testParse("20000101T060000", makeDate(1, 1, 2000, 6, 0, 0), false, + testParse( + "20000101T060000", + makeDate(1, 1, 2000, 6, 0, 0), + false, makeTzAdjustedString(1, 1, 2000, 6, 0, 0)); - testParse("20000101T071500", makeDate(1, 1, 2000, 7, 15, 0), false, + testParse( + "20000101T071500", + makeDate(1, 1, 2000, 7, 15, 0), + false, makeTzAdjustedString(1, 1, 2000, 7, 15, 0)); - testParse("20000101T151700", makeDate(1, 1, 2000, 15, 17, 0), false, + testParse( + "20000101T151700", + makeDate(1, 1, 2000, 15, 17, 0), + false, makeTzAdjustedString(1, 1, 2000, 15, 17, 0)); - testParse("20000101T235959", makeDate(1, 1, 2000, 23, 59, 59), false, + testParse( + "20000101T235959", + makeDate(1, 1, 2000, 23, 59, 59), + false, makeTzAdjustedString(1, 1, 2000, 23, 59, 59)); - testParse("20501127T235959", makeDate(11, 27, 2050, 23, 59, 59), false, + testParse( + "20501127T235959", + makeDate(11, 27, 2050, 23, 59, 59), + false, makeTzAdjustedString(11, 27, 2050, 23, 59, 59)); } @@ -94,19 +117,23 @@ public class BipDatetimeTest { public void testParseFromValidStringWithUtc() { TimeZone utc = TimeZone.getTimeZone("UTC"); utc.setRawOffset(0); - testParse("20000101T000000Z", makeDate(1, 1, 2000, 0, 0, 0, utc), true, - "20000101T000000Z"); - testParse("20000101T060115Z", makeDate(1, 1, 2000, 6, 1, 15, utc), true, - "20000101T060115Z"); - testParse("20000101T060000Z", makeDate(1, 1, 2000, 6, 0, 0, utc), true, - "20000101T060000Z"); - testParse("20000101T071500Z", makeDate(1, 1, 2000, 7, 15, 0, utc), true, - "20000101T071500Z"); - testParse("20000101T151700Z", makeDate(1, 1, 2000, 15, 17, 0, utc), true, - "20000101T151700Z"); - testParse("20000101T235959Z", makeDate(1, 1, 2000, 23, 59, 59, utc), true, + testParse("20000101T000000Z", makeDate(1, 1, 2000, 0, 0, 0, utc), true, "20000101T000000Z"); + testParse( + "20000101T060115Z", makeDate(1, 1, 2000, 6, 1, 15, utc), true, "20000101T060115Z"); + testParse("20000101T060000Z", makeDate(1, 1, 2000, 6, 0, 0, utc), true, "20000101T060000Z"); + testParse( + "20000101T071500Z", makeDate(1, 1, 2000, 7, 15, 0, utc), true, "20000101T071500Z"); + testParse( + "20000101T151700Z", makeDate(1, 1, 2000, 15, 17, 0, utc), true, "20000101T151700Z"); + testParse( + "20000101T235959Z", + makeDate(1, 1, 2000, 23, 59, 59, utc), + true, "20000101T235959Z"); - testParse("20501127T235959Z", makeDate(11, 27, 2050, 23, 59, 59, utc), true, + testParse( + "20501127T235959Z", + makeDate(11, 27, 2050, 23, 59, 59, utc), + true, "20501127T235959Z"); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java index 5ae69fbc1a9..dcecc314d2d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java @@ -22,13 +22,15 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -/** - * A test suite for the BipEncoding class - */ +/** A test suite for the BipEncoding class */ @RunWith(AndroidJUnit4.class) public class BipEncodingTest { - private void testParse(String input, int encodingType, String encodingStr, String propId, + private void testParse( + String input, + int encodingType, + String encodingStr, + String propId, boolean isAndroidSupported) { BipEncoding encoding = new BipEncoding(input); Assert.assertEquals(encodingType, encoding.getType()); @@ -37,7 +39,11 @@ public class BipEncodingTest { Assert.assertEquals(isAndroidSupported, encoding.isAndroidSupported()); } - private void testParseMany(String[] inputs, int encodingType, String encodingStr, String propId, + private void testParseMany( + String[] inputs, + int encodingType, + String encodingStr, + String propId, boolean isAndroidSupported) { for (String input : inputs) { testParse(input, encodingType, encodingStr, propId, isAndroidSupported); @@ -46,54 +52,61 @@ public class BipEncodingTest { @Test public void testParseJpeg() { - String[] inputs = new String[]{"JPEG", "jpeg", "Jpeg", "JpEg"}; + String[] inputs = new String[] {"JPEG", "jpeg", "Jpeg", "JpEg"}; testParseMany(inputs, BipEncoding.JPEG, "JPEG", null, true); } @Test public void testParseGif() { - String[] inputs = new String[]{"GIF", "gif", "Gif", "gIf"}; + String[] inputs = new String[] {"GIF", "gif", "Gif", "gIf"}; testParseMany(inputs, BipEncoding.GIF, "GIF", null, true); } @Test public void testParseWbmp() { - String[] inputs = new String[]{"WBMP", "wbmp", "Wbmp", "WbMp"}; + String[] inputs = new String[] {"WBMP", "wbmp", "Wbmp", "WbMp"}; testParseMany(inputs, BipEncoding.WBMP, "WBMP", null, false); } @Test public void testParsePng() { - String[] inputs = new String[]{"PNG", "png", "Png", "PnG"}; + String[] inputs = new String[] {"PNG", "png", "Png", "PnG"}; testParseMany(inputs, BipEncoding.PNG, "PNG", null, true); } @Test public void testParseJpeg2000() { - String[] inputs = new String[]{"JPEG2000", "jpeg2000", "Jpeg2000", "JpEg2000"}; + String[] inputs = new String[] {"JPEG2000", "jpeg2000", "Jpeg2000", "JpEg2000"}; testParseMany(inputs, BipEncoding.JPEG2000, "JPEG2000", null, false); } @Test public void testParseBmp() { - String[] inputs = new String[]{"BMP", "bmp", "Bmp", "BmP"}; + String[] inputs = new String[] {"BMP", "bmp", "Bmp", "BmP"}; testParseMany(inputs, BipEncoding.BMP, "BMP", null, true); } @Test public void testParseUsrProprietary() { - String[] inputs = new String[]{"USR-test", "usr-test", "Usr-Test", "UsR-TeSt"}; + String[] inputs = new String[] {"USR-test", "usr-test", "Usr-Test", "UsR-TeSt"}; testParseMany(inputs, BipEncoding.USR_XXX, "USR-TEST", "TEST", false); // Example used in the spec so not a bad choice here - inputs = new String[]{"USR-NOKIA-FORMAT1", "usr-nokia-format1"}; + inputs = new String[] {"USR-NOKIA-FORMAT1", "usr-nokia-format1"}; testParseMany(inputs, BipEncoding.USR_XXX, "USR-NOKIA-FORMAT1", "NOKIA-FORMAT1", false); } @Test public void testCreateBasicEncoding() { - int[] inputs = new int[]{BipEncoding.JPEG, BipEncoding.PNG, BipEncoding.BMP, - BipEncoding.GIF, BipEncoding.JPEG2000, BipEncoding.WBMP}; + int[] inputs = + new int[] { + BipEncoding.JPEG, + BipEncoding.PNG, + BipEncoding.BMP, + BipEncoding.GIF, + BipEncoding.JPEG2000, + BipEncoding.WBMP + }; for (int encodingType : inputs) { BipEncoding encoding = new BipEncoding(encodingType, null); Assert.assertEquals(encodingType, encoding.getType()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java index 2a12b1a449a..658dca4eefb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java @@ -22,9 +22,7 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -/** - * A test suite for the BipImageDescriptor class - */ +/** A test suite for the BipImageDescriptor class */ @RunWith(AndroidJUnit4.class) public class BipImageDescriptorTest { @@ -33,9 +31,11 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_encodingConstants() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setEncoding(BipEncoding.JPEG); @@ -48,9 +48,11 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_encodingObject() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipEncoding encoding = new BipEncoding(BipEncoding.JPEG, null); BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); @@ -64,9 +66,12 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_proprietaryEncoding() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setPropietaryEncoding("NOKIA-1"); @@ -79,10 +84,12 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_transformationConstantStretch() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setPropietaryEncoding("NOKIA-1"); @@ -95,10 +102,12 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_transformationConstantCrop() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setPropietaryEncoding("NOKIA-1"); @@ -111,10 +120,12 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_transformationConstantFill() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setPropietaryEncoding("NOKIA-1"); @@ -127,10 +138,12 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_transformationConstantCropThenFill() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setPropietaryEncoding("NOKIA-1"); @@ -144,9 +157,11 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_noSize() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setEncoding(BipEncoding.JPEG); @@ -158,9 +173,11 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_useMaxSize() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setEncoding(BipEncoding.JPEG); @@ -173,10 +190,12 @@ public class BipImageDescriptorTest { @Test public void testBuildImageDescriptor_allButSize() { - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); builder.setEncoding(BipEncoding.JPEG); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java index d5d6bdf2ac4..e02d9f9267f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java @@ -22,9 +22,7 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -/** - * A test suite for the BipImageFormat class - */ +/** A test suite for the BipImageFormat class */ @RunWith(AndroidJUnit4.class) public class BipImageFormatTest { @Test @@ -81,8 +79,9 @@ public class BipImageFormatTest { @Test public void testParseVariant_withTransformation() { - String expected = ""; + String expected = + ""; BipTransformation trans = new BipTransformation(); trans.addTransformation(BipTransformation.STRETCH); trans.addTransformation(BipTransformation.FILL); @@ -105,8 +104,9 @@ public class BipImageFormatTest { @Test public void testParseVariant_allFields() { - String expected = ""; + String expected = + ""; BipTransformation trans = new BipTransformation(); trans.addTransformation(BipTransformation.STRETCH); trans.addTransformation(BipTransformation.FILL); @@ -145,8 +145,11 @@ public class BipImageFormatTest { @Test public void testCreateNative_requiredOnly() { String expected = ""; - BipImageFormat format = BipImageFormat.createNative( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(1280, 1024), -1); + BipImageFormat format = + BipImageFormat.createNative( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(1280, 1024), + -1); Assert.assertEquals(BipImageFormat.FORMAT_NATIVE, format.getType()); Assert.assertEquals(new BipEncoding(BipEncoding.JPEG, null), format.getEncoding()); Assert.assertEquals(BipPixel.createFixed(1280, 1024), format.getPixel()); @@ -159,8 +162,11 @@ public class BipImageFormatTest { @Test public void testCreateNative_withSize() { String expected = ""; - BipImageFormat format = BipImageFormat.createNative( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(1280, 1024), 1048576); + BipImageFormat format = + BipImageFormat.createNative( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(1280, 1024), + 1048576); Assert.assertEquals(BipImageFormat.FORMAT_NATIVE, format.getType()); Assert.assertEquals(new BipEncoding(BipEncoding.JPEG, null), format.getEncoding()); Assert.assertEquals(BipPixel.createFixed(1280, 1024), format.getPixel()); @@ -173,8 +179,12 @@ public class BipImageFormatTest { @Test public void testCreateVariant_requiredOnly() { String expected = ""; - BipImageFormat format = BipImageFormat.createVariant( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(32, 32), -1, null); + BipImageFormat format = + BipImageFormat.createVariant( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(32, 32), + -1, + null); Assert.assertEquals(BipImageFormat.FORMAT_VARIANT, format.getType()); Assert.assertEquals(new BipEncoding(BipEncoding.JPEG, null), format.getEncoding()); Assert.assertEquals(BipPixel.createFixed(32, 32), format.getPixel()); @@ -186,12 +196,22 @@ public class BipImageFormatTest { @Test public void testCreateVariant_withTransformations() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.STRETCH, - BipTransformation.CROP, BipTransformation.FILL}); - String expected = ""; - BipImageFormat format = BipImageFormat.createVariant( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(32, 32), -1, trans); + BipTransformation trans = + new BipTransformation( + new int[] { + BipTransformation.STRETCH, + BipTransformation.CROP, + BipTransformation.FILL + }); + String expected = + ""; + BipImageFormat format = + BipImageFormat.createVariant( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(32, 32), + -1, + trans); Assert.assertEquals(BipImageFormat.FORMAT_VARIANT, format.getType()); Assert.assertEquals(new BipEncoding(BipEncoding.JPEG, null), format.getEncoding()); Assert.assertEquals(BipPixel.createFixed(32, 32), format.getPixel()); @@ -204,8 +224,12 @@ public class BipImageFormatTest { @Test public void testCreateVariant_withMaxsize() { String expected = ""; - BipImageFormat format = BipImageFormat.createVariant( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(32, 32), 123, null); + BipImageFormat format = + BipImageFormat.createVariant( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(32, 32), + 123, + null); Assert.assertEquals(BipImageFormat.FORMAT_VARIANT, format.getType()); Assert.assertEquals(new BipEncoding(BipEncoding.JPEG, null), format.getEncoding()); Assert.assertEquals(BipPixel.createFixed(32, 32), format.getPixel()); @@ -217,12 +241,22 @@ public class BipImageFormatTest { @Test public void testCreateVariant_allFields() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.STRETCH, - BipTransformation.CROP, BipTransformation.FILL}); - String expected = ""; - BipImageFormat format = BipImageFormat.createVariant( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(32, 32), 123, trans); + BipTransformation trans = + new BipTransformation( + new int[] { + BipTransformation.STRETCH, + BipTransformation.CROP, + BipTransformation.FILL + }); + String expected = + ""; + BipImageFormat format = + BipImageFormat.createVariant( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(32, 32), + 123, + trans); Assert.assertEquals(BipImageFormat.FORMAT_VARIANT, format.getType()); Assert.assertEquals(new BipEncoding(BipEncoding.JPEG, null), format.getEncoding()); Assert.assertEquals(BipPixel.createFixed(32, 32), format.getPixel()); @@ -264,28 +298,34 @@ public class BipImageFormatTest { @Test(expected = NullPointerException.class) public void testCreateFormat_noEncoding() { - BipImageFormat format = BipImageFormat.createNative(null, BipPixel.createFixed(1280, 1024), - -1); + BipImageFormat format = + BipImageFormat.createNative(null, BipPixel.createFixed(1280, 1024), -1); } @Test(expected = NullPointerException.class) public void testCreateFormat_noPixel() { - BipImageFormat format = BipImageFormat.createNative(new BipEncoding(BipEncoding.JPEG, null), - null, -1); + BipImageFormat format = + BipImageFormat.createNative(new BipEncoding(BipEncoding.JPEG, null), null, -1); } @Test public void testEquals_withSameInstance() { - BipImageFormat format = BipImageFormat.createNative( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(1280, 1024), -1); + BipImageFormat format = + BipImageFormat.createNative( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(1280, 1024), + -1); Assert.assertTrue(format.equals(format)); } @Test public void testEquals_withDifferentClass() { - BipImageFormat format = BipImageFormat.createNative( - new BipEncoding(BipEncoding.JPEG, null), BipPixel.createFixed(1280, 1024), -1); + BipImageFormat format = + BipImageFormat.createNative( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(1280, 1024), + -1); String notFormat = "notFormat"; Assert.assertFalse(format.equals(notFormat)); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java index dce9ab21b8e..d38b05b30a6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java @@ -26,9 +26,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; -/** - * A test suite for the BipImageProperties class - */ +/** A test suite for the BipImageProperties class */ @RunWith(AndroidJUnit4.class) public class BipImagePropertiesTest { private static final String IMAGE_HANDLE = "123456789"; @@ -39,18 +37,29 @@ public class BipImagePropertiesTest { // An image-properties tag with all available attributes private static final String IMAGE_PROPERTIES = - "\r\n"; + "\r\n"; // An image-properties tag without an xml version - OUT OF SPEC / INVALID private static final String IMAGE_PROPERTIES_NO_VERSION = - "\r\n"; + "\r\n"; // An image-properties tag without an image handle - OUT OF SPEC / INVALID private static final String IMAGE_PROPERTIES_NO_HANDLE = - "\r\n"; + "\r\n"; // An image-properties tag without an xml version - IN SPEC / VALID private static final String IMAGE_PROPERTIES_NO_FRIENDLY_NAME = @@ -71,7 +80,7 @@ public class BipImagePropertiesTest { // A variant format representing an range of sizes available. Has transformations and no size private static final String VARIANT_RANGE_FORMAT = " \r\n"; + + "transformation=\"stretch fill crop\" />\r\n"; // A variant format representing a range of sizes within a fixed aspect ratio. private static final String VARIANT_FIXED_RANGE_FORMAT = @@ -94,7 +103,7 @@ public class BipImagePropertiesTest { " \r\n"; private static final String ATTACHMENT_2 = " \r\n"; + + "/>\r\n"; private static final String IMAGE_PROPERTIES_END = ""; @@ -109,18 +118,19 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties with very simple information available. * - * This is the most common type of object we will receive. + *

This is the most common type of object we will receive. * - * Payload: - * - * - * - * "; + *

Payload: + * "; */ @Test public void testParsePropertiesSimple() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES_NO_FRIENDLY_NAME - + NATIVE_THUMBNAIL_FORMAT + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES_NO_FRIENDLY_NAME + + NATIVE_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -133,25 +143,29 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties with very rich information available. * - * This information includes attachments, which are not allowed in AVRCP-BIP but completely + *

This information includes attachments, which are not allowed in AVRCP-BIP but completely * allowed in standard BIP. * - * Payload: - * - * - * - * - * - * - * - * - * "; + *

Payload: + * "; */ @Test public void testParsePropertiesRich() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + NATIVE_THUMBNAIL_FORMAT - + VARIANT_FIXED_FORMAT + VARIANT_RANGE_FORMAT + VARIANT_FIXED_RANGE_FORMAT - + ATTACHMENT_1 + ATTACHMENT_2 + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES + + NATIVE_THUMBNAIL_FORMAT + + VARIANT_FIXED_FORMAT + + VARIANT_RANGE_FORMAT + + VARIANT_FIXED_RANGE_FORMAT + + ATTACHMENT_1 + + ATTACHMENT_2 + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -164,19 +178,20 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties without an image handle. * - * This is out of spec, but should not crash. Instead, the individual attributes should be + *

This is out of spec, but should not crash. Instead, the individual attributes should be * available and serializing should return null. * - * Payload: - * - * - * - * "; + *

Payload: + * "; */ @Test public void testParseNoHandle() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES_NO_HANDLE + NATIVE_THUMBNAIL_FORMAT - + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES_NO_HANDLE + + NATIVE_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(null, properties.getImageHandle()); @@ -190,19 +205,20 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties without a version. * - * This is out of spec, but should not crash. Instead, the individual attributes should be + *

This is out of spec, but should not crash. Instead, the individual attributes should be * available and serializing should return null. * - * Payload: - * - * - * - * "; + *

Payload: "; */ @Test public void testParseNoVersion() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES_NO_VERSION + NATIVE_THUMBNAIL_FORMAT - + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES_NO_VERSION + + NATIVE_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -216,18 +232,19 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties without a friendly name. * - * This is in spec, as friendly name isn't required. + *

This is in spec, as friendly name isn't required. * - * Payload: - * - * - * - * "; + *

Payload: "; */ @Test public void testParseNoFriendlyName() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES_NO_FRIENDLY_NAME - + NATIVE_THUMBNAIL_FORMAT + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES_NO_FRIENDLY_NAME + + NATIVE_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -240,16 +257,17 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties with a fixed variant thumbnail format * - * Payload: - * - * - * - * "; + *

Payload: "; */ @Test public void testParseFixedVariantThumbnailFormat() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + VARIANT_FIXED_THUMBNAIL_FORMAT - + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES + + VARIANT_FIXED_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -262,16 +280,17 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties with a range variant thumbnail format * - * Payload: - * - * - * - * "; + *

Payload: "; */ @Test public void testParseRangeVariantThumbnailFormat() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + VARIANT_RANGE_THUMBNAIL_FORMAT - + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES + + VARIANT_RANGE_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -284,16 +303,17 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties with a fixed aspect ratio range variant thumbnail format * - * Payload: - * - * - * - * "; + *

Payload: "; */ @Test public void testParseFixedRangeVariantThumbnailFormat() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + VARIANT_FIXED_RANGE_THUMBNAIL_FORMAT - + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES + + VARIANT_FIXED_RANGE_THUMBNAIL_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -306,19 +326,22 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties without any thumbnail formats * - * Payload: - * - * - * - * - * - * - * "; + *

Payload: "; */ @Test public void testParseNoThumbnailFormats() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + NATIVE_FORMAT + VARIANT_FIXED_FORMAT - + VARIANT_RANGE_FORMAT + VARIANT_FIXED_RANGE_FORMAT + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES + + NATIVE_FORMAT + + VARIANT_FIXED_FORMAT + + VARIANT_RANGE_FORMAT + + VARIANT_FIXED_RANGE_FORMAT + + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); Assert.assertEquals(IMAGE_HANDLE, properties.getImageHandle()); @@ -332,10 +355,8 @@ public class BipImagePropertiesTest { /** * Test parsing image-properties without any formats * - * Payload: - * - * - * "; + *

Payload: "; */ @Test public void testParseNoFormats() { @@ -349,20 +370,16 @@ public class BipImagePropertiesTest { Assert.assertEquals(null, properties.serialize()); } - /** - * Test parsing an image-properties with no open tag - */ - @Test (expected = ParseException.class) + /** Test parsing an image-properties with no open tag */ + @Test(expected = ParseException.class) public void testParseMalformedNoOpen() { String xmlString = XML_DOC_DECL + NATIVE_FORMAT + IMAGE_PROPERTIES_END; InputStream stream = toUtf8Stream(xmlString); BipImageProperties properties = new BipImageProperties(stream); } - /** - * Test parsing a malformed image-properties that just cuts out - */ - @Test (expected = ParseException.class) + /** Test parsing a malformed image-properties that just cuts out */ + @Test(expected = ParseException.class) public void testParseSimulateStreamEndedUnexpectedly() { String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + " - * - * - * - * - * - * - * - * "; + *

Expected Payload created: + * + * + * "; */ @Test public void testCreateProperties() { - String xmlString = XML_DOC_DECL + IMAGE_PROPERTIES + NATIVE_THUMBNAIL_FORMAT - + VARIANT_FIXED_FORMAT + VARIANT_RANGE_FORMAT + VARIANT_FIXED_RANGE_FORMAT - + ATTACHMENT_1 + ATTACHMENT_2 + IMAGE_PROPERTIES_END; + String xmlString = + XML_DOC_DECL + + IMAGE_PROPERTIES + + NATIVE_THUMBNAIL_FORMAT + + VARIANT_FIXED_FORMAT + + VARIANT_RANGE_FORMAT + + VARIANT_FIXED_RANGE_FORMAT + + ATTACHMENT_1 + + ATTACHMENT_2 + + IMAGE_PROPERTIES_END; BipTransformation trans = new BipTransformation(); trans.addTransformation(BipTransformation.STRETCH); @@ -397,21 +418,30 @@ public class BipImagePropertiesTest { BipImageProperties.Builder builder = new BipImageProperties.Builder(); builder.setImageHandle(IMAGE_HANDLE); builder.setFriendlyName(FRIENDLY_NAME); - builder.addNativeFormat(BipImageFormat.createNative(new BipEncoding(BipEncoding.JPEG, null), - BipPixel.createFixed(200, 200), -1)); + builder.addNativeFormat( + BipImageFormat.createNative( + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(200, 200), + -1)); builder.addVariantFormat( BipImageFormat.createVariant( - new BipEncoding(BipEncoding.JPEG, null), - BipPixel.createFixed(640, 480), -1, null)); + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createFixed(640, 480), + -1, + null)); builder.addVariantFormat( BipImageFormat.createVariant( - new BipEncoding(BipEncoding.GIF, null), - BipPixel.createResizableModified(80, 60, 640, 175), -1, trans)); + new BipEncoding(BipEncoding.GIF, null), + BipPixel.createResizableModified(80, 60, 640, 175), + -1, + trans)); builder.addVariantFormat( BipImageFormat.createVariant( - new BipEncoding(BipEncoding.JPEG, null), - BipPixel.createResizableFixed(150, 600, 120), -1, null)); + new BipEncoding(BipEncoding.JPEG, null), + BipPixel.createResizableFixed(150, 600, 120), + -1, + null)); builder.addAttachment( new BipAttachmentFormat("text/plain", null, "ABCD1234.txt", 5120, null, null)); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java index 7456434ae9c..5f028d1ba34 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java @@ -32,9 +32,7 @@ import org.junit.runner.RunWith; import java.io.InputStream; -/** - * A test suite for the BipImage class - */ +/** A test suite for the BipImage class */ @RunWith(AndroidJUnit4.class) public class BipImageTest { private static String sImageHandle = "123456789"; @@ -42,18 +40,18 @@ public class BipImageTest { @Before public void setUp() { - mTestResources = TestUtils.getTestApplicationResources( - InstrumentationRegistry.getTargetContext()); + mTestResources = + TestUtils.getTestApplicationResources(InstrumentationRegistry.getTargetContext()); } @Test public void testParseImage_200by200() { - InputStream imageInputStream = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_200_200); + InputStream imageInputStream = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_200_200); BipImage image = new BipImage(sImageHandle, imageInputStream); - InputStream expectedInputStream = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_200_200); + InputStream expectedInputStream = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_200_200); Bitmap bitmap = BitmapFactory.decodeStream(expectedInputStream); Assert.assertEquals(sImageHandle, image.getImageHandle()); @@ -62,12 +60,12 @@ public class BipImageTest { @Test public void testParseImage_600by600() { - InputStream imageInputStream = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_600_600); + InputStream imageInputStream = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_600_600); BipImage image = new BipImage(sImageHandle, imageInputStream); - InputStream expectedInputStream = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_600_600); + InputStream expectedInputStream = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_600_600); Bitmap bitmap = BitmapFactory.decodeStream(expectedInputStream); Assert.assertEquals(sImageHandle, image.getImageHandle()); @@ -76,8 +74,8 @@ public class BipImageTest { @Test public void testMakeFromImage_200by200() { - InputStream imageInputStream = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_200_200); + InputStream imageInputStream = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_200_200); Bitmap bitmap = BitmapFactory.decodeStream(imageInputStream); BipImage image = new BipImage(sImageHandle, bitmap); Assert.assertEquals(sImageHandle, image.getImageHandle()); @@ -86,8 +84,8 @@ public class BipImageTest { @Test public void testMakeFromImage_600by600() { - InputStream imageInputStream = mTestResources.openRawResource( - com.android.bluetooth.tests.R.raw.image_600_600); + InputStream imageInputStream = + mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.image_600_600); Bitmap bitmap = BitmapFactory.decodeStream(imageInputStream); BipImage image = new BipImage(sImageHandle, bitmap); Assert.assertEquals(sImageHandle, image.getImageHandle()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java index 11c0f339942..e40ef9cefc9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java @@ -22,14 +22,18 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -/** - * A test suite for the BipPixel class - */ +/** A test suite for the BipPixel class */ @RunWith(AndroidJUnit4.class) public class BipPixelTest { - private void testParse(String input, int pixelType, int minWidth, int minHeight, int maxWidth, - int maxHeight, String pixelStr) { + private void testParse( + String input, + int pixelType, + int minWidth, + int minHeight, + int maxWidth, + int maxHeight, + String pixelStr) { BipPixel pixel = new BipPixel(input); Assert.assertEquals(pixelType, pixel.getType()); Assert.assertEquals(minWidth, pixel.getMinWidth()); @@ -49,8 +53,8 @@ public class BipPixelTest { Assert.assertEquals(pixelStr, pixel.toString()); } - private void testResizableModified(int minWidth, int minHeight, int maxWidth, int maxHeight, - String pixelStr) { + private void testResizableModified( + int minWidth, int minHeight, int maxWidth, int maxHeight, String pixelStr) { BipPixel pixel = BipPixel.createResizableModified(minWidth, minHeight, maxWidth, maxHeight); Assert.assertEquals(BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, pixel.getType()); Assert.assertEquals(minWidth, pixel.getMinWidth()); @@ -60,8 +64,7 @@ public class BipPixelTest { Assert.assertEquals(pixelStr, pixel.toString()); } - private void testResizableFixed(int minWidth, int maxWidth, int maxHeight, - String pixelStr) { + private void testResizableFixed(int minWidth, int maxWidth, int maxHeight, String pixelStr) { int minHeight = (minWidth * maxHeight) / maxWidth; // spec defined BipPixel pixel = BipPixel.createResizableFixed(minWidth, maxWidth, maxHeight); Assert.assertEquals(BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, pixel.getType()); @@ -82,25 +85,73 @@ public class BipPixelTest { @Test public void testParseResizableModified() { - testParse("0*0-200*200", BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, 0, 0, 200, 200, + testParse( + "0*0-200*200", + BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, + 0, + 0, + 200, + 200, "0*0-200*200"); - testParse("200*200-600*600", BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, 200, 200, 600, 600, + testParse( + "200*200-600*600", + BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, + 200, + 200, + 600, + 600, "200*200-600*600"); - testParse("12*67-34*89", BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, 12, 67, 34, 89, + testParse( + "12*67-34*89", + BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, + 12, + 67, + 34, + 89, "12*67-34*89"); - testParse("123*456-1000*1000", BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, 123, 456, 1000, - 1000, "123*456-1000*1000"); + testParse( + "123*456-1000*1000", + BipPixel.TYPE_RESIZE_MODIFIED_ASPECT_RATIO, + 123, + 456, + 1000, + 1000, + "123*456-1000*1000"); } @Test public void testParseResizableFixed() { - testParse("0**-200*200", BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, 0, 0, 200, 200, + testParse( + "0**-200*200", + BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, + 0, + 0, + 200, + 200, "0**-200*200"); - testParse("200**-600*600", BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, 200, 200, 600, 600, + testParse( + "200**-600*600", + BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, + 200, + 200, + 600, + 600, "200**-600*600"); - testParse("123**-1000*1000", BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, 123, 123, 1000, 1000, + testParse( + "123**-1000*1000", + BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, + 123, + 123, + 1000, + 1000, "123**-1000*1000"); - testParse("12**-35*89", BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, 12, (12 * 89) / 35, 35, 89, + testParse( + "12**-35*89", + BipPixel.TYPE_RESIZE_FIXED_ASPECT_RATIO, + 12, + (12 * 89) / 35, + 35, + 89, "12**-35*89"); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java index 793b2df3803..53d653d3c0b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java @@ -22,9 +22,7 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -/** - * A test suite for the BipTransformation class - */ +/** A test suite for the BipTransformation class */ @RunWith(AndroidJUnit4.class) public class BipTransformationTest { @@ -257,7 +255,7 @@ public class BipTransformationTest { @Test public void testCreate_cropArray() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.CROP}); + BipTransformation trans = new BipTransformation(new int[] {BipTransformation.CROP}); Assert.assertFalse(trans.isSupported(BipTransformation.STRETCH)); Assert.assertFalse(trans.isSupported(BipTransformation.FILL)); Assert.assertTrue(trans.isSupported(BipTransformation.CROP)); @@ -266,8 +264,9 @@ public class BipTransformationTest { @Test public void testCreate_stretchFill() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.STRETCH, - BipTransformation.FILL}); + BipTransformation trans = + new BipTransformation( + new int[] {BipTransformation.STRETCH, BipTransformation.FILL}); Assert.assertTrue(trans.isSupported(BipTransformation.STRETCH)); Assert.assertTrue(trans.isSupported(BipTransformation.FILL)); Assert.assertFalse(trans.isSupported(BipTransformation.CROP)); @@ -276,8 +275,13 @@ public class BipTransformationTest { @Test public void testCreate_stretchFillCrop() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.STRETCH, - BipTransformation.FILL, BipTransformation.CROP}); + BipTransformation trans = + new BipTransformation( + new int[] { + BipTransformation.STRETCH, + BipTransformation.FILL, + BipTransformation.CROP + }); Assert.assertTrue(trans.isSupported(BipTransformation.STRETCH)); Assert.assertTrue(trans.isSupported(BipTransformation.FILL)); Assert.assertTrue(trans.isSupported(BipTransformation.CROP)); @@ -286,8 +290,13 @@ public class BipTransformationTest { @Test public void testCreate_stretchFillCropOrderChanged() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.CROP, - BipTransformation.FILL, BipTransformation.STRETCH}); + BipTransformation trans = + new BipTransformation( + new int[] { + BipTransformation.CROP, + BipTransformation.FILL, + BipTransformation.STRETCH + }); Assert.assertTrue(trans.isSupported(BipTransformation.STRETCH)); Assert.assertTrue(trans.isSupported(BipTransformation.FILL)); Assert.assertTrue(trans.isSupported(BipTransformation.CROP)); @@ -301,7 +310,7 @@ public class BipTransformationTest { @Test(expected = IllegalArgumentException.class) public void testCreate_badTransformation() { - BipTransformation trans = new BipTransformation(new int[]{BipTransformation.CROP, -7}); + BipTransformation trans = new BipTransformation(new int[] {BipTransformation.CROP, -7}); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java index d795dca157e..fb833c757b8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java @@ -31,18 +31,18 @@ public class RequestGetImagePropertiesTest { @Test public void constructor() { - RequestGetImageProperties requestGetImageProperties = new RequestGetImageProperties( - TEST_IMAGE_HANDLE); + RequestGetImageProperties requestGetImageProperties = + new RequestGetImageProperties(TEST_IMAGE_HANDLE); assertThat(requestGetImageProperties.getImageHandle()).isEqualTo(TEST_IMAGE_HANDLE); } @Test public void getType() { - RequestGetImageProperties requestGetImageProperties = new RequestGetImageProperties( - TEST_IMAGE_HANDLE); + RequestGetImageProperties requestGetImageProperties = + new RequestGetImageProperties(TEST_IMAGE_HANDLE); - assertThat(requestGetImageProperties.getType()).isEqualTo( - BipRequest.TYPE_GET_IMAGE_PROPERTIES); + assertThat(requestGetImageProperties.getType()) + .isEqualTo(BipRequest.TYPE_GET_IMAGE_PROPERTIES); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java index 8f55832574a..d68854b91e9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java @@ -40,9 +40,11 @@ public class RequestGetImageTest { RequestGetImage requestGetImage = new RequestGetImage(TEST_IMAGE_HANDLE, descriptor); - String expected = sXmlDocDecl + "\r\n" - + " \r\n" - + ""; + String expected = + sXmlDocDecl + + "\r\n" + + " \r\n" + + ""; assertThat(requestGetImage.getImageHandle()).isEqualTo(TEST_IMAGE_HANDLE); assertThat(requestGetImage.mImageDescriptor.toString()).isEqualTo(expected); } @@ -60,4 +62,4 @@ public class RequestGetImageTest { assertThat(requestGetImage.getType()).isEqualTo(BipRequest.TYPE_GET_IMAGE); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java index 697ab000016..1e7aaee9490 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java @@ -36,8 +36,7 @@ import org.mockito.junit.MockitoRule; public class BatteryServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private BatteryService mService; + @Mock private BatteryService mService; private BatteryService.BluetoothBatteryBinder mBinder; private BluetoothAdapter mAdapter; @@ -80,7 +79,7 @@ public class BatteryServiceBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] { BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.getDevicesMatchingConnectionStates(states, source); diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java index 64753a466d6..ddb36153ff8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java @@ -60,8 +60,7 @@ public class BatteryServiceTest { @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; - @Rule - public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Before public void setUp() throws Exception { @@ -78,11 +77,12 @@ public class BatteryServiceTest { startService(); // Override the timeout value to speed up the test - BatteryStateMachine.sConnectTimeoutMs = CONNECTION_TIMEOUT_MS; // 1s + BatteryStateMachine.sConnectTimeoutMs = CONNECTION_TIMEOUT_MS; // 1s // Get a device for testing mDevice = TestUtils.getTestDevice(mAdapter, 0); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); } @@ -104,108 +104,121 @@ public class BatteryServiceTest { Assert.assertNull(mService); } - /** - * Test get Battery Service - */ + /** Test get Battery Service */ @Test public void testGetBatteryService() { Assert.assertEquals(mService, BatteryService.getBatteryService()); } - /** - * Test get/set policy for BluetoothDevice - */ + /** Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() { - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", + Assert.assertEquals( + "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mService.getConnectionPolicy(mDevice)); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - Assert.assertEquals("Setting device policy to POLICY_FORBIDDEN", + Assert.assertEquals( + "Setting device policy to POLICY_FORBIDDEN", BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, mService.getConnectionPolicy(mDevice)); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - Assert.assertEquals("Setting device policy to POLICY_ALLOWED", + Assert.assertEquals( + "Setting device policy to POLICY_ALLOWED", BluetoothProfile.CONNECTION_POLICY_ALLOWED, mService.getConnectionPolicy(mDevice)); } - /** - * Test if getProfileConnectionPolicy works after the service is stopped. - */ + /** Test if getProfileConnectionPolicy works after the service is stopped. */ @Test public void testGetPolicyAfterStopped() { mService.stop(); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", + Assert.assertEquals( + "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mService.getConnectionPolicy(mDevice)); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testCanConnect() { int badPolicyValue = 1024; int badBondState = 42; - testCanConnectCase(mDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_NONE, badPolicyValue, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, badPolicyValue, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testCanConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, badPolicyValue, false); - testCanConnectCase(mDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testCanConnectCase(mDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testCanConnectCase(mDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testCanConnectCase(mDevice, - badBondState, badPolicyValue, false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testCanConnectCase(mDevice, BluetoothDevice.BOND_NONE, badPolicyValue, false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testCanConnectCase(mDevice, BluetoothDevice.BOND_BONDING, badPolicyValue, false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testCanConnectCase( + mDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testCanConnectCase(mDevice, BluetoothDevice.BOND_BONDED, badPolicyValue, false); + testCanConnectCase( + mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testCanConnectCase( + mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); + testCanConnectCase( + mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testCanConnectCase(mDevice, badBondState, badPolicyValue, false); } - /** - * Test that an outgoing connection to device - */ + /** Test that an outgoing connection to device */ @Test public void testConnectAndDump() { // Update the device policy so okToConnect() returns true when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Return Battery UUID - doReturn(new ParcelUuid[]{BluetoothUuid.BATTERY}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.BATTERY}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request Assert.assertTrue("Connect expected to succeed", mService.connect(mDevice)); @@ -214,15 +227,12 @@ public class BatteryServiceTest { mService.dump(new StringBuilder()); } - /** - * Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected - */ + /** Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected */ @Test public void testForbiddenPolicy_FailsToConnect() { // Set the device policy to POLICY_FORBIDDEN so connect() should fail when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.BATTERY)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Send a connect request @@ -231,8 +241,8 @@ public class BatteryServiceTest { @Test public void getConnectionState_whenNoDevicesAreConnected_returnsDisconnectedState() { - Assert.assertEquals(mService.getConnectionState(mDevice), - BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + mService.getConnectionState(mDevice), BluetoothProfile.STATE_DISCONNECTED); } @Test @@ -250,20 +260,21 @@ public class BatteryServiceTest { @Test public void setConnectionPolicy() { - Assert.assertTrue(mService.setConnectionPolicy( - mDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)); + Assert.assertTrue( + mService.setConnectionPolicy( + mDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)); } /** - * Helper function to test okToConnect() method + * Helper function to test okToConnect() method * - * @param device test device - * @param bondState bond state value, could be invalid - * @param policy value, could be invalid - * @param expected expected result from okToConnect() + * @param device test device + * @param bondState bond state value, could be invalid + * @param policy value, could be invalid + * @param expected expected result from okToConnect() */ - private void testCanConnectCase(BluetoothDevice device, int bondState, int policy, - boolean expected) { + private void testCanConnectCase( + BluetoothDevice device, int bondState, int policy, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.BATTERY)) diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java index 6436fbe8788..caf512457fa 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java @@ -62,8 +62,7 @@ import org.mockito.junit.MockitoRule; @LargeTest @RunWith(JUnit4.class) public class BatteryStateMachineTest { - @Rule - public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule public final MockitoRule mockito = MockitoJUnit.rule(); private BluetoothAdapter mAdapter; private Context mTargetContext; @@ -90,8 +89,9 @@ public class BatteryStateMachineTest { // Set up thread and looper mHandlerThread = new HandlerThread("BatteryStateMachineTestHandlerThread"); mHandlerThread.start(); - mBatteryStateMachine = new StubBatteryStateMachine(mTestDevice, - mBatteryService, mHandlerThread.getLooper()); + mBatteryStateMachine = + new StubBatteryStateMachine( + mTestDevice, mBatteryService, mHandlerThread.getLooper()); // Override the timeout value to speed up the test mBatteryStateMachine.sConnectTimeoutMs = CONNECTION_TIMEOUT_MS; mBatteryStateMachine.start(); @@ -105,13 +105,11 @@ public class BatteryStateMachineTest { reset(mBatteryService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mBatteryStateMachine.getConnectionState()); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mBatteryStateMachine.getConnectionState()); } /** @@ -127,9 +125,7 @@ public class BatteryStateMachineTest { mBatteryStateMachine.mShouldAllowGatt = allow; } - /** - * Test that an incoming connection with policy forbidding connection is rejected - */ + /** Test that an incoming connection with policy forbidding connection is rejected */ @Test public void testOkToConnectFails() { allowConnection(false); @@ -142,7 +138,8 @@ public class BatteryStateMachineTest { .handleConnectionStateChanged(any(BatteryStateMachine.class), anyInt(), anyInt()); // Check that we are in Disconnected state - Assert.assertThat(mBatteryStateMachine.getCurrentState(), + Assert.assertThat( + mBatteryStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BatteryStateMachine.Disconnected.class)); } @@ -158,7 +155,8 @@ public class BatteryStateMachineTest { .handleConnectionStateChanged(any(BatteryStateMachine.class), anyInt(), anyInt()); // Check that we are in Disconnected state - Assert.assertThat(mBatteryStateMachine.getCurrentState(), + Assert.assertThat( + mBatteryStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BatteryStateMachine.Disconnected.class)); assertNull(mBatteryStateMachine.mBluetoothGatt); } @@ -172,11 +170,13 @@ public class BatteryStateMachineTest { mBatteryStateMachine.sendMessage(BatteryStateMachine.CONNECT); verify(mBatteryService, timeout(TIMEOUT_MS)) - .handleConnectionStateChanged(any(BatteryStateMachine.class), + .handleConnectionStateChanged( + any(BatteryStateMachine.class), eq(BluetoothProfile.STATE_DISCONNECTED), eq(BluetoothProfile.STATE_CONNECTING)); - Assert.assertThat(mBatteryStateMachine.getCurrentState(), + Assert.assertThat( + mBatteryStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BatteryStateMachine.Connecting.class)); assertNotNull(mBatteryStateMachine.mGattCallback); @@ -184,11 +184,13 @@ public class BatteryStateMachineTest { GATT_SUCCESS, BluetoothProfile.STATE_CONNECTED); verify(mBatteryService, timeout(TIMEOUT_MS)) - .handleConnectionStateChanged(any(BatteryStateMachine.class), + .handleConnectionStateChanged( + any(BatteryStateMachine.class), eq(BluetoothProfile.STATE_CONNECTING), eq(BluetoothProfile.STATE_CONNECTED)); - Assert.assertThat(mBatteryStateMachine.getCurrentState(), + Assert.assertThat( + mBatteryStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BatteryStateMachine.Connected.class)); } @@ -200,14 +202,16 @@ public class BatteryStateMachineTest { mBatteryStateMachine.sendMessage(BatteryStateMachine.CONNECT); verify(mBatteryService, timeout(TIMEOUT_MS)) - .handleConnectionStateChanged(any(BatteryStateMachine.class), + .handleConnectionStateChanged( + any(BatteryStateMachine.class), eq(BluetoothProfile.STATE_DISCONNECTED), eq(BluetoothProfile.STATE_CONNECTING)); mBatteryStateMachine.sendMessage(BatteryStateMachine.DISCONNECT); verify(mBatteryService, timeout(TIMEOUT_MS)) - .handleConnectionStateChanged(any(BatteryStateMachine.class), + .handleConnectionStateChanged( + any(BatteryStateMachine.class), eq(BluetoothProfile.STATE_CONNECTING), eq(BluetoothProfile.STATE_DISCONNECTED)); } @@ -262,8 +266,7 @@ public class BatteryStateMachineTest { reconnect(); int badState = -1; - mBatteryStateMachine.sendMessage( - BatteryStateMachine.CONNECTION_STATE_CHANGED, badState); + mBatteryStateMachine.sendMessage(BatteryStateMachine.CONNECTION_STATE_CHANGED, badState); assertThat(mBatteryStateMachine.getCurrentState()) .isInstanceOf(BatteryStateMachine.Connected.class); @@ -378,4 +381,3 @@ public class BatteryStateMachineTest { } } } - diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java index 8b3909b8d77..445be0e2b5f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java @@ -102,7 +102,7 @@ public class BaseDataTest { BaseData data = BaseData.parseBaseData(serviceData); BaseData.BaseInformation level = data.getLevelOne(); - assertThat(level.presentationDelay).isEqualTo(new byte[] { 0x01, 0x02, 0x03 }); + assertThat(level.presentationDelay).isEqualTo(new byte[] {0x01, 0x02, 0x03}); assertThat(level.numSubGroups).isEqualTo(1); assertThat(data.getLevelTwo().size()).isEqualTo(1); diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java index 51e1820bb2a..1ed76c09cbf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java @@ -104,9 +104,7 @@ import java.util.Set; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; -/** - * Tests for {@link BassClientService} - */ +/** Tests for {@link BassClientService} */ @MediumTest @RunWith(AndroidJUnit4.class) public class BassClientServiceTest { @@ -142,7 +140,6 @@ public class BassClientServiceTest { private static final int TEST_SOURCE_ID = 10; private static final int TEST_NUM_SOURCES = 2; - private static final int TEST_MAX_NUM_DEVICES = 3; private final HashMap mStateMachines = new HashMap<>(); @@ -177,18 +174,23 @@ public class BassClientServiceTest { BluetoothLeBroadcastSubgroup createBroadcastSubgroup() { BluetoothLeAudioCodecConfigMetadata codecMetadata = new BluetoothLeAudioCodecConfigMetadata.Builder() - .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_LEFT).build(); + .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_LEFT) + .build(); BluetoothLeAudioContentMetadata contentMetadata = new BluetoothLeAudioContentMetadata.Builder() - .setProgramInfo(TEST_PROGRAM_INFO).setLanguage(TEST_LANGUAGE).build(); - BluetoothLeBroadcastSubgroup.Builder builder = new BluetoothLeBroadcastSubgroup.Builder() - .setCodecId(TEST_CODEC_ID) - .setCodecSpecificConfig(codecMetadata) - .setContentMetadata(contentMetadata); + .setProgramInfo(TEST_PROGRAM_INFO) + .setLanguage(TEST_LANGUAGE) + .build(); + BluetoothLeBroadcastSubgroup.Builder builder = + new BluetoothLeBroadcastSubgroup.Builder() + .setCodecId(TEST_CODEC_ID) + .setCodecSpecificConfig(codecMetadata) + .setContentMetadata(contentMetadata); BluetoothLeAudioCodecConfigMetadata channelCodecMetadata = new BluetoothLeAudioCodecConfigMetadata.Builder() - .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_RIGHT).build(); + .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_RIGHT) + .build(); // builder expect at least one channel BluetoothLeBroadcastChannel channel = @@ -202,10 +204,12 @@ public class BassClientServiceTest { } BluetoothLeBroadcastMetadata createBroadcastMetadata(int broadcastId) { - BluetoothDevice testDevice = mBluetoothAdapter.getRemoteLeDevice(TEST_MAC_ADDRESS, - BluetoothDevice.ADDRESS_TYPE_RANDOM); + BluetoothDevice testDevice = + mBluetoothAdapter.getRemoteLeDevice( + TEST_MAC_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM); - BluetoothLeBroadcastMetadata.Builder builder = new BluetoothLeBroadcastMetadata.Builder() + BluetoothLeBroadcastMetadata.Builder builder = + new BluetoothLeBroadcastMetadata.Builder() .setEncrypted(false) .setSourceDevice(testDevice, BluetoothDevice.ADDRESS_TYPE_RANDOM) .setSourceAdvertisingSid(TEST_ADVERTISER_SID) @@ -236,21 +240,27 @@ public class BassClientServiceTest { any(), any(), anyInt(), anyInt(), any(), any()); doNothing().when(mMethodProxy).periodicAdvertisingManagerUnregisterSync(any(), any()); - doReturn(new ParcelUuid[]{BluetoothUuid.BASS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.BASS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // This line must be called to make sure relevant objects are initialized properly mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // Mock methods in AdapterService - doReturn(FAKE_SERVICE_UUIDS).when(mAdapterService) + doReturn(FAKE_SERVICE_UUIDS) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doAnswer(invocation -> { - Set keys = mStateMachines.keySet(); - return keys.toArray(new BluetoothDevice[keys.size()]); - }).when(mAdapterService).getBondedDevices(); + doAnswer( + invocation -> { + Set keys = mStateMachines.keySet(); + return keys.toArray(new BluetoothDevice[keys.size()]); + }) + .when(mAdapterService) + .getBondedDevices(); // Mock methods in BassObjectsFactory doAnswer( @@ -271,7 +281,8 @@ public class BassClientServiceTest { }) .when(mObjectsFactory) .makeStateMachine(any(), any(), any(), any()); - doReturn(mBluetoothLeScannerWrapper).when(mObjectsFactory) + doReturn(mBluetoothLeScannerWrapper) + .when(mObjectsFactory) .getBluetoothLeScannerWrapper(any()); mBassClientService = new BassClientService(mTargetContext); @@ -339,8 +350,7 @@ public class BassClientServiceTest { } try { - BluetoothDevice device = intent.getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); assertThat(device).isNotNull(); LinkedBlockingQueue queue = mIntentQueue.get(device); assertThat(queue).isNotNull(); @@ -351,9 +361,7 @@ public class BassClientServiceTest { } } - /** - * Test to verify that BassClientService can be successfully started - */ + /** Test to verify that BassClientService can be successfully started */ @Test public void testGetBassClientService() { assertThat(mBassClientService).isEqualTo(BassClientService.getBassClientService()); @@ -363,53 +371,46 @@ public class BassClientServiceTest { .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); } - /** - * Test if getProfileConnectionPolicy works after the service is stopped. - */ + /** Test if getProfileConnectionPolicy works after the service is stopped. */ @Test public void testGetPolicyAfterStopped() { mBassClientService.stop(); - when(mDatabaseManager - .getProfileConnectionPolicy(mCurrentDevice, - BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)) + when(mDatabaseManager.getProfileConnectionPolicy( + mCurrentDevice, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", + Assert.assertEquals( + "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mBassClientService.getConnectionPolicy(mCurrentDevice)); } /** - * Test connecting to a test device. - * - service.connect() should return false - * - bassClientStateMachine.sendMessage(CONNECT) should be called. + * Test connecting to a test device. - service.connect() should return false - + * bassClientStateMachine.sendMessage(CONNECT) should be called. */ @Test public void testConnect() { - when(mDatabaseManager.getProfileConnectionPolicy(any(BluetoothDevice.class), - eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) + when(mDatabaseManager.getProfileConnectionPolicy( + any(BluetoothDevice.class), + eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); mCurrentDevice = TestUtils.getTestDevice(mBluetoothAdapter, 0); assertThat(mBassClientService.connect(mCurrentDevice)).isTrue(); verify(mObjectsFactory) .makeStateMachine( - eq(mCurrentDevice), - eq(mBassClientService), - eq(mAdapterService), - any()); + eq(mCurrentDevice), eq(mBassClientService), eq(mAdapterService), any()); BassClientStateMachine stateMachine = mStateMachines.get(mCurrentDevice); assertThat(stateMachine).isNotNull(); verify(stateMachine).sendMessage(BassClientStateMachine.CONNECT); } - /** - * Test connecting to a null device. - * - service.connect() should return false. - */ + /** Test connecting to a null device. - service.connect() should return false. */ @Test public void testConnect_nullDevice() { - when(mDatabaseManager.getProfileConnectionPolicy(any(BluetoothDevice.class), - eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) + when(mDatabaseManager.getProfileConnectionPolicy( + any(BluetoothDevice.class), + eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); BluetoothDevice nullDevice = null; @@ -417,13 +418,14 @@ public class BassClientServiceTest { } /** - * Test connecting to a device when the connection policy is forbidden. - * - service.connect() should return false. + * Test connecting to a device when the connection policy is forbidden. - service.connect() + * should return false. */ @Test public void testConnect_whenConnectionPolicyIsForbidden() { - when(mDatabaseManager.getProfileConnectionPolicy(any(BluetoothDevice.class), - eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) + when(mDatabaseManager.getProfileConnectionPolicy( + any(BluetoothDevice.class), + eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); mCurrentDevice = TestUtils.getTestDevice(mBluetoothAdapter, 0); assertThat(mCurrentDevice).isNotNull(); @@ -467,9 +469,10 @@ public class BassClientServiceTest { } private void prepareConnectedDeviceGroup() { - when(mDatabaseManager.getProfileConnectionPolicy(any(BluetoothDevice.class), + when(mDatabaseManager.getProfileConnectionPolicy( + any(BluetoothDevice.class), eq(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT))) - .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); mCurrentDevice = TestUtils.getTestDevice(mBluetoothAdapter, 0); mCurrentDevice1 = TestUtils.getTestDevice(mBluetoothAdapter, 1); @@ -481,9 +484,11 @@ public class BassClientServiceTest { List groupDevices = new ArrayList<>(); groupDevices.add(mCurrentDevice); groupDevices.add(mCurrentDevice1); - doReturn(groupDevices).when(mCsipService) + doReturn(groupDevices) + .when(mCsipService) .getGroupDevicesOrdered(mCurrentDevice, BluetoothUuid.CAP); - doReturn(groupDevices).when(mCsipService) + doReturn(groupDevices) + .when(mCsipService) .getGroupDevicesOrdered(mCurrentDevice1, BluetoothUuid.CAP); // Prepare connected devices @@ -491,38 +496,45 @@ public class BassClientServiceTest { assertThat(mBassClientService.connect(mCurrentDevice1)).isTrue(); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { // Verify the call verify(sm).sendMessage(eq(BassClientStateMachine.CONNECT)); // Notify the service about the connection event BluetoothDevice dev = sm.getDevice(); - doCallRealMethod().when(sm) - .broadcastConnectionState(eq(dev), any(Integer.class), any(Integer.class)); + doCallRealMethod() + .when(sm) + .broadcastConnectionState(eq(dev), any(Integer.class), any(Integer.class)); sm.mService = mBassClientService; sm.mDevice = dev; - sm.broadcastConnectionState(dev, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_CONNECTED); + sm.broadcastConnectionState( + dev, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED); doReturn(BluetoothProfile.STATE_CONNECTED).when(sm).getConnectionState(); doReturn(true).when(sm).isConnected(); // Inject initial broadcast source state BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null); + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID); - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null); + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 1); } } @@ -926,16 +938,16 @@ public class BassClientServiceTest { syncHandle, testDevice, TEST_ADVERTISER_SID, 0, 200, BluetoothGatt.GATT_SUCCESS); } - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, int newState, - int prevState) { + private void verifyConnectionStateIntent( + int timeoutMs, BluetoothDevice device, int newState, int prevState) { Intent intent = TestUtils.waitForIntent(timeoutMs, mIntentQueue.get(device)); assertThat(intent).isNotNull(); assertThat(BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED) .isEqualTo(intent.getAction()); assertThat(device).isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); assertThat(newState).isEqualTo(intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - assertThat(prevState).isEqualTo(intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - -1)); + assertThat(prevState) + .isEqualTo(intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); } private void handleHandoverSupport() { @@ -955,40 +967,48 @@ public class BassClientServiceTest { // Verify all group members getting ADD_BCAST_SOURCE message assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Message msg = messageCaptor.getAllValues().stream() - .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE) - && (m.obj == meta)) - .findFirst() - .orElse(null); + Message msg = + messageCaptor.getAllValues().stream() + .filter( + m -> + (m.what == BassClientStateMachine.ADD_BCAST_SOURCE) + && (m.obj == meta)) + .findFirst() + .orElse(null); assertThat(msg).isNotNull(); } } - private BluetoothLeBroadcastReceiveState injectRemoteSourceState(BassClientStateMachine sm, - BluetoothLeBroadcastMetadata meta, int sourceId, int paSynState, int encryptionState, - byte[] badCode, long bisSyncState) { - BluetoothLeBroadcastReceiveState recvState = new BluetoothLeBroadcastReceiveState( - sourceId, - meta.getSourceAddressType(), - meta.getSourceDevice(), - meta.getSourceAdvertisingSid(), - meta.getBroadcastId(), - paSynState, - encryptionState, - badCode, - meta.getSubgroups().size(), - // Bis sync states - meta.getSubgroups().stream() - .map(e -> bisSyncState) - .collect(Collectors.toList()), - meta.getSubgroups().stream() + private BluetoothLeBroadcastReceiveState injectRemoteSourceState( + BassClientStateMachine sm, + BluetoothLeBroadcastMetadata meta, + int sourceId, + int paSynState, + int encryptionState, + byte[] badCode, + long bisSyncState) { + BluetoothLeBroadcastReceiveState recvState = + new BluetoothLeBroadcastReceiveState( + sourceId, + meta.getSourceAddressType(), + meta.getSourceDevice(), + meta.getSourceAdvertisingSid(), + meta.getBroadcastId(), + paSynState, + encryptionState, + badCode, + meta.getSubgroups().size(), + // Bis sync states + meta.getSubgroups().stream() + .map(e -> bisSyncState) + .collect(Collectors.toList()), + meta.getSubgroups().stream() .map(e -> e.getContentMetadata()) - .collect(Collectors.toList()) - ); + .collect(Collectors.toList())); doReturn(meta).when(sm).getCurrentBroadcastMetadata(eq(sourceId)); List stateList = sm.getAllSources(); @@ -1004,28 +1024,46 @@ public class BassClientServiceTest { } private BluetoothLeBroadcastReceiveState injectRemoteSourceStateSourceAdded( - BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId, - int paSynState, int encryptionState, byte[] badCode) { + BassClientStateMachine sm, + BluetoothLeBroadcastMetadata meta, + int sourceId, + int paSynState, + int encryptionState, + byte[] badCode) { BluetoothLeBroadcastReceiveState recvState = - injectRemoteSourceState(sm, meta, sourceId, paSynState, encryptionState, badCode, + injectRemoteSourceState( + sm, + meta, + sourceId, + paSynState, + encryptionState, + badCode, (long) 0x00000002); - mBassClientService.getCallbacks().notifySourceAdded(sm.getDevice(), recvState, - BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + mBassClientService + .getCallbacks() + .notifySourceAdded( + sm.getDevice(), recvState, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); return recvState; } private BluetoothLeBroadcastReceiveState injectRemoteSourceStateChanged( - BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId, - int paSynState, int encryptionState, byte[] badCode, long bisSyncState) { + BassClientStateMachine sm, + BluetoothLeBroadcastMetadata meta, + int sourceId, + int paSynState, + int encryptionState, + byte[] badCode, + long bisSyncState) { BluetoothLeBroadcastReceiveState recvState = - injectRemoteSourceState(sm, meta, sourceId, paSynState, encryptionState, badCode, - bisSyncState); + injectRemoteSourceState( + sm, meta, sourceId, paSynState, encryptionState, badCode, bisSyncState); - mBassClientService.getCallbacks().notifyReceiveStateChanged(sm.getDevice(), - recvState.getSourceId(), recvState); + mBassClientService + .getCallbacks() + .notifyReceiveStateChanged(sm.getDevice(), recvState.getSourceId(), recvState); TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); return recvState; @@ -1034,35 +1072,37 @@ public class BassClientServiceTest { private void injectRemoteSourceStateRemoval(BassClientStateMachine sm, int sourceId) { List stateList = sm.getAllSources(); if (stateList == null) { - stateList = new ArrayList(); + stateList = new ArrayList(); } - stateList.replaceAll(e -> { - if (e.getSourceId() != sourceId) return e; - return new BluetoothLeBroadcastReceiveState( - sourceId, - BluetoothDevice.ADDRESS_TYPE_PUBLIC, - mBluetoothAdapter.getRemoteLeDevice("00:00:00:00:00:00", - BluetoothDevice.ADDRESS_TYPE_PUBLIC), - 0, - 0, - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, - 0, - Arrays.asList(new Long[0]), - Arrays.asList(new BluetoothLeAudioContentMetadata[0]) - ); - }); + stateList.replaceAll( + e -> { + if (e.getSourceId() != sourceId) return e; + return new BluetoothLeBroadcastReceiveState( + sourceId, + BluetoothDevice.ADDRESS_TYPE_PUBLIC, + mBluetoothAdapter.getRemoteLeDevice( + "00:00:00:00:00:00", BluetoothDevice.ADDRESS_TYPE_PUBLIC), + 0, + 0, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, + 0, + Arrays.asList(new Long[0]), + Arrays.asList(new BluetoothLeAudioContentMetadata[0])); + }); doReturn(stateList).when(sm).getAllSources(); - mBassClientService.getCallbacks().notifySourceRemoved(sm.getDevice(), sourceId, - BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + mBassClientService + .getCallbacks() + .notifySourceRemoved( + sm.getDevice(), sourceId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); } /** - * Test whether service.addSource() does send proper messages to all the - * state machines within the Csip coordinated group + * Test whether service.addSource() does send proper messages to all the state machines within + * the Csip coordinated group */ @Test public void testAddSourceForGroup() { @@ -1074,10 +1114,7 @@ public class BassClientServiceTest { verifyAddSourceForGroup(meta); } - - /** - * Test whether service.addSource() source id can be propagated through callback correctly - */ + /** Test whether service.addSource() source id can be propagated through callback correctly */ @Test public void testAddSourceCallbackForGroup() { prepareConnectedDeviceGroup(); @@ -1086,43 +1123,56 @@ public class BassClientServiceTest { onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); // verify source id try { - verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()). - onSourceAdded(eq(mCurrentDevice), eq(TEST_SOURCE_ID), - eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); + verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onSourceAdded( + eq(mCurrentDevice), + eq(TEST_SOURCE_ID), + eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); // verify source id try { - verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()). - onSourceAdded(eq(mCurrentDevice1), eq(TEST_SOURCE_ID + 1), - eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); + verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onSourceAdded( + eq(mCurrentDevice1), + eq(TEST_SOURCE_ID + 1), + eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } } - /** - * Test whether service.modifySource() does send proper messages to all the - * state machines within the Csip coordinated group + + /** + * Test whether service.modifySource() does send proper messages to all the state machines + * within the Csip coordinated group */ @Test public void testModifySourceForGroup() { @@ -1132,20 +1182,28 @@ public class BassClientServiceTest { onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } } @@ -1153,18 +1211,20 @@ public class BassClientServiceTest { // Update broadcast source using other member of the same group BluetoothLeBroadcastMetadata metaUpdate = new BluetoothLeBroadcastMetadata.Builder(meta) - .setBroadcastId(TEST_BROADCAST_ID + 1).build(); + .setBroadcastId(TEST_BROADCAST_ID + 1) + .build(); mBassClientService.modifySource(mCurrentDevice1, TEST_SOURCE_ID + 1, metaUpdate); // Verify all group members getting UPDATE_BCAST_SOURCE message on proper sources assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); assertThat(msg.get().obj).isEqualTo(metaUpdate); @@ -1178,8 +1238,8 @@ public class BassClientServiceTest { } /** - * Test whether service.removeSource() does send proper messages to all the - * state machines within the Csip coordinated group + * Test whether service.removeSource() does send proper messages to all the state machines + * within the Csip coordinated group */ @Test public void testRemoveSourceForGroup() { @@ -1189,20 +1249,28 @@ public class BassClientServiceTest { onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } } @@ -1212,13 +1280,14 @@ public class BassClientServiceTest { // Verify all group members getting REMOVE_BCAST_SOURCE message assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); // Verify using the right sourceId on each device @@ -1316,9 +1385,7 @@ public class BassClientServiceTest { } } - /** - * Test whether the group operation flag is set on addSource() and removed on removeSource - */ + /** Test whether the group operation flag is set on addSource() and removed on removeSource */ @Test public void testGroupStickyFlagSetUnset() { prepareConnectedDeviceGroup(); @@ -1328,20 +1395,28 @@ public class BassClientServiceTest { BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); // Inject source added - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } } @@ -1349,13 +1424,14 @@ public class BassClientServiceTest { // Remove broadcast source mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); // Inject source removed - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); if (sm.getDevice().equals(mCurrentDevice)) { @@ -1376,19 +1452,21 @@ public class BassClientServiceTest { // Verrify that one device got the message... verify(mStateMachines.get(mCurrentDevice), atLeast(1)).sendMessage(messageCaptor.capture()); - msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) - .findFirst(); + msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isTrue(); assertThat(msg.orElse(null)).isNotNull(); - //... but not the other one, since the sticky group flag should have been removed + // ... but not the other one, since the sticky group flag should have been removed messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mStateMachines.get(mCurrentDevice1), atLeast(1)) .sendMessage(messageCaptor.capture()); - msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) - .findFirst(); + msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isFalse(); } @@ -1450,8 +1528,8 @@ public class BassClientServiceTest { } /** - * Test that after multiple calls to service.addSource() with a group operation flag set, - * there are two call to service.removeSource() needed to clear the flag + * Test that after multiple calls to service.addSource() with a group operation flag set, there + * are two call to service.removeSource() needed to clear the flag */ @Test public void testAddRemoveMultipleSourcesForGroup() { @@ -1462,20 +1540,28 @@ public class BassClientServiceTest { onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); verifyAddSourceForGroup(meta); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else { throw new AssertionError("Unexpected device"); @@ -1485,25 +1571,34 @@ public class BassClientServiceTest { // Add another broadcast source BluetoothLeBroadcastMetadata meta1 = new BluetoothLeBroadcastMetadata.Builder(meta) - .setBroadcastId(TEST_BROADCAST_ID + 1).build(); + .setBroadcastId(TEST_BROADCAST_ID + 1) + .build(); onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); verifyAddSourceForGroup(meta1); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta1, TEST_SOURCE_ID + 2, + injectRemoteSourceStateSourceAdded( + sm, + meta1, + TEST_SOURCE_ID + 2, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta1.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta1.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta1, TEST_SOURCE_ID + 3, + injectRemoteSourceStateSourceAdded( + sm, + meta1, + TEST_SOURCE_ID + 3, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta1.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta1.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else { throw new AssertionError("Unexpected device"); @@ -1513,13 +1608,14 @@ public class BassClientServiceTest { // Remove the first broadcast source mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); // Verify using the right sourceId on each device @@ -1538,21 +1634,22 @@ public class BassClientServiceTest { BluetoothLeBroadcastMetadata metaUpdate = createBroadcastMetadata(TEST_BROADCAST_ID + 3); mBassClientService.modifySource(mCurrentDevice1, TEST_SOURCE_ID + 3, metaUpdate); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); assertThat(msg.get().obj).isEqualTo(metaUpdate); // Verify using the right sourceId on each device if (sm.getDevice().equals(mCurrentDevice)) { - assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 2); + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 2); } else if (sm.getDevice().equals(mCurrentDevice1)) { - assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 3); + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 3); } else { throw new AssertionError("Unexpected device"); } @@ -1562,22 +1659,32 @@ public class BassClientServiceTest { // REMOVE_BCAST_SOURCE message for the second source mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID + 2); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); if (sm.getDevice().equals(mCurrentDevice)) { - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> (m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) - && (m.arg1 == TEST_SOURCE_ID + 2)) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter( + m -> + (m.what + == BassClientStateMachine + .REMOVE_BCAST_SOURCE) + && (m.arg1 == TEST_SOURCE_ID + 2)) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 2); } else if (sm.getDevice().equals(mCurrentDevice1)) { - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> (m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) - && (m.arg1 == TEST_SOURCE_ID + 3)) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter( + m -> + (m.what + == BassClientStateMachine + .REMOVE_BCAST_SOURCE) + && (m.arg1 == TEST_SOURCE_ID + 3)) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 3); } else { @@ -1586,32 +1693,40 @@ public class BassClientServiceTest { } // Fake the autonomous source change - or other client setting the source - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { clearInvocations(sm); BluetoothLeBroadcastMetadata metaOther = createBroadcastMetadata(TEST_BROADCAST_ID + 20); - injectRemoteSourceStateSourceAdded(sm, metaOther, TEST_SOURCE_ID + 20, + injectRemoteSourceStateSourceAdded( + sm, + metaOther, + TEST_SOURCE_ID + 20, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } // Modify this source and verify it is not group managed BluetoothLeBroadcastMetadata metaUpdate2 = createBroadcastMetadata(TEST_BROADCAST_ID + 30); mBassClientService.modifySource(mCurrentDevice1, TEST_SOURCE_ID + 20, metaUpdate2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { verify(sm, never()).sendMessage(any()); } else if (sm.getDevice().equals(mCurrentDevice1)) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, times(1)).sendMessage(messageCaptor.capture()); - List msgs = messageCaptor.getAllValues().stream() - .filter(m -> (m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) - && (m.arg1 == TEST_SOURCE_ID + 20)) - .collect(Collectors.toList()); + List msgs = + messageCaptor.getAllValues().stream() + .filter( + m -> + (m.what + == BassClientStateMachine + .UPDATE_BCAST_SOURCE) + && (m.arg1 == TEST_SOURCE_ID + 20)) + .collect(Collectors.toList()); assertThat(msgs.size()).isEqualTo(1); } else { throw new AssertionError("Unexpected device"); @@ -1636,20 +1751,28 @@ public class BassClientServiceTest { // Prepare valid source for group BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } } @@ -1657,7 +1780,7 @@ public class BassClientServiceTest { // Verify errors are reported for the entire group mBassClientService.modifySource(mCurrentDevice, TEST_SOURCE_ID, null); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { BluetoothDevice dev = sm.getDevice(); try { verify(mCallback, after(TIMEOUT_MS)) @@ -1671,14 +1794,14 @@ public class BassClientServiceTest { } assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { doReturn(BluetoothProfile.STATE_DISCONNECTED).when(sm).getConnectionState(); } // Verify errors are reported for the entire group mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { BluetoothDevice dev = sm.getDevice(); try { verify(mCallback, after(TIMEOUT_MS)) @@ -1693,17 +1816,20 @@ public class BassClientServiceTest { } /** - * Test that an outgoing connection to two device that have BASS UUID is successful - * and a connection state change intent is sent + * Test that an outgoing connection to two device that have BASS UUID is successful and a + * connection state change intent is sent */ @Test public void testConnectedIntent() { prepareConnectedDeviceGroup(); assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { BluetoothDevice dev = sm.getDevice(); - verifyConnectionStateIntent(TIMEOUT_MS, dev, BluetoothProfile.STATE_CONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + dev, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); } @@ -2713,19 +2839,60 @@ public class BassClientServiceTest { final int testSyncHandle1 = 1; final int testSyncHandle2 = 2; final int testSyncHandle3 = 3; - byte[] scanRecord = new byte[]{ - 0x02, 0x01, 0x1a, // advertising flags - 0x05, 0x02, 0x52, 0x18, 0x0a, 0x11, // 16 bit service uuids - 0x04, 0x09, 0x50, 0x65, 0x64, // name - 0x02, 0x0A, (byte) 0xec, // tx power level - 0x05, 0x30, 0x54, 0x65, 0x73, 0x74, // broadcast name: Test - 0x06, 0x16, 0x52, 0x18, 0x50, 0x64, 0x65, // service data - 0x08, 0x16, 0x56, 0x18, 0x07, 0x03, 0x06, 0x07, 0x08, - // service data - public broadcast, - // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 - 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data - 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble - }; + byte[] scanRecord = + new byte[] { + 0x02, + 0x01, + 0x1a, // advertising flags + 0x05, + 0x02, + 0x52, + 0x18, + 0x0a, + 0x11, // 16 bit service uuids + 0x04, + 0x09, + 0x50, + 0x65, + 0x64, // name + 0x02, + 0x0A, + (byte) 0xec, // tx power level + 0x05, + 0x30, + 0x54, + 0x65, + 0x73, + 0x74, // broadcast name: Test + 0x06, + 0x16, + 0x52, + 0x18, + 0x50, + 0x64, + 0x65, // service data + 0x08, + 0x16, + 0x56, + 0x18, + 0x07, + 0x03, + 0x06, + 0x07, + 0x08, + // service data - public broadcast, + // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 + 0x05, + (byte) 0xff, + (byte) 0xe0, + 0x00, + 0x02, + 0x15, // manufacturer specific data + 0x03, + 0x50, + 0x01, + 0x02, // an unknown data type won't cause trouble + }; ScanRecord record = ScanRecord.parseFromBytes(scanRecord); prepareConnectedDeviceGroup(); @@ -2752,8 +2919,9 @@ public class BassClientServiceTest { assertThat(mBassClientService.getActiveSyncedSources(mCurrentDevice).size()).isEqualTo(4); assertThat(mBassClientService.getActiveSyncedSources(mCurrentDevice1).size()).isEqualTo(4); - BluetoothDevice testDevice4 = mBluetoothAdapter.getRemoteLeDevice( - "00:01:02:03:04:05", BluetoothDevice.ADDRESS_TYPE_RANDOM); + BluetoothDevice testDevice4 = + mBluetoothAdapter.getRemoteLeDevice( + "00:01:02:03:04:05", BluetoothDevice.ADDRESS_TYPE_RANDOM); ScanResult scanResult1 = new ScanResult(testDevice4, 0, 0, 0, 0, 0, 0, 0, record, 0); mBassClientService.selectSource(mCurrentDevice, scanResult1, false); mBassClientService.selectSource(mCurrentDevice1, scanResult1, false); @@ -2761,9 +2929,10 @@ public class BassClientServiceTest { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); - Optional msg = messageCaptor.getAllValues().stream() - .filter(m -> m.what == BassClientStateMachine.REACHED_MAX_SOURCE_LIMIT) - .findFirst(); + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.REACHED_MAX_SOURCE_LIMIT) + .findFirst(); assertThat(msg.isPresent()).isEqualTo(true); } @@ -2809,7 +2978,9 @@ public class BassClientServiceTest { null, null); - assertThat(mBassClientService.getPeriodicAdvertisementResult(testDevice, testBroadcastIdInvalid)) + assertThat( + mBassClientService.getPeriodicAdvertisementResult( + testDevice, testBroadcastIdInvalid)) .isEqualTo(null); PeriodicAdvertisementResult paResult = mBassClientService.getPeriodicAdvertisementResult(testDevice, testBroadcastId); @@ -2880,20 +3051,28 @@ public class BassClientServiceTest { onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } } @@ -2994,7 +3173,7 @@ public class BassClientServiceTest { // Verify all group members getting UPDATE_BCAST_SOURCE/ADD SOURCE resuming syncmessage assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); long count; @@ -3052,38 +3231,56 @@ public class BassClientServiceTest { onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); // Update receiver state - injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateChanged( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, (long) 0x00000001); + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, + (long) 0x00000001); verify(mLeAudioService).activeBroadcastAssistantNotification(eq(true)); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); // Update receiver state - injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateChanged( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, (long) 0x00000002); + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, + (long) 0x00000002); } } @@ -3151,7 +3348,7 @@ public class BassClientServiceTest { // Verify all group members getting UPDATE_BCAST_SOURCE ressuming syncmessage assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); long count; @@ -3201,22 +3398,32 @@ public class BassClientServiceTest { } // Update receiver state with lost BIS sync - for (BassClientStateMachine sm: mStateMachines.values()) { + for (BassClientStateMachine sm : mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateChanged( + sm, + meta, + TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, (long) 0x00000000); + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, + (long) 0x00000000); verify(mLeAudioService).activeBroadcastAssistantNotification(eq(false)); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateChanged( + sm, + meta, + TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - meta.isEncrypted() ? - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, (long) 0x00000000); + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, + (long) 0x00000000); } } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java index 5ee89dd3e88..1077fe4c16d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java @@ -129,8 +129,7 @@ import java.util.UUID; @MediumTest @RunWith(JUnit4.class) public class BassClientStateMachineTest { - @Rule - public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -165,8 +164,9 @@ public class BassClientStateMachineTest { TestUtils.setAdapterService(mAdapterService); BluetoothMethodProxy.setInstanceForTesting(mMethodProxy); - doNothing().when(mMethodProxy).periodicAdvertisingManagerTransferSync( - any(), any(), anyInt(), anyInt()); + doNothing() + .when(mMethodProxy) + .periodicAdvertisingManagerTransferSync(any(), any(), anyInt(), anyInt()); // Get a device for testing mTestDevice = TestUtils.getTestDevice(mAdapter, 0); @@ -214,13 +214,11 @@ public class BassClientStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mBassClientStateMachine.getConnectionState()); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mBassClientStateMachine.getConnectionState()); } /** @@ -236,9 +234,7 @@ public class BassClientStateMachineTest { mBassClientStateMachine.mShouldAllowGatt = allow; } - /** - * Test that an incoming connection with policy forbidding connection is rejected - */ + /** Test that an incoming connection with policy forbidding connection is rejected */ @Test public void testOkToConnectFails() { allowConnection(false); @@ -248,11 +244,12 @@ public class BassClientStateMachineTest { mBassClientStateMachine.sendMessage(CONNECT); // Verify that no connection state broadcast is executed - verify(mBassClientService, after(WAIT_MS).never()).sendBroadcast(any(Intent.class), - anyString()); + verify(mBassClientService, after(WAIT_MS).never()) + .sendBroadcast(any(Intent.class), anyString()); // Check that we are in Disconnected state - Assert.assertThat(mBassClientStateMachine.getCurrentState(), + Assert.assertThat( + mBassClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BassClientStateMachine.Disconnected.class)); } @@ -265,11 +262,12 @@ public class BassClientStateMachineTest { mBassClientStateMachine.sendMessage(CONNECT); // Verify that no connection state broadcast is executed - verify(mBassClientService, after(WAIT_MS).never()).sendBroadcast(any(Intent.class), - anyString()); + verify(mBassClientService, after(WAIT_MS).never()) + .sendBroadcast(any(Intent.class), anyString()); // Check that we are in Disconnected state - Assert.assertThat(mBassClientStateMachine.getCurrentState(), + Assert.assertThat( + mBassClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BassClientStateMachine.Disconnected.class)); assertNull(mBassClientStateMachine.mBluetoothGatt); } @@ -284,12 +282,14 @@ public class BassClientStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mBassClientService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mBassClientService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mBassClientStateMachine.getCurrentState(), + Assert.assertThat( + mBassClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BassClientStateMachine.Connecting.class)); assertNotNull(mBassClientStateMachine.mGattCallback); @@ -299,10 +299,11 @@ public class BassClientStateMachineTest { // Verify that the expected number of broadcasts are executed: // - two calls to broadcastConnectionState(): Disconnected -> Connecting -> Connected ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mBassClientService, timeout(TIMEOUT_MS).times(2)).sendBroadcast( - intentArgument2.capture(), anyString(), any(Bundle.class)); + verify(mBassClientService, timeout(TIMEOUT_MS).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); - Assert.assertThat(mBassClientStateMachine.getCurrentState(), + Assert.assertThat( + mBassClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BassClientStateMachine.Connected.class)); } @@ -316,22 +317,26 @@ public class BassClientStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mBassClientService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mBassClientService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mBassClientStateMachine.getCurrentState(), + Assert.assertThat( + mBassClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BassClientStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mBassClientService, timeout(TIMEOUT_MS).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + verify(mBassClientService, timeout(TIMEOUT_MS).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mBassClientStateMachine.getCurrentState(), + Assert.assertThat( + mBassClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(BassClientStateMachine.Disconnected.class)); } @@ -411,8 +416,8 @@ public class BassClientStateMachineTest { // --> connected // Make bluetoothGatt non-null so state will transit - mBassClientStateMachine.mBluetoothGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + mBassClientStateMachine.mBluetoothGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBroadcastScanControlPoint = new BluetoothGattCharacteristic( BassConstants.BASS_BCAST_AUDIO_SCAN_CTRL_POINT, @@ -468,8 +473,8 @@ public class BassClientStateMachineTest { @Test public void acquireAllBassChars() { - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; // Do nothing when mBluetoothGatt.getService returns null mBassClientStateMachine.acquireAllBassChars(); @@ -520,8 +525,8 @@ public class BassClientStateMachineTest { assertThat(mBassClientStateMachine.getDevice()).isEqualTo(mTestDevice); assertThat(mBassClientStateMachine.hasPendingSourceOperation()).isFalse(); assertThat(mBassClientStateMachine.hasPendingSourceOperation(1)).isFalse(); - assertThat(mBassClientStateMachine.isEmpty(new byte[] { 0 })).isTrue(); - assertThat(mBassClientStateMachine.isEmpty(new byte[] { 1 })).isFalse(); + assertThat(mBassClientStateMachine.isEmpty(new byte[] {0})).isTrue(); + assertThat(mBassClientStateMachine.isEmpty(new byte[] {1})).isFalse(); assertThat(mBassClientStateMachine.isPendingRemove(invalidSourceId)).isFalse(); } @@ -529,15 +534,42 @@ public class BassClientStateMachineTest { public void parseScanRecord_withoutBaseData_callCancelActiveSync() { mSetFlagsRule.disableFlags( Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE); - byte[] scanRecord = new byte[]{ - 0x02, 0x01, 0x1a, // advertising flags - 0x05, 0x02, 0x0b, 0x11, 0x0a, 0x11, // 16 bit service uuids - 0x04, 0x09, 0x50, 0x65, 0x64, // name - 0x02, 0x0A, (byte) 0xec, // tx power level - 0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data - 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data - 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble - }; + byte[] scanRecord = + new byte[] { + 0x02, + 0x01, + 0x1a, // advertising flags + 0x05, + 0x02, + 0x0b, + 0x11, + 0x0a, + 0x11, // 16 bit service uuids + 0x04, + 0x09, + 0x50, + 0x65, + 0x64, // name + 0x02, + 0x0A, + (byte) 0xec, // tx power level + 0x05, + 0x16, + 0x0b, + 0x11, + 0x50, + 0x64, // service data + 0x05, + (byte) 0xff, + (byte) 0xe0, + 0x00, + 0x02, + 0x15, // manufacturer specific data + 0x03, + 0x50, + 0x01, + 0x02, // an unknown data type won't cause trouble + }; // need this to ensure expected mock behavior for getActiveSyncedSource when(mBassClientService.getActiveSyncedSources(any())).thenReturn(null); @@ -622,8 +654,8 @@ public class BassClientStateMachineTest { throws InterruptedException { mBassClientStateMachine.connectGatt(true); BluetoothGattCallback cb = mBassClientStateMachine.mGattCallback; - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; // disallow connection @@ -659,8 +691,8 @@ public class BassClientStateMachineTest { initToConnectingState(); mBassClientStateMachine.connectGatt(true); BluetoothGattCallback cb = mBassClientStateMachine.mGattCallback; - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; allowConnection(false); @@ -678,8 +710,8 @@ public class BassClientStateMachineTest { public void gattCallbackOnServicesDiscovered() { mBassClientStateMachine.connectGatt(true); BluetoothGattCallback cb = mBassClientStateMachine.mGattCallback; - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; // Do nothing if mDiscoveryInitiated is false. @@ -704,9 +736,7 @@ public class BassClientStateMachineTest { verify(btGatt).requestMtu(anyInt()); } - /** - * This also tests BassClientStateMachine#processBroadcastReceiverState. - */ + /** This also tests BassClientStateMachine#processBroadcastReceiverState. */ @Test public void gattCallbackOnCharacteristicRead() { mBassClientStateMachine.mShouldHandleMessage = false; @@ -716,8 +746,8 @@ public class BassClientStateMachineTest { BassClientService.Callbacks callbacks = Mockito.mock(BassClientService.Callbacks.class); BluetoothGattCharacteristic characteristic = Mockito.mock(BluetoothGattCharacteristic.class); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); when(characteristic.getUuid()).thenReturn(BassConstants.BASS_BCAST_RECEIVER_STATE); when(mBassClientService.getCallbacks()).thenReturn(callbacks); @@ -735,7 +765,6 @@ public class BassClientStateMachineTest { assertThat(mBassClientStateMachine.mMsgAgr1).isEqualTo(GATT_FAILURE); mBassClientStateMachine.mMsgWhats.clear(); - // Characteristic read failed and mBluetoothGatt is not null. mBassClientStateMachine.mBluetoothGatt = btGatt; when(characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG)).thenReturn(desc); @@ -747,7 +776,7 @@ public class BassClientStateMachineTest { // Tests for processBroadcastReceiverState int sourceId = 1; - byte[] value = new byte[] { }; + byte[] value = new byte[] {}; mBassClientStateMachine.mNumOfBroadcastReceiverStates = 2; mBassClientStateMachine.mPendingOperation = REMOVE_BCAST_SOURCE; mBassClientStateMachine.mPendingSourceId = (byte) sourceId; @@ -902,7 +931,7 @@ public class BassClientStateMachineTest { mBassClientStateMachine.mNumOfBroadcastReceiverStates = 1; Mockito.clearInvocations(characteristic); - when(characteristic.getValue()).thenReturn(new byte[] { }); + when(characteristic.getValue()).thenReturn(new byte[] {}); cb.onCharacteristicChanged(null, characteristic); verify(characteristic, atLeast(1)).getUuid(); verify(characteristic, atLeast(1)).getValue(); @@ -918,7 +947,8 @@ public class BassClientStateMachineTest { mBassClientStateMachine.connectGatt(true); BluetoothGattCallback cb = mBassClientStateMachine.mGattCallback; - BluetoothGattCharacteristic characteristic =Mockito.mock(BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic characteristic = + Mockito.mock(BluetoothGattCharacteristic.class); when(characteristic.getUuid()).thenReturn(BassConstants.BASS_BCAST_AUDIO_SCAN_CTRL_POINT); cb.onCharacteristicWrite(null, characteristic, GATT_SUCCESS); @@ -947,8 +977,8 @@ public class BassClientStateMachineTest { cb.onMtuChanged(null, 10, GATT_SUCCESS); assertThat(mBassClientStateMachine.mMTUChangeRequested).isTrue(); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; cb.onMtuChanged(null, 10, GATT_SUCCESS); @@ -959,8 +989,8 @@ public class BassClientStateMachineTest { public void sendConnectMessage_inDisconnectedState() { initToDisconnectedState(); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; sendMessageAndVerifyTransition( @@ -974,8 +1004,8 @@ public class BassClientStateMachineTest { public void sendDisconnectMessage_inDisconnectedState() { initToDisconnectedState(); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; mBassClientStateMachine.sendMessage(DISCONNECT); @@ -988,8 +1018,8 @@ public class BassClientStateMachineTest { public void sendStateChangedMessage_inDisconnectedState() { initToDisconnectedState(); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; Message msgToConnectingState = @@ -1086,8 +1116,9 @@ public class BassClientStateMachineTest { public void sendConnectTimeMessage_inConnectingState() { initToConnectingState(); - Message timeoutWithDifferentDevice = mBassClientStateMachine.obtainMessage(CONNECT_TIMEOUT, - mAdapter.getRemoteDevice("00:00:00:00:00:00")); + Message timeoutWithDifferentDevice = + mBassClientStateMachine.obtainMessage( + CONNECT_TIMEOUT, mAdapter.getRemoteDevice("00:00:00:00:00:00")); mBassClientStateMachine.sendMessage(timeoutWithDifferentDevice); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mBassClientService, never()).sendBroadcast(any(Intent.class), anyString(), any()); @@ -1130,8 +1161,8 @@ public class BassClientStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mBassClientService, never()).sendBroadcast(any(Intent.class), anyString(), any()); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; sendMessageAndVerifyTransition( mBassClientStateMachine.obtainMessage(DISCONNECT), @@ -1167,34 +1198,35 @@ public class BassClientStateMachineTest { @Test public void sendReadBassCharacteristicsMessage_inConnectedState() { initToConnectedState(); - BluetoothGattCharacteristic gattCharacteristic = Mockito.mock( - BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic gattCharacteristic = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.sendMessage(READ_BASS_CHARACTERISTICS, gattCharacteristic); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mBassClientService, never()).sendBroadcast(any(Intent.class), anyString(), any()); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; - sendMessageAndVerifyTransition(mBassClientStateMachine.obtainMessage( - READ_BASS_CHARACTERISTICS, gattCharacteristic), + sendMessageAndVerifyTransition( + mBassClientStateMachine.obtainMessage( + READ_BASS_CHARACTERISTICS, gattCharacteristic), BassClientStateMachine.ConnectedProcessing.class); } @Test public void sendStartScanOffloadMessage_inConnectedState() { initToConnectedState(); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; mBassClientStateMachine.sendMessage(START_SCAN_OFFLOAD); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mBassClientService, never()).sendBroadcast(any(Intent.class), anyString(), any()); - BluetoothGattCharacteristic scanControlPoint = Mockito.mock( - BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; sendMessageAndVerifyTransition( @@ -1207,16 +1239,16 @@ public class BassClientStateMachineTest { @Test public void sendStopScanOffloadMessage_inConnectedState() { initToConnectedState(); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; mBassClientStateMachine.sendMessage(STOP_SCAN_OFFLOAD); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mBassClientService, never()).sendBroadcast(any(Intent.class), anyString(), any()); - BluetoothGattCharacteristic scanControlPoint = Mockito.mock( - BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; sendMessageAndVerifyTransition( @@ -1255,30 +1287,79 @@ public class BassClientStateMachineTest { Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE); initToConnectedState(); - byte[] scanRecord = new byte[]{ - 0x02, 0x01, 0x1a, // advertising flags - 0x05, 0x02, 0x52, 0x18, 0x0a, 0x11, // 16 bit service uuids - 0x04, 0x09, 0x50, 0x65, 0x64, // name - 0x02, 0x0A, (byte) 0xec, // tx power level - 0x05, 0x30, 0x54, 0x65, 0x73, 0x74, // broadcast name: Test - 0x06, 0x16, 0x52, 0x18, 0x50, 0x64, 0x65, // service data - 0x08, 0x16, 0x56, 0x18, 0x07, 0x03, 0x06, 0x07, 0x08, - // service data - public broadcast, - // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 - 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data - 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble - }; + byte[] scanRecord = + new byte[] { + 0x02, + 0x01, + 0x1a, // advertising flags + 0x05, + 0x02, + 0x52, + 0x18, + 0x0a, + 0x11, // 16 bit service uuids + 0x04, + 0x09, + 0x50, + 0x65, + 0x64, // name + 0x02, + 0x0A, + (byte) 0xec, // tx power level + 0x05, + 0x30, + 0x54, + 0x65, + 0x73, + 0x74, // broadcast name: Test + 0x06, + 0x16, + 0x52, + 0x18, + 0x50, + 0x64, + 0x65, // service data + 0x08, + 0x16, + 0x56, + 0x18, + 0x07, + 0x03, + 0x06, + 0x07, + 0x08, + // service data - public broadcast, + // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 + 0x05, + (byte) 0xff, + (byte) 0xe0, + 0x00, + 0x02, + 0x15, // manufacturer specific data + 0x03, + 0x50, + 0x01, + 0x02, // an unknown data type won't cause trouble + }; ScanRecord record = ScanRecord.parseFromBytes(scanRecord); - doNothing().when(mMethodProxy).periodicAdvertisingManagerRegisterSync( - any(), any(), anyInt(), anyInt(), any(), any()); + doNothing() + .when(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); ScanResult scanResult = new ScanResult(mTestDevice, 0, 0, 0, 0, 0, 0, 0, record, 0); - mBassClientStateMachine.sendMessage( - SELECT_BCAST_SOURCE, BassConstants.AUTO, 0, scanResult); + mBassClientStateMachine.sendMessage(SELECT_BCAST_SOURCE, BassConstants.AUTO, 0, scanResult); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - verify(mBassClientService).updatePeriodicAdvertisementResultMap( - any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), - any(), eq(TEST_BROADCAST_NAME)); + verify(mBassClientService) + .updatePeriodicAdvertisementResultMap( + any(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + any(), + eq(TEST_BROADCAST_NAME)); } @Test @@ -1298,11 +1379,11 @@ public class BassClientStateMachineTest { verify(mBassClientService).getCallbacks(); verify(callbacks).notifySourceAddFailed(any(), any(), anyInt()); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; - BluetoothGattCharacteristic scanControlPoint = Mockito.mock( - BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; sendMessageAndVerifyTransition( @@ -1431,10 +1512,10 @@ public class BassClientStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(callbacks).notifySourceModifyFailed(any(), anyInt(), anyInt()); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); - BluetoothGattCharacteristic scanControlPoint = Mockito.mock( - BluetoothGattCharacteristic.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.mBluetoothGatt = btGatt; mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; mBassClientStateMachine.mPendingOperation = 0; @@ -1523,45 +1604,45 @@ public class BassClientStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); mBassClientStateMachine.mShouldHandleMessage = true; - BluetoothLeBroadcastReceiveState recvState = new BluetoothLeBroadcastReceiveState( - 2, - BluetoothDevice.ADDRESS_TYPE_PUBLIC, - mAdapter.getRemoteLeDevice("00:00:00:00:00:00", - BluetoothDevice.ADDRESS_TYPE_PUBLIC), - 0, - 0, - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED, - null, - 0, - Arrays.asList(new Long[0]), - Arrays.asList(new BluetoothLeAudioContentMetadata[0]) - ); + BluetoothLeBroadcastReceiveState recvState = + new BluetoothLeBroadcastReceiveState( + 2, + BluetoothDevice.ADDRESS_TYPE_PUBLIC, + mAdapter.getRemoteLeDevice( + "00:00:00:00:00:00", BluetoothDevice.ADDRESS_TYPE_PUBLIC), + 0, + 0, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED, + null, + 0, + Arrays.asList(new Long[0]), + Arrays.asList(new BluetoothLeAudioContentMetadata[0])); mBassClientStateMachine.mSetBroadcastCodePending = false; mBassClientStateMachine.sendMessage(SET_BCAST_CODE, recvState); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); assertThat(mBassClientStateMachine.mSetBroadcastCodePending).isTrue(); - recvState = new BluetoothLeBroadcastReceiveState( - sourceId, - BluetoothDevice.ADDRESS_TYPE_PUBLIC, - mAdapter.getRemoteLeDevice("00:00:00:00:00:00", - BluetoothDevice.ADDRESS_TYPE_PUBLIC), - 0, - 0, - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED, - null, - 0, - Arrays.asList(new Long[0]), - Arrays.asList(new BluetoothLeAudioContentMetadata[0]) - ); + recvState = + new BluetoothLeBroadcastReceiveState( + sourceId, + BluetoothDevice.ADDRESS_TYPE_PUBLIC, + mAdapter.getRemoteLeDevice( + "00:00:00:00:00:00", BluetoothDevice.ADDRESS_TYPE_PUBLIC), + 0, + 0, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED, + null, + 0, + Arrays.asList(new Long[0]), + Arrays.asList(new BluetoothLeAudioContentMetadata[0])); mBassClientStateMachine.sendMessage(SET_BCAST_CODE, recvState); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; - BluetoothGattCharacteristic scanControlPoint = Mockito.mock( - BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; sendMessageAndVerifyTransition( @@ -1664,11 +1745,11 @@ public class BassClientStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(callbacks).notifySourceRemoveFailed(any(), anyInt(), anyInt()); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; - BluetoothGattCharacteristic scanControlPoint = Mockito.mock( - BluetoothGattCharacteristic.class); + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; sendMessageAndVerifyTransition( @@ -1739,9 +1820,7 @@ public class BassClientStateMachineTest { assertNull(mBassClientStateMachine.mBluetoothGatt); } - /** - * This also tests BassClientStateMachine#sendPendingCallbacks - */ + /** This also tests BassClientStateMachine#sendPendingCallbacks */ @Test public void sendGattTxnProcessedMessage_inConnectedProcessingState() { initToConnectedProcessingState(); @@ -1848,38 +1927,31 @@ public class BassClientStateMachineTest { mBassClientStateMachine.sendMessage(START_SCAN_OFFLOAD); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(START_SCAN_OFFLOAD)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(START_SCAN_OFFLOAD)).isTrue(); mBassClientStateMachine.sendMessage(STOP_SCAN_OFFLOAD); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(STOP_SCAN_OFFLOAD)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(STOP_SCAN_OFFLOAD)).isTrue(); mBassClientStateMachine.sendMessage(SELECT_BCAST_SOURCE); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(SELECT_BCAST_SOURCE)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(SELECT_BCAST_SOURCE)).isTrue(); mBassClientStateMachine.sendMessage(ADD_BCAST_SOURCE); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(ADD_BCAST_SOURCE)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(ADD_BCAST_SOURCE)).isTrue(); mBassClientStateMachine.sendMessage(SET_BCAST_CODE); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(SET_BCAST_CODE)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(SET_BCAST_CODE)).isTrue(); mBassClientStateMachine.sendMessage(REMOVE_BCAST_SOURCE); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(REMOVE_BCAST_SOURCE)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(REMOVE_BCAST_SOURCE)).isTrue(); mBassClientStateMachine.sendMessage(PSYNC_ACTIVE_TIMEOUT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(PSYNC_ACTIVE_TIMEOUT)) - .isTrue(); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(PSYNC_ACTIVE_TIMEOUT)).isTrue(); mBassClientStateMachine.sendMessage(REACHED_MAX_SOURCE_LIMIT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1982,19 +2054,60 @@ public class BassClientStateMachineTest { final int testSyncHandle = 1; initToConnectedState(); - byte[] scanRecord = new byte[]{ - 0x02, 0x01, 0x1a, // advertising flags - 0x05, 0x02, 0x52, 0x18, 0x0a, 0x11, // 16 bit service uuids - 0x04, 0x09, 0x50, 0x65, 0x64, // name - 0x02, 0x0A, (byte) 0xec, // tx power level - 0x05, 0x30, 0x54, 0x65, 0x73, 0x74, // broadcast name: Test - 0x06, 0x16, 0x52, 0x18, 0x2A, 0x00, 0x00, // service data, broadcast id 42 - 0x08, 0x16, 0x56, 0x18, 0x07, 0x03, 0x06, 0x07, 0x08, - // service data - public broadcast, - // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 - 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data - 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble - }; + byte[] scanRecord = + new byte[] { + 0x02, + 0x01, + 0x1a, // advertising flags + 0x05, + 0x02, + 0x52, + 0x18, + 0x0a, + 0x11, // 16 bit service uuids + 0x04, + 0x09, + 0x50, + 0x65, + 0x64, // name + 0x02, + 0x0A, + (byte) 0xec, // tx power level + 0x05, + 0x30, + 0x54, + 0x65, + 0x73, + 0x74, // broadcast name: Test + 0x06, + 0x16, + 0x52, + 0x18, + 0x2A, + 0x00, + 0x00, // service data, broadcast id 42 + 0x08, + 0x16, + 0x56, + 0x18, + 0x07, + 0x03, + 0x06, + 0x07, + 0x08, + // service data - public broadcast, + // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 + 0x05, + (byte) 0xff, + (byte) 0xe0, + 0x00, + 0x02, + 0x15, // manufacturer specific data + 0x03, + 0x50, + 0x01, + 0x02, // an unknown data type won't cause trouble + }; ScanRecord record = ScanRecord.parseFromBytes(scanRecord); ScanResult scanResult = new ScanResult(mTestDevice, 0, 0, 0, 0, 0, 0, 0, record, 0); @@ -2011,18 +2124,25 @@ public class BassClientStateMachineTest { mBassClientStateMachine.sendMessage(SELECT_BCAST_SOURCE, BassConstants.AUTO, 0, scanResult); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // validate syncing to the same broadcast id will be skipped - verify(mBassClientService, never()).updatePeriodicAdvertisementResultMap( - any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), - any(), any()); + verify(mBassClientService, never()) + .updatePeriodicAdvertisementResultMap( + any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(), any()); // need this to ensure expected mock behavior for getActiveSyncedSource when(mBassClientService.getActiveSyncedSources(any())).thenReturn(null); mBassClientStateMachine.sendMessage(SELECT_BCAST_SOURCE, BassConstants.AUTO, 0, scanResult); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - verify(mBassClientService).updatePeriodicAdvertisementResultMap( - any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), - any(), eq(TEST_BROADCAST_NAME)); + verify(mBassClientService) + .updatePeriodicAdvertisementResultMap( + any(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + any(), + eq(TEST_BROADCAST_NAME)); } @Test @@ -2045,25 +2165,79 @@ public class BassClientStateMachineTest { verify(mBassClientService).getCallbacks(); verify(callbacks).notifySourceAddFailed(any(), any(), anyInt()); - byte[] scanRecord = new byte[]{ - 0x02, 0x01, 0x1a, // advertising flags - 0x05, 0x02, 0x52, 0x18, 0x0a, 0x11, // 16 bit service uuids - 0x04, 0x09, 0x50, 0x65, 0x64, // name - 0x02, 0x0A, (byte) 0xec, // tx power level - 0x05, 0x30, 0x54, 0x65, 0x73, 0x74, // broadcast name: Test - 0x06, 0x16, 0x52, 0x18, 0x2A, 0x00, 0x00, // service data, broadcast id 42 - 0x08, 0x16, 0x56, 0x18, 0x07, 0x03, 0x06, 0x07, 0x08, - // service data - public broadcast, - // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 - 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data - 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble - }; + byte[] scanRecord = + new byte[] { + 0x02, + 0x01, + 0x1a, // advertising flags + 0x05, + 0x02, + 0x52, + 0x18, + 0x0a, + 0x11, // 16 bit service uuids + 0x04, + 0x09, + 0x50, + 0x65, + 0x64, // name + 0x02, + 0x0A, + (byte) 0xec, // tx power level + 0x05, + 0x30, + 0x54, + 0x65, + 0x73, + 0x74, // broadcast name: Test + 0x06, + 0x16, + 0x52, + 0x18, + 0x2A, + 0x00, + 0x00, // service data, broadcast id 42 + 0x08, + 0x16, + 0x56, + 0x18, + 0x07, + 0x03, + 0x06, + 0x07, + 0x08, + // service data - public broadcast, + // feature - 0x7, metadata len - 0x3, metadata - 0x6, 0x7, 0x8 + 0x05, + (byte) 0xff, + (byte) 0xe0, + 0x00, + 0x02, + 0x15, // manufacturer specific data + 0x03, + 0x50, + 0x01, + 0x02, // an unknown data type won't cause trouble + }; ScanRecord record = ScanRecord.parseFromBytes(scanRecord); - ScanResult scanResult = new ScanResult(mAdapter.getRemoteLeDevice("00:11:22:33:44:55", - BluetoothDevice.ADDRESS_TYPE_RANDOM), 0, 0, 0, 0, 0, 0, 0, record, 0); + ScanResult scanResult = + new ScanResult( + mAdapter.getRemoteLeDevice( + "00:11:22:33:44:55", BluetoothDevice.ADDRESS_TYPE_RANDOM), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + record, + 0); when(mBassClientService.getCachedBroadcast(anyInt())).thenReturn(scanResult); - doNothing().when(mMethodProxy).periodicAdvertisingManagerRegisterSync( - any(), any(), anyInt(), anyInt(), any(), any()); + doNothing() + .when(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); // validate add source will trigger select source and update mPendingSourceToAdd mBassClientStateMachine.sendMessage(ADD_BCAST_SOURCE, metadata); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -2270,12 +2444,13 @@ public class BassClientStateMachineTest { } private void moveConnectedStateToConnectedProcessingState() { - BluetoothGattCharacteristic gattCharacteristic = Mockito.mock( - BluetoothGattCharacteristic.class); - BassClientStateMachine.BluetoothGattTestableWrapper btGatt = Mockito.mock( - BassClientStateMachine.BluetoothGattTestableWrapper.class); + BluetoothGattCharacteristic gattCharacteristic = + Mockito.mock(BluetoothGattCharacteristic.class); + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); mBassClientStateMachine.mBluetoothGatt = btGatt; - sendMessageAndVerifyTransition(mBassClientStateMachine.obtainMessage( + sendMessageAndVerifyTransition( + mBassClientStateMachine.obtainMessage( READ_BASS_CHARACTERISTICS, gattCharacteristic), BassClientStateMachine.ConnectedProcessing.class); Mockito.clearInvocations(mBassClientService); @@ -2337,14 +2512,15 @@ public class BassClientStateMachineTest { BluetoothDevice testDevice = mAdapter.getRemoteLeDevice(testMacAddress, BluetoothDevice.ADDRESS_TYPE_RANDOM); - BluetoothLeBroadcastMetadata.Builder builder = new BluetoothLeBroadcastMetadata.Builder() - .setEncrypted(false) - .setSourceDevice(testDevice, BluetoothDevice.ADDRESS_TYPE_RANDOM) - .setSourceAdvertisingSid(testAdvertiserSid) - .setBroadcastId(testBroadcastId) - .setBroadcastCode(new byte[] { 0x00, 0x01, 0x00, 0x02 }) - .setPaSyncInterval(testPaSyncInterval) - .setPresentationDelayMicros(testPresentationDelayMs); + BluetoothLeBroadcastMetadata.Builder builder = + new BluetoothLeBroadcastMetadata.Builder() + .setEncrypted(false) + .setSourceDevice(testDevice, BluetoothDevice.ADDRESS_TYPE_RANDOM) + .setSourceAdvertisingSid(testAdvertiserSid) + .setBroadcastId(testBroadcastId) + .setBroadcastCode(new byte[] {0x00, 0x01, 0x00, 0x02}) + .setPaSyncInterval(testPaSyncInterval) + .setPresentationDelayMicros(testPresentationDelayMs); // builder expect at least one subgroup builder.addSubgroup(createBroadcastSubgroup()); return builder.build(); @@ -2362,18 +2538,23 @@ public class BassClientStateMachineTest { BluetoothLeAudioCodecConfigMetadata codecMetadata = new BluetoothLeAudioCodecConfigMetadata.Builder() - .setAudioLocation(testAudioLocationFrontLeft).build(); + .setAudioLocation(testAudioLocationFrontLeft) + .build(); BluetoothLeAudioContentMetadata contentMetadata = new BluetoothLeAudioContentMetadata.Builder() - .setProgramInfo(testProgramInfo).setLanguage(testLanguage).build(); - BluetoothLeBroadcastSubgroup.Builder builder = new BluetoothLeBroadcastSubgroup.Builder() - .setCodecId(testCodecId) - .setCodecSpecificConfig(codecMetadata) - .setContentMetadata(contentMetadata); + .setProgramInfo(testProgramInfo) + .setLanguage(testLanguage) + .build(); + BluetoothLeBroadcastSubgroup.Builder builder = + new BluetoothLeBroadcastSubgroup.Builder() + .setCodecId(testCodecId) + .setCodecSpecificConfig(codecMetadata) + .setContentMetadata(contentMetadata); BluetoothLeAudioCodecConfigMetadata channelCodecMetadata = new BluetoothLeAudioCodecConfigMetadata.Builder() - .setAudioLocation(testAudioLocationFrontRight).build(); + .setAudioLocation(testAudioLocationFrontRight) + .build(); // builder expect at least one channel BluetoothLeBroadcastChannel channel = diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java index 0f7034a0756..2921d739350 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java @@ -83,17 +83,17 @@ public class BleBroadcastAssistantBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] { STATE_DISCONNECTED }; + int[] states = new int[] {STATE_DISCONNECTED}; mBinder.getDevicesMatchingConnectionStates(states); verify(mService).getDevicesMatchingConnectionStates(states); doThrow(new RuntimeException()).when(mService).getDevicesMatchingConnectionStates(states); - assertThat(mBinder.getDevicesMatchingConnectionStates(states)).isEqualTo( - Collections.emptyList()); + assertThat(mBinder.getDevicesMatchingConnectionStates(states)) + .isEqualTo(Collections.emptyList()); mBinder.cleanup(); - assertThat(mBinder.getDevicesMatchingConnectionStates(states)).isEqualTo( - Collections.emptyList()); + assertThat(mBinder.getDevicesMatchingConnectionStates(states)) + .isEqualTo(Collections.emptyList()); } @Test @@ -114,7 +114,8 @@ public class BleBroadcastAssistantBinderTest { mBinder.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mService).setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); - doThrow(new RuntimeException()).when(mService) + doThrow(new RuntimeException()) + .when(mService) .setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); assertThat(mBinder.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED)) .isFalse(); @@ -175,7 +176,7 @@ public class BleBroadcastAssistantBinderTest { @Test public void startSearchingForSources() { - List filters = Collections.EMPTY_LIST; + List filters = Collections.EMPTY_LIST; mBinder.startSearchingForSources(filters); verify(mService).startSearchingForSources(filters); diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java index 239d68ba666..e2a5b4d4d08 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java @@ -51,9 +51,16 @@ public class PeriodicAdvertisementResultTest { int broadcastId = 5; PublicBroadcastData pbData = generatePublicBroadcastData(); String broadcastName = TEST_BROADCAST_NAME; - PeriodicAdvertisementResult result = new PeriodicAdvertisementResult( - mDevice, addressType, syncHandle, advSid, paInterval, broadcastId, - pbData, broadcastName); + PeriodicAdvertisementResult result = + new PeriodicAdvertisementResult( + mDevice, + addressType, + syncHandle, + advSid, + paInterval, + broadcastId, + pbData, + broadcastName); assertThat(result.getAddressType()).isEqualTo(addressType); assertThat(result.getSyncHandle()).isEqualTo(syncHandle); @@ -73,9 +80,16 @@ public class PeriodicAdvertisementResultTest { int broadcastId = 5; PublicBroadcastData pbData = null; String broadcastName = null; - PeriodicAdvertisementResult result = new PeriodicAdvertisementResult( - mDevice, addressType, syncHandle, advSid, paInterval, broadcastId, - pbData, broadcastName); + PeriodicAdvertisementResult result = + new PeriodicAdvertisementResult( + mDevice, + addressType, + syncHandle, + advSid, + paInterval, + broadcastId, + pbData, + broadcastName); int newAddressType = 6; result.updateAddressType(newAddressType); @@ -115,25 +129,30 @@ public class PeriodicAdvertisementResultTest { int broadcastId = 5; PublicBroadcastData pbData = generatePublicBroadcastData(); String broadcastName = TEST_BROADCAST_NAME; - PeriodicAdvertisementResult result = new PeriodicAdvertisementResult( - mDevice, addressType, syncHandle, advSid, paInterval, broadcastId, - pbData, broadcastName); + PeriodicAdvertisementResult result = + new PeriodicAdvertisementResult( + mDevice, + addressType, + syncHandle, + advSid, + paInterval, + broadcastId, + pbData, + broadcastName); result.print(); } - /** - * Helper to generate test data for public broadcast. - */ + /** Helper to generate test data for public broadcast. */ private PublicBroadcastData generatePublicBroadcastData() { PublicBroadcastData.PublicBroadcastInfo info = new PublicBroadcastData.PublicBroadcastInfo(); info.isEncrypted = true; - info.audioConfigQuality = ( - BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD | - BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_HIGH); + info.audioConfigQuality = + (BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD + | BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_HIGH); info.metaDataLength = 3; - info.metaData = new byte[] { 0x06, 0x07, 0x08 }; + info.metaData = new byte[] {0x06, 0x07, 0x08}; return new PublicBroadcastData(info); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java index 9a307b8704d..c9b49864631 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java @@ -39,11 +39,11 @@ public class PublicBroadcastDataTest { info.print(); info.isEncrypted = true; - info.audioConfigQuality = ( - BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD | - BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_HIGH); + info.audioConfigQuality = + (BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD + | BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_HIGH); info.metaDataLength = 3; - info.metaData = new byte[] { 0x06, 0x07, 0x08 }; + info.metaData = new byte[] {0x06, 0x07, 0x08}; info.print(); } @@ -51,33 +51,40 @@ public class PublicBroadcastDataTest { public void parsePublicBroadcastData() { assertThat(PublicBroadcastData.parsePublicBroadcastData(null)).isNull(); - byte[] serviceDataInvalid = new byte[] { - (byte) 0x02, // features, non-encrypted, standard quality prsent - }; + byte[] serviceDataInvalid = + new byte[] { + (byte) 0x02, // features, non-encrypted, standard quality prsent + }; assertThat(PublicBroadcastData.parsePublicBroadcastData(serviceDataInvalid)).isNull(); - byte[] serviceDataInvalid2 = new byte[] { - (byte) 0x02, // features, non-encrypted, standard quality prsent - (byte) 0x03, // metaDataLength - (byte) 0x06, (byte) 0x07, // invalid metaData - }; + byte[] serviceDataInvalid2 = + new byte[] { + (byte) 0x02, // features, non-encrypted, standard quality prsent + (byte) 0x03, // metaDataLength + (byte) 0x06, + (byte) 0x07, // invalid metaData + }; assertThat(PublicBroadcastData.parsePublicBroadcastData(serviceDataInvalid2)).isNull(); - byte[] serviceData = new byte[] { - (byte) 0x07, // features - (byte) 0x03, // metaDataLength - (byte) 0x06, (byte) 0x07, (byte) 0x08, // metaData - }; + byte[] serviceData = + new byte[] { + (byte) 0x07, // features + (byte) 0x03, // metaDataLength + (byte) 0x06, + (byte) 0x07, + (byte) 0x08, // metaData + }; PublicBroadcastData data = PublicBroadcastData.parsePublicBroadcastData(serviceData); assertThat(data.isEncrypted()).isTrue(); assertThat(data.getAudioConfigQuality()).isEqualTo(3); assertThat(data.getMetadataLength()).isEqualTo(3); - assertThat(data.getMetadata()).isEqualTo(new byte[] { 0x06, 0x07, 0x08 }); + assertThat(data.getMetadata()).isEqualTo(new byte[] {0x06, 0x07, 0x08}); - byte[] serviceDataNoMetaData = new byte[] { - (byte) 0x02, // features, non-encrypted, standard quality prsent - (byte) 0x00, // metaDataLength - }; + byte[] serviceDataNoMetaData = + new byte[] { + (byte) 0x02, // features, non-encrypted, standard quality prsent + (byte) 0x00, // metaDataLength + }; PublicBroadcastData dataNoMetaData = PublicBroadcastData.parsePublicBroadcastData(serviceDataNoMetaData); assertThat(dataNoMetaData.isEncrypted()).isFalse(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java index a83e4bf7e5b..c0f0c2f2dd7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java @@ -152,8 +152,8 @@ public class ActiveDeviceManagerTest { mOriginalDualModeAudioState = Utils.isDualModeAudioEnabled(); when(mA2dpService.setActiveDevice(any())).thenReturn(true); - when(mHeadsetService.getHfpCallAudioPolicy(any())).thenReturn( - new BluetoothSinkAudioPolicy.Builder().build()); + when(mHeadsetService.getHfpCallAudioPolicy(any())) + .thenReturn(new BluetoothSinkAudioPolicy.Builder().build()); when(mHeadsetService.setActiveDevice(any())).thenReturn(true); when(mHearingAidService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.setActiveDevice(any())).thenReturn(true); @@ -171,20 +171,30 @@ public class ActiveDeviceManagerTest { when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId)) .thenReturn(connectedHearingAidDevices); - when(mA2dpService.getFallbackDevice()).thenAnswer(invocation -> { - if (!mDeviceConnectionStack.isEmpty() && Objects.equals(mA2dpDevice, - mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1))) { - return mA2dpDevice; - } - return null; - }); - when(mHeadsetService.getFallbackDevice()).thenAnswer(invocation -> { - if (!mDeviceConnectionStack.isEmpty() && Objects.equals(mHeadsetDevice, - mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1))) { - return mHeadsetDevice; - } - return null; - }); + when(mA2dpService.getFallbackDevice()) + .thenAnswer( + invocation -> { + if (!mDeviceConnectionStack.isEmpty() + && Objects.equals( + mA2dpDevice, + mDeviceConnectionStack.get( + mDeviceConnectionStack.size() - 1))) { + return mA2dpDevice; + } + return null; + }); + when(mHeadsetService.getFallbackDevice()) + .thenAnswer( + invocation -> { + if (!mDeviceConnectionStack.isEmpty() + && Objects.equals( + mHeadsetDevice, + mDeviceConnectionStack.get( + mDeviceConnectionStack.size() - 1))) { + return mHeadsetDevice; + } + return null; + }); } @After @@ -201,9 +211,7 @@ public class ActiveDeviceManagerTest { @Test public void testSetUpAndTearDown() {} - /** - * One A2DP is connected. - */ + /** One A2DP is connected. */ @Test public void onlyA2dpConnected_setA2dpActive() { a2dpConnected(mA2dpDevice, false); @@ -233,9 +241,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); } - /** - * Two A2DP are connected. Should set the second one active. - */ + /** Two A2DP are connected. Should set the second one active. */ @Test public void secondA2dpConnected_setSecondA2dpActive() { a2dpConnected(mA2dpDevice, false); @@ -245,9 +251,7 @@ public class ActiveDeviceManagerTest { verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); } - /** - * One A2DP is connected and disconnected later. Should then set active device to null. - */ + /** One A2DP is connected and disconnected later. Should then set active device to null. */ @Test public void lastA2dpDisconnected_clearA2dpActive() { a2dpConnected(mA2dpDevice, false); @@ -257,9 +261,7 @@ public class ActiveDeviceManagerTest { verify(mA2dpService, timeout(TIMEOUT_MS)).removeActiveDevice(true); } - /** - * Two A2DP are connected and active device is explicitly set. - */ + /** Two A2DP are connected and active device is explicitly set. */ @Test public void a2dpActiveDeviceSelected_setActive() { a2dpConnected(mA2dpDevice, false); @@ -276,8 +278,8 @@ public class ActiveDeviceManagerTest { } /** - * Two A2DP devices are connected and the current active is then disconnected. - * Should then set active device to fallback device. + * Two A2DP devices are connected and the current active is then disconnected. Should then set + * active device to fallback device. */ @Test public void a2dpSecondDeviceDisconnected_fallbackDeviceActive() { @@ -292,18 +294,14 @@ public class ActiveDeviceManagerTest { verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice); } - /** - * One Headset is connected. - */ + /** One Headset is connected. */ @Test public void onlyHeadsetConnected_setHeadsetActive() { headsetConnected(mHeadsetDevice, false); verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mHeadsetDevice); } - /** - * Two Headset are connected. Should set the second one active. - */ + /** Two Headset are connected. Should set the second one active. */ @Test public void secondHeadsetConnected_setSecondHeadsetActive() { headsetConnected(mHeadsetDevice, false); @@ -313,9 +311,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); } - /** - * One Headset is connected and disconnected later. Should then set active device to null. - */ + /** One Headset is connected and disconnected later. Should then set active device to null. */ @Test public void lastHeadsetDisconnected_clearHeadsetActive() { headsetConnected(mHeadsetDevice, false); @@ -325,9 +321,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); } - /** - * Two Headset are connected and active device is explicitly set. - */ + /** Two Headset are connected and active device is explicitly set. */ @Test public void headsetActiveDeviceSelected_setActive() { headsetConnected(mHeadsetDevice, false); @@ -344,8 +338,8 @@ public class ActiveDeviceManagerTest { } /** - * Two Headsets are connected and the current active is then disconnected. - * Should then set active device to fallback device. + * Two Headsets are connected and the current active is then disconnected. Should then set + * active device to fallback device. */ @Test public void headsetSecondDeviceDisconnected_fallbackDeviceActive() { @@ -576,19 +570,18 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, never()).setActiveDevice(any()); } - /** - * A headset device with connecting audio policy set to NOT ALLOWED. - */ + /** A headset device with connecting audio policy set to NOT ALLOWED. */ @Test public void notAllowedConnectingPolicyHeadsetConnected_noSetActiveDevice() { // setting connecting policy to NOT ALLOWED when(mHeadsetService.getHfpCallAudioPolicy(mHeadsetDevice)) - .thenReturn(new BluetoothSinkAudioPolicy.Builder() - .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .setActiveDevicePolicyAfterConnection( - BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) - .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .build()); + .thenReturn( + new BluetoothSinkAudioPolicy.Builder() + .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .setActiveDevicePolicyAfterConnection( + BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) + .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .build()); headsetConnected(mHeadsetDevice, false); verify(mHeadsetService, never()).setActiveDevice(mHeadsetDevice); @@ -596,14 +589,13 @@ public class ActiveDeviceManagerTest { @Test public void twoHearingAidDevicesConnected_WithTheSameHiSyncId() { - Assume.assumeTrue("Ignore test when HearingAidService is not enabled", - HearingAidService.isEnabled()); + Assume.assumeTrue( + "Ignore test when HearingAidService is not enabled", HearingAidService.isEnabled()); List connectedHearingAidDevices = new ArrayList<>(); connectedHearingAidDevices.add(mHearingAidDevice); connectedHearingAidDevices.add(mSecondaryAudioDevice); - when(mHearingAidService.getHiSyncId(mSecondaryAudioDevice)) - .thenReturn(mHearingAidHiSyncId); + when(mHearingAidService.getHiSyncId(mSecondaryAudioDevice)).thenReturn(mHearingAidHiSyncId); when(mHearingAidService.getConnectedPeerDevices(mHearingAidHiSyncId)) .thenReturn(connectedHearingAidDevices); @@ -613,9 +605,7 @@ public class ActiveDeviceManagerTest { verify(mHearingAidService, never()).setActiveDevice(mSecondaryAudioDevice); } - /** - * A combo (A2DP + Headset) device is connected. Then a Hearing Aid is connected. - */ + /** A combo (A2DP + Headset) device is connected. Then a Hearing Aid is connected. */ @Test public void hearingAidActive_clearA2dpAndHeadsetActive() { a2dpConnected(mA2dpHeadsetDevice, true); @@ -629,9 +619,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(null); } - /** - * A Hearing Aid is connected. Then a combo (A2DP + Headset) device is connected. - */ + /** A Hearing Aid is connected. Then a combo (A2DP + Headset) device is connected. */ @Test public void hearingAidActive_dontSetA2dpAndHeadsetActive() { hearingAidActiveDeviceChanged(mHearingAidDevice); @@ -643,9 +631,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); } - /** - * A Hearing Aid is connected. Then an A2DP active device is explicitly set. - */ + /** A Hearing Aid is connected. Then an A2DP active device is explicitly set. */ @Test public void hearingAidActive_setA2dpActiveExplicitly() { when(mHearingAidService.removeActiveDevice(anyBoolean())).thenReturn(true); @@ -662,9 +648,7 @@ public class ActiveDeviceManagerTest { Assert.assertTrue(mActiveDeviceManager.getHearingAidActiveDevices().isEmpty()); } - /** - * A Hearing Aid is connected. Then a Headset active device is explicitly set. - */ + /** A Hearing Aid is connected. Then a Headset active device is explicitly set. */ @Test public void hearingAidActive_setHeadsetActiveExplicitly() { when(mHearingAidService.removeActiveDevice(anyBoolean())).thenReturn(true); @@ -688,9 +672,7 @@ public class ActiveDeviceManagerTest { assertThat(mActiveDeviceManager.getHearingAidActiveDevices()).isEmpty(); } - /** - * One LE Audio is connected. - */ + /** One LE Audio is connected. */ @Test public void onlyLeAudioConnected_setHeadsetActive() { when(mLeAudioService.isGroupAvailableForStream(anyInt())).thenReturn(true); @@ -706,9 +688,7 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice); } - /** - * Two LE Audio are connected. Should set the second one active. - */ + /** Two LE Audio are connected. Should set the second one active. */ @Test public void secondLeAudioConnected_setSecondLeAudioActive() { when(mLeAudioService.isGroupAvailableForStream(anyInt())).thenReturn(true); @@ -719,9 +699,7 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); } - /** - * One LE Audio is connected and disconnected later. Should then set active device to null. - */ + /** One LE Audio is connected and disconnected later. Should then set active device to null. */ @Test public void lastLeAudioDisconnected_clearLeAudioActive() { when(mLeAudioService.isGroupAvailableForStream(anyInt())).thenReturn(true); @@ -732,9 +710,7 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, timeout(TIMEOUT_MS)).removeActiveDevice(false); } - /** - * Two LE Audio are connected and active device is explicitly set. - */ + /** Two LE Audio are connected and active device is explicitly set. */ @Test public void leAudioActiveDeviceSelected_setActive() { when(mLeAudioService.isGroupAvailableForStream(anyInt())).thenReturn(true); @@ -753,8 +729,8 @@ public class ActiveDeviceManagerTest { } /** - * Two LE Audio are connected and the current active is then disconnected. - * Should then set active device to fallback device. + * Two LE Audio are connected and the current active is then disconnected. Should then set + * active device to fallback device. */ @Test public void leAudioSecondDeviceDisconnected_fallbackDeviceActive() { @@ -769,9 +745,7 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); } - /** - * A combo (A2DP + Headset) device is connected. Then an LE Audio is connected. - */ + /** A combo (A2DP + Headset) device is connected. Then an LE Audio is connected. */ @Test public void leAudioActive_clearA2dpAndHeadsetActive() { a2dpConnected(mA2dpHeadsetDevice, true); @@ -785,9 +759,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); } - /** - * An LE Audio is connected. Then a combo (A2DP + Headset) device is connected. - */ + /** An LE Audio is connected. Then a combo (A2DP + Headset) device is connected. */ @Test public void leAudioActive_setA2dpAndHeadsetActive() { leAudioActiveDeviceChanged(mLeAudioDevice); @@ -799,9 +771,7 @@ public class ActiveDeviceManagerTest { verify(mHeadsetService, atLeastOnce()).setActiveDevice(mA2dpHeadsetDevice); } - /** - * An LE Audio is connected. Then an A2DP active device is explicitly set. - */ + /** An LE Audio is connected. Then an A2DP active device is explicitly set. */ @Test public void leAudioActive_setA2dpActiveExplicitly() { leAudioActiveDeviceChanged(mLeAudioDevice); @@ -815,9 +785,7 @@ public class ActiveDeviceManagerTest { Assert.assertNull(mActiveDeviceManager.getLeAudioActiveDevice()); } - /** - * An LE Audio is connected. Then a Headset active device is explicitly set. - */ + /** An LE Audio is connected. Then a Headset active device is explicitly set. */ @Test public void leAudioActive_setHeadsetActiveExplicitly() { leAudioActiveDeviceChanged(mLeAudioDevice); @@ -832,8 +800,8 @@ public class ActiveDeviceManagerTest { } /** - * An LE Audio connected. An A2DP connected. The A2DP disconnected. - * Then the LE Audio should be the active one. + * An LE Audio connected. An A2DP connected. The A2DP disconnected. Then the LE Audio should be + * the active one. */ @Test public void leAudioAndA2dpConnectedThenA2dpDisconnected_fallbackToLeAudio() { @@ -852,8 +820,8 @@ public class ActiveDeviceManagerTest { } /** - * An LE Audio set connected. The not active bud disconnected. - * Then the active device should not change and hasFallback should be set to false. + * An LE Audio set connected. The not active bud disconnected. Then the active device should not + * change and hasFallback should be set to false. */ @Test public void leAudioSetConnectedThenNotActiveOneDisconnected_noFallback() { @@ -876,9 +844,9 @@ public class ActiveDeviceManagerTest { } /** - * An LE Audio set connected. The active bud disconnected. Set active device - * returns false indicating an issue (the other bud is also disconnected). - * Then the active device should be removed and hasFallback should be set to false. + * An LE Audio set connected. The active bud disconnected. Set active device returns false + * indicating an issue (the other bud is also disconnected). Then the active device should be + * removed and hasFallback should be set to false. */ @Test public void leAudioSetConnectedThenActiveOneDisconnected_noFallback() { @@ -904,9 +872,9 @@ public class ActiveDeviceManagerTest { } /** - * An LE Audio set connected. The active bud disconnected. Set active device - * returns true indicating the other bud is going to be the active device. - * Then the active device should change and hasFallback should be set to true. + * An LE Audio set connected. The active bud disconnected. Set active device returns true + * indicating the other bud is going to be the active device. Then the active device should + * change and hasFallback should be set to true. */ @Test public void leAudioSetConnectedThenActiveOneDisconnected_hasFallback() { @@ -959,8 +927,8 @@ public class ActiveDeviceManagerTest { } /** - * An A2DP connected. An LE Audio connected. The LE Audio disconnected. - * Then the A2DP should be the active one. + * An A2DP connected. An LE Audio connected. The LE Audio disconnected. Then the A2DP should be + * the active one. */ @Test public void a2dpAndLeAudioConnectedThenLeAudioDisconnected_fallbackToA2dp() { @@ -981,8 +949,8 @@ public class ActiveDeviceManagerTest { } /** - * Two Hearing Aid are connected and the current active is then disconnected. - * Should then set active device to fallback device. + * Two Hearing Aid are connected and the current active is then disconnected. Should then set + * active device to fallback device. */ @Test public void hearingAidSecondDeviceDisconnected_fallbackDeviceActive() { @@ -1005,8 +973,8 @@ public class ActiveDeviceManagerTest { } /** - * Hearing aid is connected, but active device is different BT. - * When the active device is disconnected, the hearing aid should be the active one. + * Hearing aid is connected, but active device is different BT. When the active device is + * disconnected, the hearing aid should be the active one. */ @Test public void activeDeviceDisconnected_fallbackToHearingAid() { @@ -1032,13 +1000,10 @@ public class ActiveDeviceManagerTest { a2dpDisconnected(mA2dpDevice); verify(mA2dpService, timeout(TIMEOUT_MS).atLeast(1)).removeActiveDevice(false); - verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)) - .setActiveDevice(mHearingAidDevice); + verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mHearingAidDevice); } - /** - * One LE Hearing Aid is connected. - */ + /** One LE Hearing Aid is connected. */ @Test public void onlyLeHearingAidConnected_setLeAudioActive() { leHearingAidConnected(mLeHearingAidDevice); @@ -1052,10 +1017,7 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice); } - /** - * LE audio is connected after LE Hearing Aid device. - * Keep LE hearing Aid active. - */ + /** LE audio is connected after LE Hearing Aid device. Keep LE hearing Aid active. */ @Test public void leAudioConnectedAfterLeHearingAid_setLeAudioActiveShouldNotBeCalled() { leHearingAidConnected(mLeHearingAidDevice); @@ -1071,9 +1033,8 @@ public class ActiveDeviceManagerTest { } /** - * Test connect/disconnect of devices. - * Hearing Aid, LE Hearing Aid, A2DP connected, then LE hearing Aid and hearing aid - * disconnected. + * Test connect/disconnect of devices. Hearing Aid, LE Hearing Aid, A2DP connected, then LE + * hearing Aid and hearing aid disconnected. */ @Test public void activeDeviceChange_withHearingAidLeHearingAidAndA2dpDevices() { @@ -1186,8 +1147,8 @@ public class ActiveDeviceManagerTest { } /** - * Verifies that other profiles do not have their active device cleared when we fail to make - * a newly connected device active. + * Verifies that other profiles do not have their active device cleared when we fail to make a + * newly connected device active. */ @Test public void setActiveDeviceFailsUponConnection() { @@ -1242,9 +1203,7 @@ public class ActiveDeviceManagerTest { verify(mHearingAidService, times(1)).removeActiveDevice(anyBoolean()); } - /** - * A wired audio device is connected. Then all active devices are set to null. - */ + /** A wired audio device is connected. Then all active devices are set to null. */ @Test public void wiredAudioDeviceConnected_setAllActiveDevicesNull() { a2dpConnected(mA2dpDevice, false); @@ -1315,9 +1274,7 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, never()).setActiveDevice(any()); } - /** - * Helper to indicate A2dp connected for a device. - */ + /** Helper to indicate A2dp connected for a device. */ private void a2dpConnected(BluetoothDevice device, boolean supportHfp) { mDatabaseManager.setProfileConnectionPolicy( device, @@ -1336,13 +1293,13 @@ public class ActiveDeviceManagerTest { BluetoothProfile.STATE_CONNECTED); } - /** - * Helper to indicate A2dp disconnected for a device. - */ + /** Helper to indicate A2dp disconnected for a device. */ private void a2dpDisconnected(BluetoothDevice device) { mDeviceConnectionStack.remove(device); - mMostRecentDevice = (mDeviceConnectionStack.size() > 0) - ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null; + mMostRecentDevice = + (mDeviceConnectionStack.size() > 0) + ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) + : null; mActiveDeviceManager.profileConnectionStateChanged( BluetoothProfile.A2DP, @@ -1403,9 +1360,7 @@ public class ActiveDeviceManagerTest { mActiveDeviceManager.profileActiveDeviceChanged(BluetoothProfile.HEADSET, device); } - /** - * Helper to indicate Hearing Aid connected for a device. - */ + /** Helper to indicate Hearing Aid connected for a device. */ private void hearingAidConnected(BluetoothDevice device) { mDeviceConnectionStack.add(device); mMostRecentDevice = device; @@ -1417,13 +1372,13 @@ public class ActiveDeviceManagerTest { BluetoothProfile.STATE_CONNECTED); } - /** - * Helper to indicate Hearing Aid disconnected for a device. - */ + /** Helper to indicate Hearing Aid disconnected for a device. */ private void hearingAidDisconnected(BluetoothDevice device) { mDeviceConnectionStack.remove(device); - mMostRecentDevice = (mDeviceConnectionStack.size() > 0) - ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null; + mMostRecentDevice = + (mDeviceConnectionStack.size() > 0) + ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) + : null; mActiveDeviceManager.profileConnectionStateChanged( BluetoothProfile.HEARING_AID, @@ -1432,9 +1387,7 @@ public class ActiveDeviceManagerTest { BluetoothProfile.STATE_DISCONNECTED); } - /** - * Helper to indicate Hearing Aid active device changed for a device. - */ + /** Helper to indicate Hearing Aid active device changed for a device. */ private void hearingAidActiveDeviceChanged(BluetoothDevice device) { mDeviceConnectionStack.remove(device); mDeviceConnectionStack.add(device); @@ -1443,9 +1396,7 @@ public class ActiveDeviceManagerTest { mActiveDeviceManager.profileActiveDeviceChanged(BluetoothProfile.HEARING_AID, device); } - /** - * Helper to indicate LE Audio connected for a device. - */ + /** Helper to indicate LE Audio connected for a device. */ private void leAudioConnected(BluetoothDevice device) { mMostRecentDevice = device; @@ -1456,13 +1407,13 @@ public class ActiveDeviceManagerTest { BluetoothProfile.STATE_CONNECTED); } - /** - * Helper to indicate LE Audio disconnected for a device. - */ + /** Helper to indicate LE Audio disconnected for a device. */ private void leAudioDisconnected(BluetoothDevice device) { mDeviceConnectionStack.remove(device); - mMostRecentDevice = (mDeviceConnectionStack.size() > 0) - ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null; + mMostRecentDevice = + (mDeviceConnectionStack.size() > 0) + ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) + : null; mActiveDeviceManager.profileConnectionStateChanged( BluetoothProfile.LE_AUDIO, @@ -1471,9 +1422,7 @@ public class ActiveDeviceManagerTest { BluetoothProfile.STATE_DISCONNECTED); } - /** - * Helper to indicate LE Audio active device changed for a device. - */ + /** Helper to indicate LE Audio active device changed for a device. */ private void leAudioActiveDeviceChanged(BluetoothDevice device) { mDeviceConnectionStack.remove(device); mDeviceConnectionStack.add(device); @@ -1482,9 +1431,7 @@ public class ActiveDeviceManagerTest { mActiveDeviceManager.profileActiveDeviceChanged(BluetoothProfile.LE_AUDIO, device); } - /** - * Helper to indicate LE Hearing Aid connected for a device. - */ + /** Helper to indicate LE Hearing Aid connected for a device. */ private void leHearingAidConnected(BluetoothDevice device) { mDeviceConnectionStack.add(device); mMostRecentDevice = device; @@ -1499,8 +1446,10 @@ public class ActiveDeviceManagerTest { /** Helper to indicate LE Hearing Aid disconnected for a device. */ private void leHearingAidDisconnected(BluetoothDevice device) { mDeviceConnectionStack.remove(device); - mMostRecentDevice = (mDeviceConnectionStack.size() > 0) - ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null; + mMostRecentDevice = + (mDeviceConnectionStack.size() > 0) + ? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) + : null; mActiveDeviceManager.profileConnectionStateChanged( BluetoothProfile.HAP_CLIENT, diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java index d98ee994177..02dd5930e4a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java @@ -70,7 +70,7 @@ public class AdapterServiceBinderTest { @Test public void dump() { FileDescriptor fd = new FileDescriptor(); - String[] args = new String[] { }; + String[] args = new String[] {}; mBinder.dump(fd, args); verify(mService).dump(any(), any(), any()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java index 93a6688fe46..35fd88ac562 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java @@ -148,12 +148,14 @@ public class AdapterServiceRestartTest { Context targetContext = InstrumentationRegistry.getTargetContext(); mMockContentResolver = new MockContentResolver(targetContext); - mMockContentResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() { - @Override - public Bundle call(String method, String request, Bundle args) { - return Bundle.EMPTY; - } - }); + mMockContentResolver.addProvider( + Settings.AUTHORITY, + new MockContentProvider() { + @Override + public Bundle call(String method, String request, Bundle args) { + return Bundle.EMPTY; + } + }); mPowerManager = targetContext.getSystemService(PowerManager.class); mPermissionCheckerManager = targetContext.getSystemService(PermissionCheckerManager.class); @@ -170,8 +172,8 @@ public class AdapterServiceRestartTest { when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo); when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); when(mMockContext.getApplicationContext()).thenReturn(mMockContext); - when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0)).thenReturn( - mMockContext); + when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0)) + .thenReturn(mMockContext); when(mMockContext.getResources()).thenReturn(mMockResources); when(mMockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID); when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); @@ -204,10 +206,10 @@ public class AdapterServiceRestartTest { "AdapterServiceTestPrefs", Context.MODE_PRIVATE)); doAnswer( - invocation -> { - Object[] args = invocation.getArguments(); - return targetContext.getDatabasePath((String) args[0]); - }) + invocation -> { + Object[] args = invocation.getArguments(); + return targetContext.getDatabasePath((String) args[0]); + }) .when(mMockContext) .getDatabasePath(anyString()); @@ -221,7 +223,8 @@ public class AdapterServiceRestartTest { when(mIBluetoothCallback.asBinder()).thenReturn(mBinder); - doReturn(Process.BLUETOOTH_UID).when(mMockPackageManager) + doReturn(Process.BLUETOOTH_UID) + .when(mMockPackageManager) .getPackageUidAsUser(any(), anyInt(), anyInt()); when(mMockMetricsLogger.init(any())).thenReturn(true); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java index 78d69150547..28b3294a726 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java @@ -181,7 +181,6 @@ public class AdapterServiceTest { private static final int NATIVE_INIT_MS = 8000; private static final int NATIVE_DISABLE_MS = 8000; - private PackageManager mMockPackageManager; private MockContentResolver mMockContentResolver; private int mForegroundUserId; @@ -248,12 +247,14 @@ public class AdapterServiceTest { Context targetContext = InstrumentationRegistry.getTargetContext(); mMockContentResolver = new MockContentResolver(targetContext); - mMockContentResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() { - @Override - public Bundle call(String method, String request, Bundle args) { - return Bundle.EMPTY; - } - }); + mMockContentResolver.addProvider( + Settings.AUTHORITY, + new MockContentProvider() { + @Override + public Bundle call(String method, String request, Bundle args) { + return Bundle.EMPTY; + } + }); mBluetoothManager = targetContext.getSystemService(BluetoothManager.class); mCompanionDeviceManager = targetContext.getSystemService(CompanionDeviceManager.class); @@ -268,8 +269,8 @@ public class AdapterServiceTest { when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo); when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); when(mMockContext.getApplicationContext()).thenReturn(mMockContext); - when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0)).thenReturn( - mMockContext); + when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0)) + .thenReturn(mMockContext); when(mMockContext.getResources()).thenReturn(mMockResources); when(mMockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID); when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); @@ -304,10 +305,10 @@ public class AdapterServiceTest { "AdapterServiceTestPrefs", Context.MODE_PRIVATE)); doAnswer( - invocation -> { - Object[] args = invocation.getArguments(); - return targetContext.getDatabasePath((String) args[0]); - }) + invocation -> { + Object[] args = invocation.getArguments(); + return targetContext.getDatabasePath((String) args[0]); + }) .when(mMockContext) .getDatabasePath(anyString()); @@ -319,7 +320,8 @@ public class AdapterServiceTest { when(mIBluetoothCallback.asBinder()).thenReturn(mBinder); - doReturn(Process.BLUETOOTH_UID).when(mMockPackageManager) + doReturn(Process.BLUETOOTH_UID) + .when(mMockPackageManager) .getPackageUidAsUser(any(), anyInt(), anyInt()); when(mMockGattService.getName()).thenReturn("GattService"); @@ -573,10 +575,7 @@ public class AdapterServiceTest { Log.e(TAG, "doDisable() complete success"); } - /** - * Test: Turn Bluetooth on. - * Check whether the AdapterService gets started. - */ + /** Test: Turn Bluetooth on. Check whether the AdapterService gets started. */ @Test public void testEnable() { doEnable(false); @@ -598,10 +597,7 @@ public class AdapterServiceTest { assertThat(mAdapterService.getScanMode()).isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE); } - /** - * Test: Turn Bluetooth on/off. - * Check whether the AdapterService gets started and stopped. - */ + /** Test: Turn Bluetooth on/off. Check whether the AdapterService gets started and stopped. */ @Test public void testEnableDisable() { doEnable(false); @@ -609,8 +605,8 @@ public class AdapterServiceTest { } /** - * Test: Turn Bluetooth on/off with only GATT supported. - * Check whether the AdapterService gets started and stopped. + * Test: Turn Bluetooth on/off with only GATT supported. Check whether the AdapterService gets + * started and stopped. */ @Test public void testEnableDisableOnlyGatt() { @@ -633,10 +629,7 @@ public class AdapterServiceTest { doDisable(true); } - /** - * Test: Don't start GATT - * Check whether the AdapterService quits gracefully - */ + /** Test: Don't start GATT Check whether the AdapterService quits gracefully */ @Test public void testGattStartTimeout() { assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); @@ -671,10 +664,7 @@ public class AdapterServiceTest { assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); } - /** - * Test: Don't stop GATT - * Check whether the AdapterService quits gracefully - */ + /** Test: Don't stop GATT Check whether the AdapterService quits gracefully */ @Test public void testGattStopTimeout() { doEnable(false); @@ -841,10 +831,7 @@ public class AdapterServiceTest { mAdapterService.unregisterRemoteCallback(callback); } - /** - * Test: Don't start a classic profile - * Check whether the AdapterService quits gracefully - */ + /** Test: Don't start a classic profile Check whether the AdapterService quits gracefully */ @Test public void testProfileStartTimeout() { assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); @@ -922,15 +909,12 @@ public class AdapterServiceTest { assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); } - /** - * Test: Toggle snoop logging setting - * Check whether the AdapterService restarts fully - */ + /** Test: Toggle snoop logging setting Check whether the AdapterService restarts fully */ @Test public void testSnoopLoggingChange() { BluetoothProperties.snoop_log_mode_values snoopSetting = BluetoothProperties.snoop_log_mode() - .orElse(BluetoothProperties.snoop_log_mode_values.EMPTY); + .orElse(BluetoothProperties.snoop_log_mode_values.EMPTY); BluetoothProperties.snoop_log_mode(BluetoothProperties.snoop_log_mode_values.DISABLED); doEnable(false); @@ -974,11 +958,10 @@ public class AdapterServiceTest { BluetoothProperties.snoop_log_mode(snoopSetting); } - /** - * Test: Obfuscate a null Bluetooth - * Check if returned value from {@link AdapterService#obfuscateAddress(BluetoothDevice)} is - * an empty array when device address is null + * Test: Obfuscate a null Bluetooth Check if returned value from {@link + * AdapterService#obfuscateAddress(BluetoothDevice)} is an empty array when device address is + * null */ @Test public void testObfuscateBluetoothAddress_NullAddress() { @@ -1069,7 +1052,8 @@ public class AdapterServiceTest { } // Trigger address consolidate callback - remoteDevices.addressConsolidateCallback(Utils.getBytesFromAddress(TEST_BT_ADDR_1), + remoteDevices.addressConsolidateCallback( + Utils.getBytesFromAddress(TEST_BT_ADDR_1), Utils.getBytesFromAddress(TEST_BT_ADDR_2)); // Verify we can get correct identity address @@ -1127,9 +1111,8 @@ public class AdapterServiceTest { } /** - * Test: Get id for null address - * Check if returned value from {@link AdapterService#getMetricId(BluetoothDevice)} is - * 0 when device address is null + * Test: Get id for null address Check if returned value from {@link + * AdapterService#getMetricId(BluetoothDevice)} is 0 when device address is null */ @Test public void testGetMetricId_NullAddress() { @@ -1183,8 +1166,8 @@ public class AdapterServiceTest { FileDescriptor fd = new FileDescriptor(); PrintWriter writer = mock(PrintWriter.class); - mAdapterService.dump(fd, writer, new String[]{}); - mAdapterService.dump(fd, writer, new String[]{"set-test-mode", "enabled"}); + mAdapterService.dump(fd, writer, new String[] {}); + mAdapterService.dump(fd, writer, new String[] {"set-test-mode", "enabled"}); doReturn(new byte[0]).when(mNativeInterface).dumpMetrics(); mAdapterService.dump(fd, writer, new String[] {"--proto-bin"}); mAdapterService.dump(fd, writer, new String[] {"random", "arguments"}); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java index 0e779facba9..e3a2f9d91af 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java @@ -59,8 +59,9 @@ public class BondStateMachineTest { BluetoothDevice.DEVICE_TYPE_DUAL, BluetoothDevice.DEVICE_TYPE_LE }; - private static final ParcelUuid[] TEST_UUIDS = - {ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB")}; + private static final ParcelUuid[] TEST_UUIDS = { + ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB") + }; private static final int BOND_NONE = BluetoothDevice.BOND_NONE; private static final int BOND_BONDING = BluetoothDevice.BOND_BONDING; @@ -97,12 +98,11 @@ public class BondStateMachineTest { mRemoteDevices = new RemoteDevices(mAdapterService, mHandlerThread.getLooper()); mRemoteDevices.reset(); - when(mAdapterService.getResources()).thenReturn( - mTargetContext.getResources()); + when(mAdapterService.getResources()).thenReturn(mTargetContext.getResources()); mAdapterProperties = new AdapterProperties(mAdapterService); mAdapterProperties.init(mRemoteDevices); - mBondStateMachine = BondStateMachine.make(mAdapterService, mAdapterProperties, - mRemoteDevices); + mBondStateMachine = + BondStateMachine.make(mAdapterService, mAdapterProperties, mRemoteDevices); } @After @@ -142,11 +142,11 @@ public class BondStateMachineTest { verify(mNativeInterface, times(1)).removeBond(eq(TEST_BT_ADDR_BYTES)); verify(mNativeInterface, times(1)).removeBond(eq(TEST_BT_ADDR_BYTES_2)); - mBondStateMachine.bondStateChangeCallback(AbstractionLayer.BT_STATUS_SUCCESS, - TEST_BT_ADDR_BYTES, BOND_NONE, 0); + mBondStateMachine.bondStateChangeCallback( + AbstractionLayer.BT_STATUS_SUCCESS, TEST_BT_ADDR_BYTES, BOND_NONE, 0); TestUtils.waitForLooperToFinishScheduledTask(mBondStateMachine.getHandler().getLooper()); - mBondStateMachine.bondStateChangeCallback(AbstractionLayer.BT_STATUS_SUCCESS, - TEST_BT_ADDR_BYTES_2, BOND_NONE, 0); + mBondStateMachine.bondStateChangeCallback( + AbstractionLayer.BT_STATUS_SUCCESS, TEST_BT_ADDR_BYTES_2, BOND_NONE, 0); TestUtils.waitForLooperToFinishScheduledTask(mBondStateMachine.getHandler().getLooper()); // Try to pair these two devices again, createBondNative() should be invoked. @@ -173,12 +173,16 @@ public class BondStateMachineTest { mRemoteDevices.reset(); mBondStateMachine.mPendingBondedDevices.clear(); - BluetoothDevice device1 = BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice( - Utils.getAddressStringFromByte(TEST_BT_ADDR_BYTES), - BluetoothDevice.ADDRESS_TYPE_PUBLIC); - BluetoothDevice device2 = BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice( - Utils.getAddressStringFromByte(TEST_BT_ADDR_BYTES_2), - BluetoothDevice.ADDRESS_TYPE_RANDOM); + BluetoothDevice device1 = + BluetoothAdapter.getDefaultAdapter() + .getRemoteLeDevice( + Utils.getAddressStringFromByte(TEST_BT_ADDR_BYTES), + BluetoothDevice.ADDRESS_TYPE_PUBLIC); + BluetoothDevice device2 = + BluetoothAdapter.getDefaultAdapter() + .getRemoteLeDevice( + Utils.getAddressStringFromByte(TEST_BT_ADDR_BYTES_2), + BluetoothDevice.ADDRESS_TYPE_RANDOM); // The createBond() request for two devices with different address types. Message createBondMsg1 = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); @@ -257,219 +261,323 @@ public class BondStateMachineTest { testSendIntentNoPendingDevice( BOND_NONE, BOND_NONE, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_NONE, BOND_BONDING, false, BOND_BONDING, - true, BOND_NONE, BOND_BONDING, false); - testSendIntentNoPendingDevice(BOND_NONE, BOND_BONDED, false, BOND_BONDED, - true, BOND_NONE, BOND_BONDING, true); - testSendIntentNoPendingDevice(BOND_NONE, badBondState, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, BOND_NONE, false, BOND_NONE, - true, BOND_BONDING, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, BOND_BONDING, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, BOND_BONDED, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, true); - testSendIntentNoPendingDevice(BOND_BONDING, badBondState, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, BOND_NONE, false, BOND_NONE, - true, BOND_BONDED, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, BOND_BONDING, false, BOND_BONDING, - true, BOND_BONDED, BOND_BONDING, false); - testSendIntentNoPendingDevice(BOND_BONDED, BOND_BONDED, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, badBondState, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - - testSendIntentNoPendingDevice(BOND_NONE, BOND_NONE, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_NONE, BOND_BONDING, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_NONE, BOND_BONDED, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_NONE, badBondState, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, BOND_NONE, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, BOND_BONDING, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, BOND_BONDED, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDING, badBondState, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, BOND_NONE, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, BOND_BONDING, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, BOND_BONDED, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDevice(BOND_BONDED, badBondState, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_NONE, BOND_BONDING, false, BOND_BONDING, true, BOND_NONE, BOND_BONDING, false); + testSendIntentNoPendingDevice( + BOND_NONE, BOND_BONDED, false, BOND_BONDED, true, BOND_NONE, BOND_BONDING, true); + testSendIntentNoPendingDevice( + BOND_NONE, badBondState, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDING, BOND_NONE, false, BOND_NONE, true, BOND_BONDING, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDING, + BOND_BONDING, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentNoPendingDevice( + BOND_BONDING, BOND_BONDED, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, true); + testSendIntentNoPendingDevice( + BOND_BONDING, + badBondState, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentNoPendingDevice( + BOND_BONDED, BOND_NONE, false, BOND_NONE, true, BOND_BONDED, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDED, + BOND_BONDING, + false, + BOND_BONDING, + true, + BOND_BONDED, + BOND_BONDING, + false); + testSendIntentNoPendingDevice( + BOND_BONDED, BOND_BONDED, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDED, badBondState, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + + testSendIntentNoPendingDevice( + BOND_NONE, BOND_NONE, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_NONE, BOND_BONDING, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_NONE, BOND_BONDED, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_NONE, badBondState, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDING, BOND_NONE, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDING, BOND_BONDING, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDING, BOND_BONDED, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDING, badBondState, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDED, BOND_NONE, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDED, BOND_BONDING, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDED, BOND_BONDED, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDevice( + BOND_BONDED, badBondState, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); // Uuid not available, mPendingBondedDevice contains a remote device. - testSendIntentPendingDevice(BOND_NONE, BOND_NONE, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_NONE, BOND_BONDING, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_NONE, BOND_BONDED, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_NONE, badBondState, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, BOND_NONE, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, BOND_BONDING, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, BOND_BONDED, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, badBondState, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDED, BOND_NONE, false, BOND_NONE, - true, BOND_BONDING, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDED, BOND_BONDING, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDED, BOND_BONDED, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, true); - testSendIntentPendingDevice(BOND_BONDED, badBondState, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - - testSendIntentPendingDevice(BOND_NONE, BOND_NONE, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_NONE, BOND_BONDING, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_NONE, BOND_BONDED, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_NONE, badBondState, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, BOND_NONE, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, BOND_BONDING, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, BOND_BONDED, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDING, badBondState, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDED, BOND_NONE, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDED, BOND_BONDING, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDevice(BOND_BONDED, BOND_BONDED, true, BOND_BONDED, - true, BOND_BONDING, BOND_BONDED, false); - testSendIntentPendingDevice(BOND_BONDED, badBondState, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, BOND_NONE, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, BOND_BONDING, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, BOND_BONDED, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, badBondState, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, BOND_NONE, false, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, + BOND_BONDING, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentPendingDevice( + BOND_BONDING, BOND_BONDED, false, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, + badBondState, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentPendingDevice( + BOND_BONDED, BOND_NONE, false, BOND_NONE, true, BOND_BONDING, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDED, BOND_BONDING, false, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDED, BOND_BONDED, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, true); + testSendIntentPendingDevice( + BOND_BONDED, badBondState, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + + testSendIntentPendingDevice( + BOND_NONE, BOND_NONE, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, BOND_BONDING, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, BOND_BONDED, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_NONE, badBondState, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, BOND_NONE, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, BOND_BONDING, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, BOND_BONDED, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDING, badBondState, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDED, BOND_NONE, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDED, BOND_BONDING, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDevice( + BOND_BONDED, + BOND_BONDED, + true, + BOND_BONDED, + true, + BOND_BONDING, + BOND_BONDED, + false); + testSendIntentPendingDevice( + BOND_BONDED, badBondState, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); // Uuid available, mPendingBondedDevice is empty. - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_NONE, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_BONDING, false, BOND_BONDING, - true, BOND_NONE, BOND_BONDING, false); - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_BONDED, false, BOND_BONDED, - true, BOND_NONE, BOND_BONDED, false); - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, badBondState, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_NONE, false, BOND_NONE, - true, BOND_BONDING, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_BONDING, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_BONDED, false, BOND_BONDED, - true, BOND_BONDING, BOND_BONDED, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, badBondState, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_NONE, false, BOND_NONE, - true, BOND_BONDED, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_BONDING, false, BOND_BONDING, - true, BOND_BONDED, BOND_BONDING, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_BONDED, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, badBondState, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_NONE, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_BONDING, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_BONDED, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_NONE, badBondState, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_NONE, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_BONDING, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_BONDED, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, badBondState, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_NONE, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_BONDING, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_BONDED, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, badBondState, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, BOND_NONE, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, BOND_BONDING, false, BOND_BONDING, true, BOND_NONE, BOND_BONDING, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, BOND_BONDED, false, BOND_BONDED, true, BOND_NONE, BOND_BONDED, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, badBondState, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, BOND_NONE, false, BOND_NONE, true, BOND_BONDING, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, + BOND_BONDING, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, + BOND_BONDED, + false, + BOND_BONDED, + true, + BOND_BONDING, + BOND_BONDED, + false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, + badBondState, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, BOND_NONE, false, BOND_NONE, true, BOND_BONDED, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, + BOND_BONDING, + false, + BOND_BONDING, + true, + BOND_BONDED, + BOND_BONDING, + false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, BOND_BONDED, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, badBondState, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, BOND_NONE, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, BOND_BONDING, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, BOND_BONDED, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_NONE, badBondState, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, BOND_NONE, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, BOND_BONDING, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, BOND_BONDED, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDING, badBondState, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, BOND_NONE, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, BOND_BONDING, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, BOND_BONDED, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentNoPendingDeviceWithUuid( + BOND_BONDED, badBondState, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); // Uuid available, mPendingBondedDevice contains a remote device. - testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_NONE, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_BONDING, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_BONDED, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_NONE, badBondState, false, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_NONE, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_BONDING, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_BONDED, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, badBondState, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_NONE, false, BOND_NONE, - true, BOND_BONDING, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_BONDING, false, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_BONDED, false, BOND_BONDED, - true, BOND_BONDING, BOND_BONDED, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, badBondState, false, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - - testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_NONE, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_BONDING, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_BONDED, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_NONE, badBondState, true, BOND_NONE, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_NONE, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_BONDING, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_BONDED, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDING, badBondState, true, BOND_BONDING, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_NONE, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_BONDING, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_BONDED, true, BOND_BONDED, - true, BOND_BONDING, BOND_BONDED, false); - testSendIntentPendingDeviceWithUuid(BOND_BONDED, badBondState, true, BOND_BONDED, - false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, BOND_NONE, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, BOND_BONDING, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, BOND_BONDED, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, badBondState, false, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, BOND_NONE, false, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, + BOND_BONDING, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, BOND_BONDED, false, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, + badBondState, + false, + BOND_BONDING, + false, + BOND_NONE, + BOND_NONE, + false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, BOND_NONE, false, BOND_NONE, true, BOND_BONDING, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, BOND_BONDING, false, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, + BOND_BONDED, + false, + BOND_BONDED, + true, + BOND_BONDING, + BOND_BONDED, + false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, badBondState, false, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + + testSendIntentPendingDeviceWithUuid( + BOND_NONE, BOND_NONE, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, BOND_BONDING, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, BOND_BONDED, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_NONE, badBondState, true, BOND_NONE, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, BOND_NONE, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, BOND_BONDING, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, BOND_BONDED, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDING, badBondState, true, BOND_BONDING, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, BOND_NONE, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, BOND_BONDING, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, + BOND_BONDED, + true, + BOND_BONDED, + true, + BOND_BONDING, + BOND_BONDED, + false); + testSendIntentPendingDeviceWithUuid( + BOND_BONDED, badBondState, true, BOND_BONDED, false, BOND_NONE, BOND_NONE, false); } - private void testSendIntentCase(int oldState, int newState, boolean isTriggerFromDelayMessage, - int expectedNewState, boolean shouldBroadcast, int broadcastOldState, - int broadcastNewState, boolean shouldDelayMessageExist) { + private void testSendIntentCase( + int oldState, + int newState, + boolean isTriggerFromDelayMessage, + int expectedNewState, + boolean shouldBroadcast, + int broadcastOldState, + int broadcastNewState, + boolean shouldDelayMessageExist) { ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); // Setup old state before start test. mDeviceProperties.mBondState = oldState; try { - mBondStateMachine.sendIntent(mDevice, newState, TEST_BOND_REASON, - isTriggerFromDelayMessage); + mBondStateMachine.sendIntent( + mDevice, newState, TEST_BOND_REASON, isTriggerFromDelayMessage); } catch (IllegalArgumentException e) { // Do nothing. } @@ -481,14 +589,19 @@ public class BondStateMachineTest { // Check for bond state Intent status. if (shouldBroadcast) { - verify(mAdapterService, times(++mVerifyCount)).sendBroadcastAsUser( - intentArgument.capture(), eq(UserHandle.ALL), - eq(BLUETOOTH_CONNECT), any(Bundle.class)); - verifyBondStateChangeIntent(broadcastOldState, broadcastNewState, - intentArgument.getValue()); + verify(mAdapterService, times(++mVerifyCount)) + .sendBroadcastAsUser( + intentArgument.capture(), eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verifyBondStateChangeIntent( + broadcastOldState, broadcastNewState, intentArgument.getValue()); } else { - verify(mAdapterService, times(mVerifyCount)).sendBroadcastAsUser(any(Intent.class), - any(UserHandle.class), anyString(), any(Bundle.class)); + verify(mAdapterService, times(mVerifyCount)) + .sendBroadcastAsUser( + any(Intent.class), + any(UserHandle.class), + anyString(), + any(Bundle.class)); } if (shouldDelayMessageExist) { @@ -624,11 +737,11 @@ public class BondStateMachineTest { Assert.assertEquals(BluetoothDevice.ACTION_BOND_STATE_CHANGED, intent.getAction()); Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); Assert.assertEquals(newState, intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1)); - Assert.assertEquals(oldState, intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, - -1)); + Assert.assertEquals( + oldState, intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1)); if (newState == BOND_NONE) { - Assert.assertEquals(TEST_BOND_REASON, - intent.getIntExtra(BluetoothDevice.EXTRA_UNBOND_REASON, -1)); + Assert.assertEquals( + TEST_BOND_REASON, intent.getIntExtra(BluetoothDevice.EXTRA_UNBOND_REASON, -1)); } else { Assert.assertEquals(-1, intent.getIntExtra(BluetoothDevice.EXTRA_UNBOND_REASON, -1)); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java index 3e9f37b74c5..30eb0f1b62d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java @@ -53,12 +53,9 @@ public class CompanionManagerTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AdapterService mAdapterService; - @Mock - SharedPreferences mSharedPreferences; - @Mock - SharedPreferences.Editor mEditor; + @Mock private AdapterService mAdapterService; + @Mock SharedPreferences mSharedPreferences; + @Mock SharedPreferences.Editor mEditor; @Before public void setUp() throws Exception { @@ -72,8 +69,10 @@ public class CompanionManagerTest { doReturn(mHandlerThread.getLooper()).when(mAdapterService).getMainLooper(); // Mock SharedPreferences when(mSharedPreferences.edit()).thenReturn(mEditor); - doReturn(mSharedPreferences).when(mAdapterService).getSharedPreferences(eq( - CompanionManager.COMPANION_INFO), eq(Context.MODE_PRIVATE)); + doReturn(mSharedPreferences) + .when(mAdapterService) + .getSharedPreferences( + eq(CompanionManager.COMPANION_INFO), eq(Context.MODE_PRIVATE)); // Tell the AdapterService that it is a mock (see isMock documentation) doReturn(true).when(mAdapterService).isMock(); // Use the resources in the instrumentation instead of the mocked AdapterService @@ -147,20 +146,20 @@ public class CompanionManagerTest { private void checkReasonableConnParameterHelper(int priority) { // Max/Min values from the Bluetooth spec Version 5.3 | Vol 4, Part E | 7.8.18 - final int minInterval = 6; // 0x0006 + final int minInterval = 6; // 0x0006 final int maxInterval = 3200; // 0x0C80 - final int minLatency = 0; // 0x0000 - final int maxLatency = 499; // 0x01F3 - - int min = mCompanionManager.getGattConnParameters( - TEST_DEVICE, CompanionManager.GATT_CONN_INTERVAL_MIN, - priority); - int max = mCompanionManager.getGattConnParameters( - TEST_DEVICE, CompanionManager.GATT_CONN_INTERVAL_MAX, - priority); - int latency = mCompanionManager.getGattConnParameters( - TEST_DEVICE, CompanionManager.GATT_CONN_LATENCY, - priority); + final int minLatency = 0; // 0x0000 + final int maxLatency = 499; // 0x01F3 + + int min = + mCompanionManager.getGattConnParameters( + TEST_DEVICE, CompanionManager.GATT_CONN_INTERVAL_MIN, priority); + int max = + mCompanionManager.getGattConnParameters( + TEST_DEVICE, CompanionManager.GATT_CONN_INTERVAL_MAX, priority); + int latency = + mCompanionManager.getGattConnParameters( + TEST_DEVICE, CompanionManager.GATT_CONN_LATENCY, priority); Assert.assertTrue(max >= min); Assert.assertTrue(max >= minInterval); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java index f1de518872a..a715b357115 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java @@ -92,7 +92,6 @@ public class DataMigrationTest { when(mMockContext.getCacheDir()).thenReturn(mTargetContext.getCacheDir()); when(mMockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mPrefs); - } @After @@ -108,17 +107,15 @@ public class DataMigrationTest { assertThat(DataMigration.migrationStatus(mMockContext)).isEqualTo(status); } - /** - * Test: execute Empty migration - */ + /** Test: execute Empty migration */ @Test public void testEmptyMigration() { BluetoothLegacyContentProvider fakeContentProvider = new BluetoothLegacyContentProvider(mMockContext); mMockContentResolver.addProvider(AUTHORITY, fakeContentProvider); - final int nCallCount = DataMigration.sharedPreferencesKeys.length - + 1; // +1 for default preferences + final int nCallCount = + DataMigration.sharedPreferencesKeys.length + 1; // +1 for default preferences final int nBundleCount = 2; // `bluetooth_db` && `btopp.db` assertRunStatus(DataMigration.MIGRATION_STATUS_COMPLETED); @@ -136,14 +133,21 @@ public class DataMigrationTest { BluetoothLegacyContentProvider(Context ctx) { super(ctx); } + int mCallCount = 0; int mBundleCount = 0; + @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { mBundleCount++; return null; } + @Override public Bundle call(String method, String arg, Bundle extras) { mCallCount++; @@ -151,9 +155,7 @@ public class DataMigrationTest { } } - /** - * Test: execute migration without having a content provided registered - */ + /** Test: execute migration without having a content provided registered */ @Test public void testMissingProvider() { assertThat(DataMigration.isMigrationApkInstalled(mMockContext)).isFalse(); @@ -164,32 +166,25 @@ public class DataMigrationTest { assertThat(DataMigration.isMigrationApkInstalled(mMockContext)).isTrue(); } - /** - * Test: execute migration after too many attempt - */ + /** Test: execute migration after too many attempt */ @Test public void testTooManyAttempt() { - assertThat(mPrefs.getInt(DataMigration.MIGRATION_ATTEMPT_PROPERTY, -1)) - .isEqualTo(-1); + assertThat(mPrefs.getInt(DataMigration.MIGRATION_ATTEMPT_PROPERTY, -1)).isEqualTo(-1); for (int i = 0; i < DataMigration.MAX_ATTEMPT; i++) { - assertThat(DataMigration.incrementeMigrationAttempt(mMockContext)) - .isTrue(); + assertThat(DataMigration.incrementeMigrationAttempt(mMockContext)).isTrue(); assertThat(mPrefs.getInt(DataMigration.MIGRATION_ATTEMPT_PROPERTY, -1)) - .isEqualTo(i + 1); + .isEqualTo(i + 1); } - assertThat(DataMigration.incrementeMigrationAttempt(mMockContext)) - .isFalse(); + assertThat(DataMigration.incrementeMigrationAttempt(mMockContext)).isFalse(); assertThat(mPrefs.getInt(DataMigration.MIGRATION_ATTEMPT_PROPERTY, -1)) - .isEqualTo(DataMigration.MAX_ATTEMPT + 1); + .isEqualTo(DataMigration.MAX_ATTEMPT + 1); mMockContentResolver.addProvider(AUTHORITY, new MockContentProvider(mMockContext)); assertRunStatus(DataMigration.MIGRATION_STATUS_MAX_ATTEMPT); } - /** - * Test: execute migration of SharedPreferences - */ + /** Test: execute migration of SharedPreferences */ @Test public void testSharedPreferencesMigration() { BluetoothLegacySharedPreferencesContentProvider fakeContentProvider = @@ -224,8 +219,8 @@ public class DataMigrationTest { assertThat(DataMigration.sharedPreferencesMigration("empty", mMockContext)).isFalse(); - assertThat(DataMigration - .sharedPreferencesMigration("anything else", mMockContext)).isTrue(); + assertThat(DataMigration.sharedPreferencesMigration("anything else", mMockContext)) + .isTrue(); } private static class BluetoothLegacySharedPreferencesContentProvider @@ -233,15 +228,22 @@ public class DataMigrationTest { BluetoothLegacySharedPreferencesContentProvider(Context ctx) { super(ctx); } + String mLastMethod = null; int mCallCount = 0; int mBundleCount = 0; + @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { mBundleCount++; return null; } + @Override public Bundle call(String method, String arg, Bundle extras) { mCallCount++; @@ -252,7 +254,7 @@ public class DataMigrationTest { final String key = "key" + arg; Bundle b = new Bundle(); b.putStringArrayList(DataMigration.KEY_LIST, new ArrayList(Arrays.asList(key))); - switch(arg) { + switch (arg) { case "Boolean": b.putBoolean(key, true); break; @@ -272,7 +274,7 @@ public class DataMigrationTest { b.putObject(key, null); break; case "Invalid": - // Put anything different from Boolean/Long/Integer/String + // Put anything different from Boolean/Long/Integer/String b.putFloat(key, 42f); break; case "empty": @@ -286,15 +288,13 @@ public class DataMigrationTest { } } - /** - * Test: execute migration of BLUETOOTH_DATABASE and OPP_DATABASE without correct data - */ + /** Test: execute migration of BLUETOOTH_DATABASE and OPP_DATABASE without correct data */ @Test public void testIncompleteDbMigration() { when(mMockContext.getDatabasePath("btopp.db")) - .thenReturn(mTargetContext.getDatabasePath("TestOppDb")); + .thenReturn(mTargetContext.getDatabasePath("TestOppDb")); when(mMockContext.getDatabasePath("bluetooth_db")) - .thenReturn(mTargetContext.getDatabasePath("TestBluetoothDb")); + .thenReturn(mTargetContext.getDatabasePath("TestBluetoothDb")); BluetoothLegacyDbContentProvider fakeContentProvider = new BluetoothLegacyDbContentProvider(mMockContext); @@ -308,17 +308,13 @@ public class DataMigrationTest { } private static final List> FAKE_SAMPLE = - Arrays.asList( - new Pair("wrong_key", "wrong_content") - ); + Arrays.asList(new Pair("wrong_key", "wrong_content")); - /** - * Test: execute migration of BLUETOOTH_DATABASE - */ + /** Test: execute migration of BLUETOOTH_DATABASE */ @Test public void testBluetoothDbMigration() { when(mMockContext.getDatabasePath("bluetooth_db")) - .thenReturn(mTargetContext.getDatabasePath("TestBluetoothDb")); + .thenReturn(mTargetContext.getDatabasePath("TestBluetoothDb")); BluetoothLegacyDbContentProvider fakeContentProvider = new BluetoothLegacyDbContentProvider(mMockContext); @@ -333,17 +329,16 @@ public class DataMigrationTest { Log.d(TAG, "Metadata migrated: " + metadata); - assertWithMessage("Address mismatch") - .that(metadata.getAddress()).isEqualTo("my_address"); + assertWithMessage("Address mismatch").that(metadata.getAddress()).isEqualTo("my_address"); assertWithMessage("Connection policy mismatch") - .that(metadata.getProfileConnectionPolicy(BluetoothProfile.A2DP)) - .isEqualTo(CONNECTION_POLICY_FORBIDDEN); + .that(metadata.getProfileConnectionPolicy(BluetoothProfile.A2DP)) + .isEqualTo(CONNECTION_POLICY_FORBIDDEN); assertWithMessage("Custom metadata mismatch") - .that(metadata.getCustomizedMeta(BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING)) - .isEqualTo(CUSTOM_META); + .that(metadata.getCustomizedMeta(BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING)) + .isEqualTo(CUSTOM_META); } - private static final byte[] CUSTOM_META = new byte[]{ 42, 43, 44}; + private static final byte[] CUSTOM_META = new byte[] {42, 43, 44}; private static final List> BLUETOOTH_DATABASE_SAMPLE = Arrays.asList( @@ -401,16 +396,13 @@ public class DataMigrationTest { new Pair("untethered_right_low_battery_threshold", CUSTOM_META), new Pair("untethered_case_low_battery_threshold", CUSTOM_META), new Pair("spatial_audio", CUSTOM_META), - new Pair("fastpair_customized", CUSTOM_META) - ); + new Pair("fastpair_customized", CUSTOM_META)); - /** - * Test: execute migration of OPP_DATABASE - */ + /** Test: execute migration of OPP_DATABASE */ @Test public void testOppDbMigration() { when(mMockContext.getDatabasePath("btopp.db")) - .thenReturn(mTargetContext.getDatabasePath("TestOppDb")); + .thenReturn(mTargetContext.getDatabasePath("TestOppDb")); BluetoothLegacyDbContentProvider fakeContentProvider = new BluetoothLegacyDbContentProvider(mMockContext); @@ -438,23 +430,29 @@ public class DataMigrationTest { // Long new Pair(BluetoothShare.TOTAL_BYTES, 42L), - new Pair(BluetoothShare.TIMESTAMP, 42L) - ); + new Pair(BluetoothShare.TIMESTAMP, 42L)); private static class BluetoothLegacyDbContentProvider extends MockContentProvider { BluetoothLegacyDbContentProvider(Context ctx) { super(ctx); } + String mLastMethod = null; Cursor mCursor = null; int mCallCount = 0; int mBundleCount = 0; + @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { mBundleCount++; return mCursor; } + @Override public Bundle call(String method, String arg, Bundle extras) { mCallCount++; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java index 7acfcb494d0..e827751fb1e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java @@ -149,8 +149,7 @@ public class PhonePolicyTest { /** * Test that when new UUIDs are refreshed for a device then we set the priorities for various - * profiles accurately. The following profiles should have ON priorities: - * A2DP, HFP, HID and PAN + * profiles accurately. The following profiles should have ON priorities: A2DP, HFP, HID and PAN */ @Test public void testProcessInitProfilePriorities() { @@ -362,19 +361,25 @@ public class PhonePolicyTest { // Does not auto connect and allow HFP and A2DP to be connected processInitProfilePriorities_LeAudioHelper(true, false, false, false); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO, + .setProfileConnectionPolicy( + device, + BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.A2DP, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + .setProfileConnectionPolicy( + device, BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.HEADSET, + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Auto connect to HFP and A2DP but disallow LE Audio processInitProfilePriorities_LeAudioHelper(false, true, false, false); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO, + .setProfileConnectionPolicy( + device, + BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) .setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); @@ -384,13 +389,17 @@ public class PhonePolicyTest { // Does not auto connect and disallow LE Audio to be connected processInitProfilePriorities_LeAudioHelper(false, false, false, false); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) - .setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO, + .setProfileConnectionPolicy( + device, + BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) - .setProfileConnectionPolicy(device, BluetoothProfile.A2DP, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + .setProfileConnectionPolicy( + device, BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) - .setProfileConnectionPolicy(device, BluetoothProfile.HEADSET, + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } @@ -411,13 +420,17 @@ public class PhonePolicyTest { // Does not auto connect and allow HFP and A2DP to be connected processInitProfilePriorities_LeAudioHelper(true, false, true, false); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO, + .setProfileConnectionPolicy( + device, + BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.A2DP, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + .setProfileConnectionPolicy( + device, BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.HEADSET, + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Auto connect to LE audio but disallow HFP and A2DP @@ -425,22 +438,32 @@ public class PhonePolicyTest { verify(mLeAudioService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) .setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.HEADSET, + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .setProfileConnectionPolicy(device, BluetoothProfile.A2DP, + .setProfileConnectionPolicy( + device, + BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Does not auto connect and disallow HFP and A2DP to be connected processInitProfilePriorities_LeAudioHelper(false, false, true, false); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) - .setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO, + .setProfileConnectionPolicy( + device, + BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_ALLOWED); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) - .setProfileConnectionPolicy(device, BluetoothProfile.HEADSET, + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) - .setProfileConnectionPolicy(device, BluetoothProfile.A2DP, + .setProfileConnectionPolicy( + device, + BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } @@ -733,10 +756,10 @@ public class PhonePolicyTest { when(mAdapterService.getBondState(bondedDevice)).thenReturn(BluetoothDevice.BOND_BONDED); // Return CONNECTION_POLICY_ALLOWED over HFP and A2DP - when(mHeadsetService.getConnectionPolicy(bondedDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Inject an event that the adapter is turned on. mPhonePolicy.onBluetoothStateChange(BluetoothAdapter.STATE_OFF, BluetoothAdapter.STATE_ON); @@ -746,9 +769,7 @@ public class PhonePolicyTest { verify(mHeadsetService).connect(eq(bondedDevice)); } - /** - * Test that when an active device is disconnected, we will not auto connect it - */ + /** Test that when an active device is disconnected, we will not auto connect it */ @Test public void testDisconnectNoAutoConnect() { // Return desired values from the mocked object(s) @@ -762,18 +783,18 @@ public class PhonePolicyTest { connectionOrder.add(getTestDevice(mAdapter, 2)); connectionOrder.add(getTestDevice(mAdapter, 3)); - when(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()).thenReturn( - connectionOrder.get(0)); + when(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()) + .thenReturn(connectionOrder.get(0)); // Make all devices auto connect - when(mHeadsetService.getConnectionPolicy(connectionOrder.get(0))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mHeadsetService.getConnectionPolicy(connectionOrder.get(1))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mHeadsetService.getConnectionPolicy(connectionOrder.get(2))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mHeadsetService.getConnectionPolicy(connectionOrder.get(3))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + when(mHeadsetService.getConnectionPolicy(connectionOrder.get(0))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(connectionOrder.get(1))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(connectionOrder.get(2))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(connectionOrder.get(3))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Make one of the device active mPhonePolicy.profileActiveDeviceChanged(BluetoothProfile.A2DP, connectionOrder.get(0)); @@ -801,8 +822,8 @@ public class PhonePolicyTest { verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(3)), anyInt()); // Disconnect a2dp for the device from previous STATE_CONNECTED - when(mHeadsetService.getConnectionState(connectionOrder.get(1))).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mHeadsetService.getConnectionState(connectionOrder.get(1))) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); mPhonePolicy.profileConnectionStateChanged( BluetoothProfile.A2DP, connectionOrder.get(1), @@ -864,10 +885,10 @@ public class PhonePolicyTest { // Return PRIORITY_AUTO_CONNECT over HFP and A2DP. This would imply that the profiles are // auto-connectable. - when(mHeadsetService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); @@ -878,8 +899,8 @@ public class PhonePolicyTest { hsConnectedDevices.add(bondedDevices[0]); when(mHeadsetService.getConnectedDevices()).thenReturn(hsConnectedDevices); // Also the A2DP should say that its not connected for same device - when(mA2dpService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); // ACL is connected, lets simulate this. when(mAdapterService.getConnectionState(bondedDevices[0])) @@ -887,12 +908,15 @@ public class PhonePolicyTest { // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles - updateProfileConnectionStateHelper(bondedDevices[0], BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + bondedDevices[0], + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we get a call to A2DP connect - verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - eq(bondedDevices[0])); + verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(eq(bondedDevices[0])); } /** @@ -958,15 +982,15 @@ public class PhonePolicyTest { when(mAdapterService.getConnectionState(testDevice)) .thenReturn(BluetoothProfile.STATE_CONNECTED); - when(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()).thenReturn( - connectionOrder.get(0)); + when(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()) + .thenReturn(connectionOrder.get(0)); // Return PRIORITY_AUTO_CONNECT over HFP and A2DP. This would imply that the profiles are // auto-connectable. - when(mHeadsetService.getConnectionPolicy(connectionOrder.get(0))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(connectionOrder.get(0))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(connectionOrder.get(0))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(connectionOrder.get(0))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); @@ -977,22 +1001,28 @@ public class PhonePolicyTest { hsConnectedDevices.add(connectionOrder.get(0)); when(mHeadsetService.getConnectedDevices()).thenReturn(hsConnectedDevices); // Also the A2DP should say that its not connected for same device - when(mA2dpService.getConnectionState(connectionOrder.get(0))).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(connectionOrder.get(0))) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); // We send a connection success event for one profile since the re-connect *only* works if // we have already connected successfully over one of the profiles - updateProfileConnectionStateHelper(connectionOrder.get(0), BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + connectionOrder.get(0), + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we get a call to A2DP reconnect - verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - connectionOrder.get(0)); + verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(connectionOrder.get(0)); // We send a connection failure event for the attempted profile, and keep the connected // profile connected. - updateProfileConnectionStateHelper(connectionOrder.get(0), BluetoothProfile.A2DP, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); + updateProfileConnectionStateHelper( + connectionOrder.get(0), + BluetoothProfile.A2DP, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1000,17 +1030,23 @@ public class PhonePolicyTest { verify(mA2dpService, never()).setConnectionPolicy(eq(connectionOrder.get(0)), anyInt()); // Send a connection success event for one profile again without disconnecting all profiles - updateProfileConnectionStateHelper(connectionOrder.get(0), BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + connectionOrder.get(0), + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we won't get a call to A2DP reconnect again before all profiles disconnected - verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - connectionOrder.get(0)); + verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(connectionOrder.get(0)); // Send a disconnection event for all connected profiles hsConnectedDevices.remove(connectionOrder.get(0)); - updateProfileConnectionStateHelper(connectionOrder.get(0), BluetoothProfile.HEADSET, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); + updateProfileConnectionStateHelper( + connectionOrder.get(0), + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTED); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1173,9 +1209,9 @@ public class PhonePolicyTest { /** * Test that a second device will auto-connect if there is already one connected device. * - * Even though we currently only set one device to be auto connect. The consumer of the auto - * connect property works independently so that we will connect to all devices that are in - * auto connect mode. + *

Even though we currently only set one device to be auto connect. The consumer of the auto + * connect property works independently so that we will connect to all devices that are in auto + * connect mode. */ @Test public void testAutoConnectMultipleDevices() { @@ -1196,10 +1232,10 @@ public class PhonePolicyTest { // Return PRIORITY_AUTO_CONNECT over HFP and A2DP. This would imply that the profiles // are auto-connectable. - when(mHeadsetService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // We want to trigger (in CONNECT_OTHER_PROFILES_TIMEOUT) a call to connect A2DP // To enable that we need to make sure that HeadsetService returns the device as list // of connected devices. @@ -1217,35 +1253,39 @@ public class PhonePolicyTest { when(mHeadsetService.getConnectedDevices()).thenReturn(hsConnectedDevices); when(mA2dpService.getConnectedDevices()).thenReturn(a2dpConnectedDevices); // Two of the A2DP devices are not connected - when(mA2dpService.getConnectionState(a2dpNotConnectedDevice1)).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mA2dpService.getConnectionState(a2dpNotConnectedDevice2)).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(a2dpNotConnectedDevice1)) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(a2dpNotConnectedDevice2)) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles - updateProfileConnectionStateHelper(a2dpNotConnectedDevice1, BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + a2dpNotConnectedDevice1, + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles - updateProfileConnectionStateHelper(a2dpNotConnectedDevice2, BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + a2dpNotConnectedDevice2, + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we get a call to A2DP connect - verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - eq(a2dpNotConnectedDevice1)); - verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - eq(a2dpNotConnectedDevice2)); + verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(eq(a2dpNotConnectedDevice1)); + verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(eq(a2dpNotConnectedDevice2)); } /** * Test that the connection policy of all devices are set as appropriate if there is one - * connected device. - * - The HFP and A2DP connect priority for connected devices is set to - * BluetoothProfile.PRIORITY_AUTO_CONNECT - * - The HFP and A2DP connect priority for bonded devices is set to - * BluetoothProfile.CONNECTION_POLICY_ALLOWED + * connected device. - The HFP and A2DP connect priority for connected devices is set to + * BluetoothProfile.PRIORITY_AUTO_CONNECT - The HFP and A2DP connect priority for bonded devices + * is set to BluetoothProfile.CONNECTION_POLICY_ALLOWED */ @Test public void testSetConnectionPolicyMultipleDevices() { @@ -1271,29 +1311,29 @@ public class PhonePolicyTest { if (i == 0) { hsConnectedDevices.add(testDevice); a2dpConnectedDevices.add(testDevice); - when(mHeadsetService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); } if (i == 1) { hsConnectedDevices.add(testDevice); - when(mHeadsetService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mA2dpService.getConnectionPolicy(testDevice)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); } if (i == 2) { a2dpConnectedDevices.add(testDevice); - when(mHeadsetService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mA2dpService.getConnectionPolicy(testDevice)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); } if (i == 3) { // Device not connected - when(mHeadsetService.getConnectionPolicy(testDevice)).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(testDevice)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mA2dpService.getConnectionPolicy(testDevice)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); } @@ -1304,41 +1344,43 @@ public class PhonePolicyTest { when(mA2dpService.getConnectedDevices()).thenReturn(a2dpConnectedDevices); // Some of the devices are not connected // testDevices[0] - connected for both HFP and A2DP - when(mHeadsetService.getConnectionState(testDevices[0])).thenReturn( - BluetoothProfile.STATE_CONNECTED); - when(mA2dpService.getConnectionState(testDevices[0])).thenReturn( - BluetoothProfile.STATE_CONNECTED); + when(mHeadsetService.getConnectionState(testDevices[0])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); + when(mA2dpService.getConnectionState(testDevices[0])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); // testDevices[1] - connected only for HFP - will auto-connect for A2DP - when(mHeadsetService.getConnectionState(testDevices[1])).thenReturn( - BluetoothProfile.STATE_CONNECTED); - when(mA2dpService.getConnectionState(testDevices[1])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mHeadsetService.getConnectionState(testDevices[1])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); + when(mA2dpService.getConnectionState(testDevices[1])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); // testDevices[2] - connected only for A2DP - will auto-connect for HFP - when(mHeadsetService.getConnectionState(testDevices[2])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mA2dpService.getConnectionState(testDevices[2])).thenReturn( - BluetoothProfile.STATE_CONNECTED); + when(mHeadsetService.getConnectionState(testDevices[2])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(testDevices[2])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); // testDevices[3] - not connected - when(mHeadsetService.getConnectionState(testDevices[3])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mA2dpService.getConnectionState(testDevices[3])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - + when(mHeadsetService.getConnectionState(testDevices[3])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(testDevices[3])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); // Generate connection state changed for HFP for testDevices[1] and trigger // auto-connect for A2DP. - updateProfileConnectionStateHelper(testDevices[1], BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + testDevices[1], + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we get a call to A2DP connect - verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - eq(testDevices[1])); + verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(eq(testDevices[1])); // testDevices[1] auto-connect completed for A2DP a2dpConnectedDevices.add(testDevices[1]); when(mA2dpService.getConnectedDevices()).thenReturn(a2dpConnectedDevices); - when(mA2dpService.getConnectionState(testDevices[1])).thenReturn( - BluetoothProfile.STATE_CONNECTED); + when(mA2dpService.getConnectionState(testDevices[1])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); // Check the connect priorities for all devices // - testDevices[0] - connected for HFP and A2DP: setConnectionPolicy() should not be called @@ -1350,8 +1392,9 @@ public class PhonePolicyTest { // called verify(mHeadsetService, times(0)).setConnectionPolicy(eq(testDevices[0]), anyInt()); verify(mA2dpService, times(0)).setConnectionPolicy(eq(testDevices[0]), anyInt()); - verify(mHeadsetService, times(0)).setConnectionPolicy(eq(testDevices[1]), - eq(BluetoothProfile.PRIORITY_AUTO_CONNECT)); + verify(mHeadsetService, times(0)) + .setConnectionPolicy( + eq(testDevices[1]), eq(BluetoothProfile.PRIORITY_AUTO_CONNECT)); verify(mA2dpService, times(0)).setConnectionPolicy(eq(testDevices[1]), anyInt()); verify(mHeadsetService, times(0)).setConnectionPolicy(eq(testDevices[2]), anyInt()); verify(mA2dpService, times(0)).setConnectionPolicy(eq(testDevices[2]), anyInt()); @@ -1361,18 +1404,21 @@ public class PhonePolicyTest { // Generate connection state changed for A2DP for testDevices[2] and trigger // auto-connect for HFP. - updateProfileConnectionStateHelper(testDevices[2], BluetoothProfile.A2DP, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + testDevices[2], + BluetoothProfile.A2DP, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we get a call to HFP connect - verify(mHeadsetService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( - eq(testDevices[2])); + verify(mHeadsetService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) + .connect(eq(testDevices[2])); // testDevices[2] auto-connect completed for HFP hsConnectedDevices.add(testDevices[2]); when(mHeadsetService.getConnectedDevices()).thenReturn(hsConnectedDevices); - when(mHeadsetService.getConnectionState(testDevices[2])).thenReturn( - BluetoothProfile.STATE_CONNECTED); + when(mHeadsetService.getConnectionState(testDevices[2])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); // Check the connect priorities for all devices // - testDevices[0] - connected for HFP and A2DP: setConnectionPolicy() should not be called @@ -1387,16 +1433,15 @@ public class PhonePolicyTest { verify(mHeadsetService, times(0)).setConnectionPolicy(eq(testDevices[1]), anyInt()); verify(mA2dpService, times(0)).setConnectionPolicy(eq(testDevices[1]), anyInt()); verify(mHeadsetService, times(0)).setConnectionPolicy(eq(testDevices[2]), anyInt()); - verify(mA2dpService, times(0)).setConnectionPolicy(eq(testDevices[2]), - eq(BluetoothProfile.PRIORITY_AUTO_CONNECT)); + verify(mA2dpService, times(0)) + .setConnectionPolicy( + eq(testDevices[2]), eq(BluetoothProfile.PRIORITY_AUTO_CONNECT)); verify(mHeadsetService, times(0)).setConnectionPolicy(eq(testDevices[3]), anyInt()); verify(mA2dpService, times(0)).setConnectionPolicy(eq(testDevices[3]), anyInt()); clearInvocations(mHeadsetService, mA2dpService); } - /** - * Test that we will not try to reconnect on a profile if all the connections failed - */ + /** Test that we will not try to reconnect on a profile if all the connections failed */ @Test public void testNoReconnectOnNoConnect() { // Return a list of bonded devices (just one) @@ -1406,10 +1451,10 @@ public class PhonePolicyTest { // Return PRIORITY_AUTO_CONNECT over HFP and A2DP. This would imply that the profiles are // auto-connectable. - when(mHeadsetService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); @@ -1418,23 +1463,23 @@ public class PhonePolicyTest { when(mA2dpService.getConnectedDevices()).thenReturn(Collections.emptyList()); // Both A2DP and HFP should say this device is not connected, except for the intent - when(mA2dpService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mHeadsetService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mHeadsetService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); mPhonePolicy.handleAclConnected(bondedDevices[0]); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // Check that we don't get any calls to reconnect - verify(mA2dpService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()).connect( - eq(bondedDevices[0])); + verify(mA2dpService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()) + .connect(eq(bondedDevices[0])); verify(mHeadsetService, never()).connect(eq(bondedDevices[0])); } /** - * Test that we will not try to reconnect on a profile if all the connections failed - * with multiple devices + * Test that we will not try to reconnect on a profile if all the connections failed with + * multiple devices */ @Test public void testNoReconnectOnNoConnect_MultiDevice() { @@ -1446,32 +1491,32 @@ public class PhonePolicyTest { // Return PRIORITY_AUTO_CONNECT over HFP and A2DP. This would imply that the profiles are // auto-connectable. - when(mHeadsetService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mHeadsetService.getConnectionPolicy(bondedDevices[1])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevices[1])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevices[1])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevices[1])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); // Return an a list with only the second device as connected - when(mHeadsetService.getConnectedDevices()).thenReturn( - Collections.singletonList(bondedDevices[1])); - when(mA2dpService.getConnectedDevices()).thenReturn( - Collections.singletonList(bondedDevices[1])); + when(mHeadsetService.getConnectedDevices()) + .thenReturn(Collections.singletonList(bondedDevices[1])); + when(mA2dpService.getConnectedDevices()) + .thenReturn(Collections.singletonList(bondedDevices[1])); // Both A2DP and HFP should say this device is not connected, except for the intent - when(mA2dpService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mHeadsetService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mA2dpService.getConnectionState(bondedDevices[1])).thenReturn( - BluetoothProfile.STATE_CONNECTED); - when(mHeadsetService.getConnectionState(bondedDevices[1])).thenReturn( - BluetoothProfile.STATE_CONNECTED); + when(mA2dpService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mHeadsetService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(bondedDevices[1])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); + when(mHeadsetService.getConnectionState(bondedDevices[1])) + .thenReturn(BluetoothProfile.STATE_CONNECTED); // ACL is connected for both devices. when(mAdapterService.getConnectionState(bondedDevices[0])) @@ -1485,8 +1530,8 @@ public class PhonePolicyTest { waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // Check that we don't get any calls to reconnect - verify(mA2dpService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()).connect( - eq(bondedDevices[0])); + verify(mA2dpService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()) + .connect(eq(bondedDevices[0])); verify(mHeadsetService, never()).connect(eq(bondedDevices[0])); } @@ -1503,29 +1548,29 @@ public class PhonePolicyTest { // Return PRIORITY_AUTO_CONNECT over HFP and A2DP. This would imply that the profiles are // auto-connectable. - when(mHeadsetService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevices[0])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mHeadsetService.getConnectionPolicy(bondedDevices[1])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mA2dpService.getConnectionPolicy(bondedDevices[1])).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevices[0])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getConnectionPolicy(bondedDevices[1])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mA2dpService.getConnectionPolicy(bondedDevices[1])) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); // Return an a list with only the second device as connected - when(mHeadsetService.getConnectedDevices()).thenReturn( - Collections.singletonList(bondedDevices[1])); + when(mHeadsetService.getConnectedDevices()) + .thenReturn(Collections.singletonList(bondedDevices[1])); when(mA2dpService.getConnectedDevices()).thenReturn(Collections.emptyList()); // Both A2DP and HFP should say this device is not connected, except for the intent - when(mA2dpService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mHeadsetService.getConnectionState(bondedDevices[0])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); - when(mA2dpService.getConnectionState(bondedDevices[1])).thenReturn( - BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mHeadsetService.getConnectionState(bondedDevices[0])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); + when(mA2dpService.getConnectionState(bondedDevices[1])) + .thenReturn(BluetoothProfile.STATE_DISCONNECTED); // ACL is connected, lets simulate this. when(mAdapterService.getConnectionState(bondedDevices[1])) @@ -1533,8 +1578,11 @@ public class PhonePolicyTest { // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles - updateProfileConnectionStateHelper(bondedDevices[1], BluetoothProfile.HEADSET, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + updateProfileConnectionStateHelper( + bondedDevices[1], + BluetoothProfile.HEADSET, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); // Check that we do get A2DP call to reconnect, because HEADSET just got connected verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)) @@ -1560,15 +1608,14 @@ public class PhonePolicyTest { mPhonePolicy.onUuidsDiscovered(device, null); // Check that we do not crash and not call any setPriority methods - verify(mHeadsetService, - after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()) + verify(mHeadsetService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()) .setConnectionPolicy(eq(device), eq(BluetoothProfile.CONNECTION_POLICY_ALLOWED)); verify(mA2dpService, never()) .setConnectionPolicy(eq(device), eq(BluetoothProfile.CONNECTION_POLICY_ALLOWED)); } - private void updateProfileConnectionStateHelper(BluetoothDevice device, int profileId, - int nextState, int prevState) { + private void updateProfileConnectionStateHelper( + BluetoothDevice device, int profileId, int nextState, int prevState) { switch (profileId) { case BluetoothProfile.A2DP: when(mA2dpService.getConnectionState(device)).thenReturn(nextState); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java index fb4d3122efa..5755864ef80 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java @@ -130,7 +130,6 @@ public class ProfileServiceTest { } Assert.assertNotNull(Looper.myLooper()); - doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); doNothing().when(mAdapterService).addProfile(any()); doNothing().when(mAdapterService).removeProfile(any()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java index 5cbd92d4b3a..ec1e9774501 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java @@ -67,8 +67,9 @@ public class RemoteDevicesTest { mDevice1 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR_1); mHandlerThread = new HandlerThread("RemoteDevicesTestHandlerThread"); mHandlerThread.start(); - mTestLooperManager = InstrumentationRegistry.getInstrumentation() - .acquireLooperManager(mHandlerThread.getLooper()); + mTestLooperManager = + InstrumentationRegistry.getInstrumentation() + .acquireLooperManager(mHandlerThread.getLooper()); mBluetoothManager = mTargetContext.getSystemService(BluetoothManager.class); when(mAdapterService.getSystemService(Context.BLUETOOTH_SERVICE)) @@ -111,32 +112,34 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that update same battery level for the same device does not trigger intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); verify(mAdapterService).sendBroadcast(any(), anyString(), any()); // Verify that updating battery level to different value triggers the intent again batteryLevel = 15; - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService, times(2)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); // Verify that user can get battery level after the update - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); verifyNoMoreInteractions(mAdapterService); } @@ -149,7 +152,7 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating with invalid battery level does not trigger the intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); verify(mAdapterService, never()).sendBroadcast(any(), anyString(), any()); // Verify that device property stays null after invalid update @@ -166,7 +169,7 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating invalid battery level does not trigger the intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); verify(mAdapterService, never()).sendBroadcast(any(), anyString(), any()); // Verify that device property stays null after invalid update @@ -181,7 +184,7 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that resetting battery level keeps device property null - mRemoteDevices.resetBatteryLevel(mDevice1, /*fromBas=*/ false); + mRemoteDevices.resetBatteryLevel(mDevice1, /* fromBas= */ false); Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); verifyNoMoreInteractions(mAdapterService); @@ -195,40 +198,43 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that resetting battery level changes it back to BluetoothDevice // .BATTERY_LEVEL_UNKNOWN - mRemoteDevices.resetBatteryLevel(mDevice1, /*fromBas=*/ false); + mRemoteDevices.resetBatteryLevel(mDevice1, /* fromBas= */ false); // Verify BATTERY_LEVEL_CHANGED intent is sent after first reset - verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); - verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - mIntentArgument); + verify(mAdapterService, times(2)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); + verifyBatteryLevelChangedIntent( + mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify value is reset in properties Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), BluetoothDevice.BATTERY_LEVEL_UNKNOWN); // Verify no intent is sent after second reset - mRemoteDevices.resetBatteryLevel(mDevice1, /*fromBas=*/ false); - verify(mAdapterService, times(2)).sendBroadcast(any(), anyString(), - any()); + mRemoteDevices.resetBatteryLevel(mDevice1, /* fromBas= */ false); + verify(mAdapterService, times(2)).sendBroadcast(any(), anyString(), any()); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService, times(3)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); @@ -243,16 +249,17 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that resetting battery level changes it back to BluetoothDevice // .BATTERY_LEVEL_UNKNOWN @@ -261,20 +268,23 @@ public class RemoteDevicesTest { BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED); // Verify BATTERY_LEVEL_CHANGED intent is sent after first reset - verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); - verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - mIntentArgument); + verify(mAdapterService, times(2)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); + verifyBatteryLevelChangedIntent( + mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify value is reset in properties Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), BluetoothDevice.BATTERY_LEVEL_UNKNOWN); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService, times(3)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); @@ -292,16 +302,17 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that battery level is not reset mRemoteDevices.onHeadsetConnectionStateChanged( @@ -310,8 +321,8 @@ public class RemoteDevicesTest { BluetoothProfile.STATE_DISCONNECTED); Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(batteryLevel, - mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); + Assert.assertEquals( + batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); // Recover the previous battery service if exists clearBatteryServiceForTesting(oldBatteryService); @@ -328,43 +339,54 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(batteryLevel, - mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); + Assert.assertEquals( + batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); // Verify that when device is completely disconnected, RemoteDevices reset battery level to // BluetoothDevice.BATTERY_LEVEL_UNKNOWN when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); - mRemoteDevices.aclStateChangeCallback(0, Utils.getByteAddress(mDevice1), - AbstractionLayer.BT_ACL_STATE_DISCONNECTED, 2, 19, + mRemoteDevices.aclStateChangeCallback( + 0, + Utils.getByteAddress(mDevice1), + AbstractionLayer.BT_ACL_STATE_DISCONNECTED, + 2, + 19, BluetoothDevice.ERROR); // HCI code 19 remote terminated // Verify ACTION_ACL_DISCONNECTED and BATTERY_LEVEL_CHANGED intent are sent - verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); + verify(mAdapterService, times(3)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verify(mAdapterService, times(2)).obfuscateAddress(mDevice1); - verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + verifyBatteryLevelChangedIntent( + mDevice1, + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - Assert.assertEquals(BLUETOOTH_CONNECT, + Assert.assertEquals( + BLUETOOTH_CONNECT, mStringArgument.getAllValues().get(mStringArgument.getAllValues().size() - 2)); - Assert.assertEquals(BluetoothDevice.ACTION_ACL_DISCONNECTED, - mIntentArgument.getValue().getAction()); + Assert.assertEquals( + BluetoothDevice.ACTION_ACL_DISCONNECTED, mIntentArgument.getValue().getAction()); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify value is reset in properties Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService, times(4)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService, times(4)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); } @@ -379,8 +401,9 @@ public class RemoteDevicesTest { // Verify that ACTION_HF_INDICATORS_VALUE_CHANGED intent updates battery level mRemoteDevices.onHfIndicatorValueChanged( mDevice1, HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS, batteryLevel); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); } @@ -411,8 +434,9 @@ public class RemoteDevicesTest { BluetoothAssignedNumbers.PLANTRONICS, BluetoothHeadset.AT_CMD_TYPE_SET, getXEventArray(3, 8)); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, 42, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); } @@ -437,8 +461,9 @@ public class RemoteDevicesTest { 3, 10 }); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, 60, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); } @@ -446,67 +471,101 @@ public class RemoteDevicesTest { @Test public void testGetBatteryLevelFromXEventVsc() { Assert.assertEquals(42, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(3, 8))); - Assert.assertEquals(100, - RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(10, 11))); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + Assert.assertEquals( + 100, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(10, 11))); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(1, 1))); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(3, 1))); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(-1, 1))); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(-1, -1))); } @Test public void testGetBatteryLevelFromAppleBatteryVsc() { - Assert.assertEquals(10, RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 1, BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 0 - })); - Assert.assertEquals(100, RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 1, BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 9 - })); - Assert.assertEquals(60, RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 3, - BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, - 5, - 2, - 1, - 3, - 10 - })); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 3, - BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, - 5, - 2, - 1, - 3 - })); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 1, - BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, - 10 - })); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 1, - BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, - -1 - })); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ - 1, - BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, - "5" - })); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{1, 35, 37})); - Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + Assert.assertEquals( + 10, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 1, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + 0 + })); + Assert.assertEquals( + 100, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 1, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + 9 + })); + Assert.assertEquals( + 60, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 3, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + 5, + 2, + 1, + 3, + 10 + })); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 3, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + 5, + 2, + 1, + 3 + })); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 1, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + 10 + })); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 1, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + -1 + })); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc( + new Object[] { + 1, + BluetoothHeadset + .VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, + "5" + })); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, + RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[] {1, 35, 37})); + Assert.assertEquals( + BluetoothDevice.BATTERY_LEVEL_UNKNOWN, RemoteDevices.getBatteryLevelFromAppleBatteryVsc( - new Object[]{1, "WRONG", "WRONG"})); + new Object[] {1, "WRONG", "WRONG"})); } @Test @@ -517,16 +576,17 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that resetting battery level changes it back to BluetoothDevice // .BATTERY_LEVEL_UNKNOWN @@ -536,21 +596,24 @@ public class RemoteDevicesTest { BluetoothProfile.STATE_DISCONNECTED); // Verify BATTERY_LEVEL_CHANGED intent is sent after first reset - verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); - verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, - mIntentArgument); + verify(mAdapterService, times(2)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); + verifyBatteryLevelChangedIntent( + mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify value is reset in properties Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), BluetoothDevice.BATTERY_LEVEL_UNKNOWN); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), - mStringArgument.capture(), any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService, times(3)) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); @@ -568,16 +631,17 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), - batteryLevel); + Assert.assertEquals( + mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that battery level is not reset. mRemoteDevices.onHeadsetClientConnectionStateChanged( @@ -586,8 +650,8 @@ public class RemoteDevicesTest { BluetoothProfile.STATE_DISCONNECTED); Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); - Assert.assertEquals(batteryLevel, - mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); + Assert.assertEquals( + batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); clearBatteryServiceForTesting(oldBatteryService); @@ -606,7 +670,7 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); verify(mAdapterService) .sendBroadcast( mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); @@ -619,14 +683,14 @@ public class RemoteDevicesTest { mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that updating battery service overrides hfp battery level - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel2, /*fromBas=*/ true); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel2, /* fromBas= */ true); verify(mAdapterService, times(2)) .sendBroadcast( mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel2, mIntentArgument); // Verify that the battery level isn't reset - mRemoteDevices.resetBatteryLevel(mDevice1, /*fromBas=*/ true); + mRemoteDevices.resetBatteryLevel(mDevice1, /* fromBas= */ true); Assert.assertEquals( batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); verify(mAdapterService, times(3)) @@ -650,7 +714,7 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ false); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ false); verify(mAdapterService) .sendBroadcast( mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); @@ -663,11 +727,11 @@ public class RemoteDevicesTest { mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that updating battery service doesn't send broadcast - mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /*fromBas=*/ true); + mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel, /* fromBas= */ true); verifyNoMoreInteractions(mAdapterService); // Verify that the battery level isn't reset - mRemoteDevices.resetBatteryLevel(mDevice1, /*fromBas=*/ true); + mRemoteDevices.resetBatteryLevel(mDevice1, /* fromBas= */ true); Assert.assertEquals( batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); verifyNoMoreInteractions(mAdapterService); @@ -686,10 +750,13 @@ public class RemoteDevicesTest { // Verify that ACTION_AG_EVENT intent updates battery level mRemoteDevices.onAgBatteryLevelChanged(mDevice1, batteryLevel); - verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), - any(Bundle.class)); - verifyBatteryLevelChangedIntent(mDevice1, - RemoteDevices.batteryChargeIndicatorToPercentge(batteryLevel), mIntentArgument); + verify(mAdapterService) + .sendBroadcast( + mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); + verifyBatteryLevelChangedIntent( + mDevice1, + RemoteDevices.batteryChargeIndicatorToPercentge(batteryLevel), + mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); } @@ -701,16 +768,19 @@ public class RemoteDevicesTest { mRemoteDevices.addDeviceProperties(Utils.getBytesFromAddress(TEST_BT_ADDR_1)); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(mDevice1); - BluetoothSinkAudioPolicy policies = new BluetoothSinkAudioPolicy.Builder() - .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .setActiveDevicePolicyAfterConnection(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .build(); + BluetoothSinkAudioPolicy policies = + new BluetoothSinkAudioPolicy.Builder() + .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .setActiveDevicePolicyAfterConnection( + BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .build(); deviceProp.setHfAudioPolicyForRemoteAg(policies); // Verify that the audio policy properties are set and get propperly - Assert.assertEquals(policies, mRemoteDevices.getDeviceProperties(mDevice1) - .getHfAudioPolicyForRemoteAg()); + Assert.assertEquals( + policies, + mRemoteDevices.getDeviceProperties(mDevice1).getHfAudioPolicyForRemoteAg()); } @Test @@ -750,20 +820,21 @@ public class RemoteDevicesTest { Assert.assertNull(mRemoteDevices.getDeviceProperties(null)); } - - private static void verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, - ArgumentCaptor intentArgument) { + private static void verifyBatteryLevelChangedIntent( + BluetoothDevice device, int batteryLevel, ArgumentCaptor intentArgument) { verifyBatteryLevelChangedIntent(device, batteryLevel, intentArgument.getValue()); } - private static void verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, - Intent intent) { + private static void verifyBatteryLevelChangedIntent( + BluetoothDevice device, int batteryLevel, Intent intent) { Assert.assertEquals(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED, intent.getAction()); Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(batteryLevel, - intent.getIntExtra(BluetoothDevice.EXTRA_BATTERY_LEVEL, -15)); - Assert.assertEquals(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, intent.getFlags()); + Assert.assertEquals( + batteryLevel, intent.getIntExtra(BluetoothDevice.EXTRA_BATTERY_LEVEL, -15)); + Assert.assertEquals( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, + intent.getFlags()); } private static Object[] getXEventArray(int batteryLevel, int numLevels) { @@ -778,8 +849,7 @@ public class RemoteDevicesTest { private static BatteryService setBatteryServiceForTesting(BluetoothDevice device) { BatteryService newService = mock(BatteryService.class); - when(newService.getConnectionState(device)) - .thenReturn(BluetoothProfile.STATE_CONNECTED); + when(newService.getConnectionState(device)).thenReturn(BluetoothProfile.STATE_CONNECTED); when(newService.isAvailable()).thenReturn(true); BatteryService oldService = BatteryService.getBatteryService(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java index 36be66af702..398b29d5ef6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java @@ -68,7 +68,6 @@ public class SilenceDeviceManagerTest { @Mock private A2dpService mA2dpService; @Mock private HeadsetService mHeadsetService; - @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getTargetContext(); @@ -83,8 +82,7 @@ public class SilenceDeviceManagerTest { mHandlerThread = new HandlerThread("SilenceManagerTestHandlerThread"); mHandlerThread.start(); mLooper = mHandlerThread.getLooper(); - mSilenceDeviceManager = new SilenceDeviceManager(mAdapterService, mServiceFactory, - mLooper); + mSilenceDeviceManager = new SilenceDeviceManager(mAdapterService, mServiceFactory, mLooper); mSilenceDeviceManager.start(); } @@ -119,9 +117,10 @@ public class SilenceDeviceManagerTest { if (wasSilenced) { Assert.assertTrue(mSilenceDeviceManager.setSilenceMode(mTestDevice, true)); TestUtils.waitForLooperToFinishScheduledTask(mLooper); - verify(mAdapterService, times(++mVerifyCount)).sendBroadcastAsUser( - intentArgument.capture(), eq(UserHandle.ALL), - eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mAdapterService, times(++mVerifyCount)) + .sendBroadcastAsUser( + intentArgument.capture(), eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), any(Bundle.class)); } // Set silence state and check whether state changed successfully @@ -131,9 +130,10 @@ public class SilenceDeviceManagerTest { // Check for silence state changed intent if (wasSilenced != enableSilence) { - verify(mAdapterService, times(++mVerifyCount)).sendBroadcastAsUser( - intentArgument.capture(), eq(UserHandle.ALL), - eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mAdapterService, times(++mVerifyCount)) + .sendBroadcastAsUser( + intentArgument.capture(), eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), any(Bundle.class)); verifySilenceStateIntent(intentArgument.getValue()); } @@ -145,9 +145,10 @@ public class SilenceDeviceManagerTest { if (enableSilence) { // If the silence mode is enabled, it should be automatically disabled // after device is disconnected. - verify(mAdapterService, times(++mVerifyCount)).sendBroadcastAsUser( - intentArgument.capture(), eq(UserHandle.ALL), - eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mAdapterService, times(++mVerifyCount)) + .sendBroadcastAsUser( + intentArgument.capture(), eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), any(Bundle.class)); } } @@ -159,9 +160,10 @@ public class SilenceDeviceManagerTest { Assert.assertFalse(mSilenceDeviceManager.getSilenceMode(mTestDevice)); // Should be no intent been broadcasted - verify(mAdapterService, times(mVerifyCount)).sendBroadcastAsUser( - intentArgument.capture(), eq(UserHandle.ALL), - eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mAdapterService, times(mVerifyCount)) + .sendBroadcastAsUser( + intentArgument.capture(), eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), any(Bundle.class)); } void verifySilenceStateIntent(Intent intent) { @@ -169,36 +171,28 @@ public class SilenceDeviceManagerTest { Assert.assertEquals(mTestDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); } - /** - * Helper to indicate A2dp connected for a device. - */ + /** Helper to indicate A2dp connected for a device. */ private void a2dpConnected(BluetoothDevice device) { mSilenceDeviceManager.a2dpConnectionStateChanged( device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); TestUtils.waitForLooperToFinishScheduledTask(mLooper); } - /** - * Helper to indicate A2dp disconnected for a device. - */ + /** Helper to indicate A2dp disconnected for a device. */ private void a2dpDisconnected(BluetoothDevice device) { mSilenceDeviceManager.a2dpConnectionStateChanged( device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); TestUtils.waitForLooperToFinishScheduledTask(mLooper); } - /** - * Helper to indicate Headset connected for a device. - */ + /** Helper to indicate Headset connected for a device. */ private void headsetConnected(BluetoothDevice device) { mSilenceDeviceManager.hfpConnectionStateChanged( device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); TestUtils.waitForLooperToFinishScheduledTask(mLooper); } - /** - * Helper to indicate Headset disconnected for a device. - */ + /** Helper to indicate Headset disconnected for a device. */ private void headsetDisconnected(BluetoothDevice device) { mSilenceDeviceManager.hfpConnectionStateChanged( device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java index ae60fb4d7e5..09c7d4340f1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java @@ -63,63 +63,71 @@ public final class BluetoothKeystoreServiceTest { "/data/misc/bluedroid/bt_config.checksum.encrypted"; // bt_config file test content. - private final List mConfigTestData = List.of("[Info]", - "FileSource = Empty", - "TimeCreated = XXXX-XX-XX XX:XX:XX", - "", - "[Metrics]", - "Salt256Bit = aaaaaaaaaaaaaaaaaaa", - "", - "[Adapter]", - "Address = 11:22:33:44:55:66", - "LE_LOCAL_KEY_IRK = IRK1234567890", - "LE_LOCAL_KEY_IR = IR1234567890", - "LE_LOCAL_KEY_DHK = DHK1234567890", - "LE_LOCAL_KEY_ER = ER1234567890", - "ScanMode = 0", - "DiscoveryTimeout = 120", - "", - "[aa:bb:cc:dd:ee:ff]", - "Timestamp = 12345678", - "Name = Test", - "DevClass = 1234567", - "LinkKey = 11223344556677889900aabbccddeeff", - "LE_KEY_PENC = ec111111111111111111111111111111111111111111111111111111", - "LE_KEY_PID = d222222222222222222222222222222222222222222222", - "LE_KEY_PCSRK = c33333333333333333333333333333333333333333333333", - "LE_KEY_LENC = eec4444444444444444444444444444444444444", - "LE_KEY_LCSRK = aec555555555555555555555555555555555555555555555", - "LE_KEY_LID =" - ); - - private final List mConfigTestDataForOldEncryptedFile = List.of("[Info]", - "FileSource = Empty", - "TimeCreated = XXXX-XX-XX XX:XX:XX", - "", - "[Metrics]", - "Salt256Bit = aaaaaaaaaaaaaaaaaaa", - "", - "[Adapter]", - "Address = 11:22:33:44:55:66", - "LE_LOCAL_KEY_IRK = IRK1234567890", - "LE_LOCAL_KEY_IR = IR1234567890", - "LE_LOCAL_KEY_DHK = DHK1234567890", - "LE_LOCAL_KEY_ER = ER1234567890", - "ScanMode = 0", - "DiscoveryTimeout = 120", - "", - "[aa:bb:cc:dd:ee:ff]", - "Timestamp = 12345678", - "Name = Test", - "DevClass = 1234567", - "LinkKey = CgzgWAk2ROa2cjknZhsaMIPzf20MvCRx2QeAHycQ7gFy9LnVi9FYs/PodOfl+FP5YkXP/WHkY4", - "LE_KEY_PENC = CgwomFvDc/IuhOeoTn8aSPHqDneIZJ7aszhKQPorqeDPF50cytW4I/LzmdNvMeVX0qBsuh", - "LE_KEY_PID = Cgxu7Z7sXniNj3ija1waPkvHCLH4gnttOyb0OZjiJj+xH3KvtfDh6k2wbgGcGTLe9pYS4EX", - "LE_KEY_PCSRK = Cgx5t1PkIm8ohz9BLzYaQOsrmZakN77CMgbWeBIqT8bW6bQhK1JZYpp3qWZVM8HM3y09h", - "LE_KEY_LENC = CgytzELdVX+QptdzuuMaOLDiNuzn7BNK9OmPNHYspp4ojThTA/5iWBxrZV6E3qZydLyNHk", - "LE_KEY_LCSRK = CgydDaLIr/pSx1/eoPEaQEZN2BDpSJPjOSiJWwDBkMkgIpf/YmfxB6rUB8EXHkC+9eSy4", - "LE_KEY_LID =" - ); + private final List mConfigTestData = + List.of( + "[Info]", + "FileSource = Empty", + "TimeCreated = XXXX-XX-XX XX:XX:XX", + "", + "[Metrics]", + "Salt256Bit = aaaaaaaaaaaaaaaaaaa", + "", + "[Adapter]", + "Address = 11:22:33:44:55:66", + "LE_LOCAL_KEY_IRK = IRK1234567890", + "LE_LOCAL_KEY_IR = IR1234567890", + "LE_LOCAL_KEY_DHK = DHK1234567890", + "LE_LOCAL_KEY_ER = ER1234567890", + "ScanMode = 0", + "DiscoveryTimeout = 120", + "", + "[aa:bb:cc:dd:ee:ff]", + "Timestamp = 12345678", + "Name = Test", + "DevClass = 1234567", + "LinkKey = 11223344556677889900aabbccddeeff", + "LE_KEY_PENC = ec111111111111111111111111111111111111111111111111111111", + "LE_KEY_PID = d222222222222222222222222222222222222222222222", + "LE_KEY_PCSRK = c33333333333333333333333333333333333333333333333", + "LE_KEY_LENC = eec4444444444444444444444444444444444444", + "LE_KEY_LCSRK = aec555555555555555555555555555555555555555555555", + "LE_KEY_LID ="); + + private final List mConfigTestDataForOldEncryptedFile = + List.of( + "[Info]", + "FileSource = Empty", + "TimeCreated = XXXX-XX-XX XX:XX:XX", + "", + "[Metrics]", + "Salt256Bit = aaaaaaaaaaaaaaaaaaa", + "", + "[Adapter]", + "Address = 11:22:33:44:55:66", + "LE_LOCAL_KEY_IRK = IRK1234567890", + "LE_LOCAL_KEY_IR = IR1234567890", + "LE_LOCAL_KEY_DHK = DHK1234567890", + "LE_LOCAL_KEY_ER = ER1234567890", + "ScanMode = 0", + "DiscoveryTimeout = 120", + "", + "[aa:bb:cc:dd:ee:ff]", + "Timestamp = 12345678", + "Name = Test", + "DevClass = 1234567", + "LinkKey =" + + " CgzgWAk2ROa2cjknZhsaMIPzf20MvCRx2QeAHycQ7gFy9LnVi9FYs/PodOfl+FP5YkXP/WHkY4", + "LE_KEY_PENC =" + + " CgwomFvDc/IuhOeoTn8aSPHqDneIZJ7aszhKQPorqeDPF50cytW4I/LzmdNvMeVX0qBsuh", + "LE_KEY_PID =" + + " Cgxu7Z7sXniNj3ija1waPkvHCLH4gnttOyb0OZjiJj+xH3KvtfDh6k2wbgGcGTLe9pYS4EX", + "LE_KEY_PCSRK =" + + " Cgx5t1PkIm8ohz9BLzYaQOsrmZakN77CMgbWeBIqT8bW6bQhK1JZYpp3qWZVM8HM3y09h", + "LE_KEY_LENC =" + + " CgytzELdVX+QptdzuuMaOLDiNuzn7BNK9OmPNHYspp4ojThTA/5iWBxrZV6E3qZydLyNHk", + "LE_KEY_LCSRK =" + + " CgydDaLIr/pSx1/eoPEaQEZN2BDpSJPjOSiJWwDBkMkgIpf/YmfxB6rUB8EXHkC+9eSy4", + "LE_KEY_LID ="); private List mConfigData = new ArrayList<>(); @@ -170,17 +178,19 @@ public final class BluetoothKeystoreServiceTest { } private void createNameDecryptKeyResult() { - mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LinkKey", - "11223344556677889900aabbccddeeff"); - mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LE_KEY_PENC", + mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LinkKey", "11223344556677889900aabbccddeeff"); + mNameDecryptKeyResult.put( + "aa:bb:cc:dd:ee:ff-LE_KEY_PENC", "ec111111111111111111111111111111111111111111111111111111"); - mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LE_KEY_PID", - "d222222222222222222222222222222222222222222222"); - mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LE_KEY_PCSRK", + mNameDecryptKeyResult.put( + "aa:bb:cc:dd:ee:ff-LE_KEY_PID", "d222222222222222222222222222222222222222222222"); + mNameDecryptKeyResult.put( + "aa:bb:cc:dd:ee:ff-LE_KEY_PCSRK", "c33333333333333333333333333333333333333333333333"); - mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LE_KEY_LENC", - "eec4444444444444444444444444444444444444"); - mNameDecryptKeyResult.put("aa:bb:cc:dd:ee:ff-LE_KEY_LCSRK", + mNameDecryptKeyResult.put( + "aa:bb:cc:dd:ee:ff-LE_KEY_LENC", "eec4444444444444444444444444444444444444"); + mNameDecryptKeyResult.put( + "aa:bb:cc:dd:ee:ff-LE_KEY_LCSRK", "aec555555555555555555555555555555555555555555555"); } @@ -234,8 +244,8 @@ public final class BluetoothKeystoreServiceTest { // load config file. Assert.assertTrue(parseConfigFile(CONFIG_FILE_PATH)); // make sure it is same with createNameDecryptKeyResult - Assert.assertTrue(doCompareMap(mNameDecryptKeyResult, - mBluetoothKeystoreService.getNameDecryptKey())); + Assert.assertTrue( + doCompareMap(mNameDecryptKeyResult, mBluetoothKeystoreService.getNameDecryptKey())); } @Test @@ -245,8 +255,9 @@ public final class BluetoothKeystoreServiceTest { // Wait for encryption to complete mBluetoothKeystoreService.stopThread(); - Assert.assertTrue(doCompareKeySet(mNameDecryptKeyResult, - mBluetoothKeystoreService.getNameEncryptKey())); + Assert.assertTrue( + doCompareKeySet( + mNameDecryptKeyResult, mBluetoothKeystoreService.getNameEncryptKey())); } @Test @@ -261,8 +272,8 @@ public final class BluetoothKeystoreServiceTest { // Wait for encryption to complete mBluetoothKeystoreService.stopThread(); - Assert.assertTrue(doCompareMap(mNameDecryptKeyResult, - mBluetoothKeystoreService.getNameDecryptKey())); + Assert.assertTrue( + doCompareMap(mNameDecryptKeyResult, mBluetoothKeystoreService.getNameDecryptKey())); } @Test @@ -302,8 +313,8 @@ public final class BluetoothKeystoreServiceTest { mBluetoothKeystoreService.getNameDecryptKey().remove(CONFIG_FILE_PREFIX); mBluetoothKeystoreService.getNameDecryptKey().remove(CONFIG_BACKUP_PREFIX); - Assert.assertTrue(doCompareMap(mNameDecryptKeyResult, - mBluetoothKeystoreService.getNameDecryptKey())); + Assert.assertTrue( + doCompareMap(mNameDecryptKeyResult, mBluetoothKeystoreService.getNameDecryptKey())); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java index 94c1993b404..0973b2bd705 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java @@ -100,10 +100,12 @@ public final class DatabaseManagerTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule - public MigrationTestHelper testHelper = new MigrationTestHelper( - InstrumentationRegistry.getInstrumentation(), - MetadataDatabase.class.getCanonicalName(), - new FrameworkSQLiteOpenHelperFactory()); + public MigrationTestHelper testHelper = + new MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + MetadataDatabase.class.getCanonicalName(), + new FrameworkSQLiteOpenHelperFactory()); + @Before public void setUp() throws Exception { TestUtils.setAdapterService(mAdapterService); @@ -113,18 +115,19 @@ public final class DatabaseManagerTest { mTestDevice3 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR3); // Create a memory database for DatabaseManager instead of use a real database. - mDatabase = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getTargetContext(), - MetadataDatabase.class).build(); + mDatabase = + Room.inMemoryDatabaseBuilder( + InstrumentationRegistry.getTargetContext(), MetadataDatabase.class) + .build(); - when(mAdapterService.getPackageManager()).thenReturn( - InstrumentationRegistry.getTargetContext().getPackageManager()); + when(mAdapterService.getPackageManager()) + .thenReturn(InstrumentationRegistry.getTargetContext().getPackageManager()); mDatabaseManager = new DatabaseManager(mAdapterService); BluetoothDevice[] bondedDevices = {mTestDevice}; doReturn(bondedDevices).when(mAdapterService).getBondedDevices(); - doNothing().when(mAdapterService).metadataChanged( - anyString(), anyInt(), any(byte[].class)); + doNothing().when(mAdapterService).metadataChanged(anyString(), anyInt(), any(byte[].class)); restartDatabaseManagerHelper(); } @@ -143,15 +146,18 @@ public final class DatabaseManagerTest { restartDatabaseManagerHelper(); for (int id = 0; id < BluetoothProfile.MAX_PROFILE_ID; id++) { - Assert.assertEquals(BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + Assert.assertEquals( + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mDatabaseManager.getProfileConnectionPolicy(mTestDevice, id)); } - Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + Assert.assertEquals( + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); - Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); + Assert.assertEquals( + BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, + mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); for (int id = 0; id < MAX_META_ID; id++) { Assert.assertNull(mDatabaseManager.getCustomMeta(mTestDevice, id)); @@ -168,24 +174,42 @@ public final class DatabaseManagerTest { int badConnectionPolicy = -100; // Cases of device not in database - testSetGetProfileConnectionPolicyCase(false, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testSetGetProfileConnectionPolicyCase(false, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, true); - testSetGetProfileConnectionPolicyCase(false, BluetoothProfile.CONNECTION_POLICY_ALLOWED, - BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testSetGetProfileConnectionPolicyCase(false, badConnectionPolicy, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testSetGetProfileConnectionPolicyCase( + false, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testSetGetProfileConnectionPolicyCase( + false, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + true); + testSetGetProfileConnectionPolicyCase( + false, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testSetGetProfileConnectionPolicyCase( + false, badConnectionPolicy, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); // Cases of device already in database - testSetGetProfileConnectionPolicyCase(true, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testSetGetProfileConnectionPolicyCase(true, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, true); - testSetGetProfileConnectionPolicyCase(true, BluetoothProfile.CONNECTION_POLICY_ALLOWED, - BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testSetGetProfileConnectionPolicyCase(true, badConnectionPolicy, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testSetGetProfileConnectionPolicyCase( + true, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testSetGetProfileConnectionPolicyCase( + true, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + true); + testSetGetProfileConnectionPolicyCase( + true, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testSetGetProfileConnectionPolicyCase( + true, badConnectionPolicy, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); } @Test @@ -193,30 +217,48 @@ public final class DatabaseManagerTest { int badValue = -100; // Cases of device not in database - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + false, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + false, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + false, BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, - badValue, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + false, + badValue, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); // Cases of device already in database - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + true, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + true, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + true, BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); - testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, - badValue, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); + testSetGetA2dpOptionalCodecsCase( + A2DP_SUPPORT_OP_CODEC_TEST, + true, + badValue, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); } @Test @@ -224,30 +266,48 @@ public final class DatabaseManagerTest { int badValue = -100; // Cases of device not in database - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, - badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + false, + badValue, + BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); // Cases of device already in database - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, - badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); + testSetGetA2dpOptionalCodecsCase( + A2DP_ENALBED_OP_CODEC_TEST, + true, + badValue, + BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); } @Test @@ -310,10 +370,10 @@ public final class DatabaseManagerTest { mDatabase.insert(otherData2); // Add OTHER_BT_ADDR1 OTHER_BT_ADDR2 to bonded devices - BluetoothDevice otherDevice1 = BluetoothAdapter.getDefaultAdapter() - .getRemoteDevice(OTHER_BT_ADDR1); - BluetoothDevice otherDevice2 = BluetoothAdapter.getDefaultAdapter() - .getRemoteDevice(OTHER_BT_ADDR2); + BluetoothDevice otherDevice1 = + BluetoothAdapter.getDefaultAdapter().getRemoteDevice(OTHER_BT_ADDR1); + BluetoothDevice otherDevice2 = + BluetoothAdapter.getDefaultAdapter().getRemoteDevice(OTHER_BT_ADDR2); BluetoothDevice[] bondedDevices = {otherDevice1, otherDevice2}; doReturn(bondedDevices).when(mAdapterService).getBondedDevices(); @@ -338,7 +398,6 @@ public final class DatabaseManagerTest { mDatabaseManager.mMetadataCache.clear(); // Wait for clear database TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - } @Test @@ -347,142 +406,110 @@ public final class DatabaseManagerTest { byte[] value = "input value".getBytes(); // Device is not in database - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MANUFACTURER_NAME, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MODEL_NAME, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_SOFTWARE_VERSION, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_HARDWARE_VERSION, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_COMPANION_APP, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_ICON, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_DEVICE_TYPE, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_BATTERY, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_CHARGING, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(false, - BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(false, + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MANUFACTURER_NAME, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MODEL_NAME, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_SOFTWARE_VERSION, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_HARDWARE_VERSION, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_COMPANION_APP, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_ICON, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_DEVICE_TYPE, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_BATTERY, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_CHARGING, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(false, - BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_SPATIAL_AUDIO, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_LE_AUDIO, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_GMCS_CCCD, - value, true); - testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_GTBS_CCCD, - value, true); + value, + true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_SPATIAL_AUDIO, value, true); + testSetGetCustomMetaCase( + false, BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_LE_AUDIO, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_GMCS_CCCD, value, true); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_GTBS_CCCD, value, true); testSetGetCustomMetaCase(false, badKey, value, false); testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_EXCLUSIVE_MANAGER, value, true); // Device is in database - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MANUFACTURER_NAME, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MODEL_NAME, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_SOFTWARE_VERSION, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_HARDWARE_VERSION, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_COMPANION_APP, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_ICON, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_DEVICE_TYPE, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_BATTERY, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_CHARGING, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(true, - BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(true, - BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(true, - BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_SPATIAL_AUDIO, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_LE_AUDIO, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_GMCS_CCCD, - value, true); - testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_GTBS_CCCD, - value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MANUFACTURER_NAME, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MODEL_NAME, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_SOFTWARE_VERSION, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_HARDWARE_VERSION, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_COMPANION_APP, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_ICON, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_DEVICE_TYPE, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_BATTERY, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_CHARGING, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_SPATIAL_AUDIO, value, true); + testSetGetCustomMetaCase( + true, BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_LE_AUDIO, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_GMCS_CCCD, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_GTBS_CCCD, value, true); testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_EXCLUSIVE_MANAGER, value, true); } + @Test public void testSetGetAudioPolicyMetaData() { int badKey = 100; - BluetoothSinkAudioPolicy value = new BluetoothSinkAudioPolicy.Builder() - .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .setActiveDevicePolicyAfterConnection(BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) - .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .build(); + BluetoothSinkAudioPolicy value = + new BluetoothSinkAudioPolicy.Builder() + .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .setActiveDevicePolicyAfterConnection( + BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) + .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .build(); // Device is not in database testSetGetAudioPolicyMetadataCase(false, value, true); @@ -556,8 +583,9 @@ public final class DatabaseManagerTest { mDatabaseManager.setConnection(mTestDevice, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertTrue(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); + Assert.assertTrue( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); List mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); @@ -568,13 +596,14 @@ public final class DatabaseManagerTest { mDatabaseManager.setConnection(mTestDevice2, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertTrue(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertTrue( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); Assert.assertEquals(mTestDevice2, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -583,13 +612,14 @@ public final class DatabaseManagerTest { mDatabaseManager.setConnection(mTestDevice, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertTrue(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); + Assert.assertTrue( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -598,13 +628,14 @@ public final class DatabaseManagerTest { mDatabaseManager.setDisconnection(mTestDevice, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -613,15 +644,17 @@ public final class DatabaseManagerTest { mDatabaseManager.setConnection(mTestDevice3, BluetoothProfile.HEADSET); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice3.getAddress()) + .is_active_a2dp_device); Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -631,15 +664,17 @@ public final class DatabaseManagerTest { mDatabaseManager.setConnection(mTestDevice, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertTrue(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); + Assert.assertTrue( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice3.getAddress()) + .is_active_a2dp_device); Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -649,15 +684,17 @@ public final class DatabaseManagerTest { mDatabaseManager.setConnection(mTestDevice3, BluetoothProfile.HEADSET); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertTrue(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); + Assert.assertTrue( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice3.getAddress()) + .is_active_a2dp_device); Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -667,15 +704,17 @@ public final class DatabaseManagerTest { mDatabaseManager.setDisconnection(mTestDevice2, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertTrue(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); + Assert.assertTrue( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice3.getAddress()) + .is_active_a2dp_device); Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -685,15 +724,17 @@ public final class DatabaseManagerTest { mDatabaseManager.setDisconnection(mTestDevice, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice3.getAddress()) + .is_active_a2dp_device); Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -703,15 +744,17 @@ public final class DatabaseManagerTest { mDatabaseManager.setDisconnection(mTestDevice3, BluetoothProfile.A2DP); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); - Assert.assertFalse(mDatabaseManager - .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice2.getAddress()) + .is_active_a2dp_device); + Assert.assertFalse( + mDatabaseManager.mMetadataCache.get(mTestDevice3.getAddress()) + .is_active_a2dp_device); Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); - mostRecentlyConnectedDevicesOrdered = - mDatabaseManager.getMostRecentlyConnectedDevices(); + mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices(); Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); @@ -730,22 +773,26 @@ public final class DatabaseManagerTest { preferences.putInt(BluetoothAdapter.AUDIO_MODE_DUPLEX, BluetoothProfile.LE_AUDIO); // TEST 1: If input is invalid, throws the right Exception - Assert.assertThrows(NullPointerException.class, + Assert.assertThrows( + NullPointerException.class, () -> mDatabaseManager.setPreferredAudioProfiles(null, preferences)); - Assert.assertThrows(NullPointerException.class, + Assert.assertThrows( + NullPointerException.class, () -> mDatabaseManager.setPreferredAudioProfiles(new ArrayList<>(), null)); - Assert.assertThrows(IllegalArgumentException.class, + Assert.assertThrows( + IllegalArgumentException.class, () -> mDatabaseManager.setPreferredAudioProfiles(new ArrayList<>(), preferences)); - Assert.assertThrows(IllegalArgumentException.class, + Assert.assertThrows( + IllegalArgumentException.class, () -> mDatabaseManager.getPreferredAudioProfiles(null)); // TEST 2: If not stored, setter fails and getter returns an empty Bundle - testSetGetPreferredAudioProfilesCase(false, preferences, Bundle.EMPTY, - BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED); + testSetGetPreferredAudioProfilesCase( + false, preferences, Bundle.EMPTY, BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED); // TEST 3: If stored, setter succeeds and getter returns the stored preference - testSetGetPreferredAudioProfilesCase(true, preferences, preferences, - BluetoothStatusCodes.SUCCESS); + testSetGetPreferredAudioProfilesCase( + true, preferences, preferences, BluetoothStatusCodes.SUCCESS); } @Test @@ -759,8 +806,9 @@ public final class DatabaseManagerTest { // Migrate database from 100 to 101 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 101, true, - MetadataDatabase.MIGRATION_100_101); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 101, true, MetadataDatabase.MIGRATION_100_101); cursor = db.query("SELECT * FROM metadata"); // Check whether pbap_client_priority exists in version 101 @@ -809,7 +857,8 @@ public final class DatabaseManagerTest { device.put("unthethered_left_charging", testString); device.put("unthethered_right_charging", testString); device.put("unthethered_case_charging", testString); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Check the metadata names on version 101 @@ -826,8 +875,9 @@ public final class DatabaseManagerTest { // Migrate database from 101 to 102 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 102, true, - MetadataDatabase.MIGRATION_101_102); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 102, true, MetadataDatabase.MIGRATION_101_102); cursor = db.query("SELECT * FROM metadata"); // metadata names should be changed on version 102 @@ -934,7 +984,8 @@ public final class DatabaseManagerTest { device.put("untethered_left_charging", testString); device.put("untethered_right_charging", testString); device.put("untethered_case_charging", testString); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Check the metadata names on version 102 @@ -953,8 +1004,9 @@ public final class DatabaseManagerTest { // Migrate database from 102 to 103 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 103, true, - MetadataDatabase.MIGRATION_102_103); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 103, true, MetadataDatabase.MIGRATION_102_103); cursor = db.query("SELECT * FROM metadata"); // metadata names should be changed on version 103 @@ -1078,13 +1130,15 @@ public final class DatabaseManagerTest { device.put("untethered_left_charging", testString); device.put("untethered_right_charging", testString); device.put("untethered_case_charging", testString); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 103 to 104 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 104, true, - MetadataDatabase.MIGRATION_103_104); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 104, true, MetadataDatabase.MIGRATION_103_104); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "last_active_time", true); @@ -1108,8 +1162,9 @@ public final class DatabaseManagerTest { // Migrate database from 104 to 105 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 105, true, - MetadataDatabase.MIGRATION_104_105); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 105, true, MetadataDatabase.MIGRATION_104_105); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "device_type", true); @@ -1146,13 +1201,15 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 105 to 106 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 106, true, - MetadataDatabase.MIGRATION_105_106); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 106, true, MetadataDatabase.MIGRATION_105_106); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "le_audio_connection_policy", true); @@ -1174,13 +1231,15 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 106 to 107 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 107, true, - MetadataDatabase.MIGRATION_106_107); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 107, true, MetadataDatabase.MIGRATION_106_107); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "volume_control_connection_policy", true); @@ -1200,12 +1259,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 107 to 108 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 108, true, - MetadataDatabase.MIGRATION_107_108); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 108, true, MetadataDatabase.MIGRATION_107_108); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "csip_set_coordinator_connection_policy", true); while (cursor.moveToNext()) { @@ -1223,12 +1284,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 108 to 109 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 109, true, - MetadataDatabase.MIGRATION_108_109); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 109, true, MetadataDatabase.MIGRATION_108_109); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "le_call_control_connection_policy", true); while (cursor.moveToNext()) { @@ -1246,12 +1309,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 109 to 110 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 110, true, - MetadataDatabase.MIGRATION_109_110); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 110, true, MetadataDatabase.MIGRATION_109_110); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "hap_client_connection_policy", true); while (cursor.moveToNext()) { @@ -1269,12 +1334,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 111 to 112 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 112, true, - MetadataDatabase.MIGRATION_111_112); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 112, true, MetadataDatabase.MIGRATION_111_112); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "battery_connection_policy", true); while (cursor.moveToNext()) { @@ -1291,12 +1358,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 112 to 113 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 113, true, - MetadataDatabase.MIGRATION_112_113); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 113, true, MetadataDatabase.MIGRATION_112_113); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "spatial_audio", true); assertHasColumn(cursor, "fastpair_customized", true); @@ -1315,12 +1384,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 113 to 114 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 114, true, - MetadataDatabase.MIGRATION_113_114); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 114, true, MetadataDatabase.MIGRATION_113_114); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "le_audio", true); while (cursor.moveToNext()) { @@ -1337,13 +1408,15 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 114 to 115 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 115, true, - MetadataDatabase.MIGRATION_114_115); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 115, true, MetadataDatabase.MIGRATION_114_115); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "call_establish_audio_policy", true); @@ -1365,13 +1438,15 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 115 to 116 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 116, true, - MetadataDatabase.MIGRATION_115_116); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 116, true, MetadataDatabase.MIGRATION_115_116); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "preferred_output_only_profile", true); assertHasColumn(cursor, "preferred_duplex_profile", true); @@ -1390,12 +1465,14 @@ public final class DatabaseManagerTest { ContentValues device = new ContentValues(); device.put("address", TEST_BT_ADDR); device.put("migrated", false); - assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), CoreMatchers.not(-1)); // Migrate database from 116 to 117 db.close(); - db = testHelper.runMigrationsAndValidate(DB_NAME, 117, true, - MetadataDatabase.MIGRATION_116_117); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 117, true, MetadataDatabase.MIGRATION_116_117); Cursor cursor = db.query("SELECT * FROM metadata"); assertHasColumn(cursor, "gmcs_cccd", true); assertHasColumn(cursor, "gtbs_cccd", true); @@ -1479,9 +1556,7 @@ public final class DatabaseManagerTest { } } - /** - * Helper function to check whether the database has the expected column - */ + /** Helper function to check whether the database has the expected column */ void assertHasColumn(Cursor cursor, String columnName, boolean hasColumn) { if (hasColumn) { assertThat(cursor.getColumnIndex(columnName), CoreMatchers.not(-1)); @@ -1490,27 +1565,21 @@ public final class DatabaseManagerTest { } } - /** - * Helper function to check whether the database has the expected value - */ + /** Helper function to check whether the database has the expected value */ void assertColumnIntData(Cursor cursor, String columnName, int value) { assertThat(cursor.getInt(cursor.getColumnIndex(columnName)), CoreMatchers.is(value)); } - /** - * Helper function to check whether the column data type is BLOB - */ + /** Helper function to check whether the column data type is BLOB */ void assertColumnBlob(Cursor cursor, String columnName) { - assertThat(cursor.getType(cursor.getColumnIndex(columnName)), + assertThat( + cursor.getType(cursor.getColumnIndex(columnName)), CoreMatchers.is(Cursor.FIELD_TYPE_BLOB)); } - /** - * Helper function to check the BLOB data in a column is expected - */ + /** Helper function to check the BLOB data in a column is expected */ void assertColumnBlobData(Cursor cursor, String columnName, byte[] data) { - assertThat(cursor.getBlob(cursor.getColumnIndex(columnName)), - CoreMatchers.is(data)); + assertThat(cursor.getBlob(cursor.getColumnIndex(columnName)), CoreMatchers.is(data)); } void restartDatabaseManagerHelper() { @@ -1530,17 +1599,22 @@ public final class DatabaseManagerTest { TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); } - void testSetGetProfileConnectionPolicyCase(boolean stored, int connectionPolicy, - int expectedConnectionPolicy, boolean expectedSetResult) { + void testSetGetProfileConnectionPolicyCase( + boolean stored, + int connectionPolicy, + int expectedConnectionPolicy, + boolean expectedSetResult) { if (stored) { Metadata data = new Metadata(TEST_BT_ADDR); mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); mDatabase.insert(data); } - Assert.assertEquals(expectedSetResult, - mDatabaseManager.setProfileConnectionPolicy(mTestDevice, - BluetoothProfile.HEADSET, connectionPolicy)); - Assert.assertEquals(expectedConnectionPolicy, + Assert.assertEquals( + expectedSetResult, + mDatabaseManager.setProfileConnectionPolicy( + mTestDevice, BluetoothProfile.HEADSET, connectionPolicy)); + Assert.assertEquals( + expectedConnectionPolicy, mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.HEADSET)); // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); @@ -1560,7 +1634,8 @@ public final class DatabaseManagerTest { // Check whether the device is in database restartDatabaseManagerHelper(); - Assert.assertEquals(expectedConnectionPolicy, + Assert.assertEquals( + expectedConnectionPolicy, mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.HEADSET)); mDatabaseManager.factoryReset(); @@ -1577,12 +1652,12 @@ public final class DatabaseManagerTest { } if (test == A2DP_SUPPORT_OP_CODEC_TEST) { mDatabaseManager.setA2dpSupportsOptionalCodecs(mTestDevice, value); - Assert.assertEquals(expectedValue, - mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); + Assert.assertEquals( + expectedValue, mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); } else { mDatabaseManager.setA2dpOptionalCodecsEnabled(mTestDevice, value); - Assert.assertEquals(expectedValue, - mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); + Assert.assertEquals( + expectedValue, mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); } // Wait for database update TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); @@ -1600,11 +1675,11 @@ public final class DatabaseManagerTest { // Check whether the device is in database restartDatabaseManagerHelper(); if (test == A2DP_SUPPORT_OP_CODEC_TEST) { - Assert.assertEquals(expectedValue, - mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); + Assert.assertEquals( + expectedValue, mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); } else { - Assert.assertEquals(expectedValue, - mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); + Assert.assertEquals( + expectedValue, mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); } mDatabaseManager.factoryReset(); @@ -1620,18 +1695,17 @@ public final class DatabaseManagerTest { Metadata data = new Metadata(TEST_BT_ADDR); mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); mDatabase.insert(data); - Assert.assertEquals(expectedResult, - mDatabaseManager.setCustomMeta(mTestDevice, key, testValue)); + Assert.assertEquals( + expectedResult, mDatabaseManager.setCustomMeta(mTestDevice, key, testValue)); verify(mAdapterService).metadataChanged(TEST_BT_ADDR, key, testValue); verifyTime++; } - Assert.assertEquals(expectedResult, - mDatabaseManager.setCustomMeta(mTestDevice, key, value)); + Assert.assertEquals( + expectedResult, mDatabaseManager.setCustomMeta(mTestDevice, key, value)); if (expectedResult) { // Check for callback and get value verify(mAdapterService, times(verifyTime)).metadataChanged(TEST_BT_ADDR, key, value); - Assert.assertEquals(value, - mDatabaseManager.getCustomMeta(mTestDevice, key)); + Assert.assertEquals(value, mDatabaseManager.getCustomMeta(mTestDevice, key)); } else { Assert.assertNull(mDatabaseManager.getCustomMeta(mTestDevice, key)); return; @@ -1641,8 +1715,7 @@ public final class DatabaseManagerTest { // Check whether the value is saved in database restartDatabaseManagerHelper(); - Assert.assertArrayEquals(value, - mDatabaseManager.getCustomMeta(mTestDevice, key)); + Assert.assertArrayEquals(value, mDatabaseManager.getCustomMeta(mTestDevice, key)); mDatabaseManager.factoryReset(); mDatabaseManager.mMetadataCache.clear(); @@ -1650,22 +1723,22 @@ public final class DatabaseManagerTest { TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); } - void testSetGetAudioPolicyMetadataCase(boolean stored, - BluetoothSinkAudioPolicy policy, boolean expectedResult) { + void testSetGetAudioPolicyMetadataCase( + boolean stored, BluetoothSinkAudioPolicy policy, boolean expectedResult) { BluetoothSinkAudioPolicy testPolicy = new BluetoothSinkAudioPolicy.Builder().build(); if (stored) { Metadata data = new Metadata(TEST_BT_ADDR); mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); mDatabase.insert(data); - Assert.assertEquals(expectedResult, + Assert.assertEquals( + expectedResult, mDatabaseManager.setAudioPolicyMetadata(mTestDevice, testPolicy)); } - Assert.assertEquals(expectedResult, - mDatabaseManager.setAudioPolicyMetadata(mTestDevice, policy)); + Assert.assertEquals( + expectedResult, mDatabaseManager.setAudioPolicyMetadata(mTestDevice, policy)); if (expectedResult) { // Check for callback and get value - Assert.assertEquals(policy, - mDatabaseManager.getAudioPolicyMetadata(mTestDevice)); + Assert.assertEquals(policy, mDatabaseManager.getAudioPolicyMetadata(mTestDevice)); } else { Assert.assertNull(mDatabaseManager.getAudioPolicyMetadata(mTestDevice)); return; @@ -1675,8 +1748,7 @@ public final class DatabaseManagerTest { // Check whether the value is saved in database restartDatabaseManagerHelper(); - Assert.assertEquals(policy, - mDatabaseManager.getAudioPolicyMetadata(mTestDevice)); + Assert.assertEquals(policy, mDatabaseManager.getAudioPolicyMetadata(mTestDevice)); mDatabaseManager.factoryReset(); mDatabaseManager.mMetadataCache.clear(); @@ -1684,8 +1756,11 @@ public final class DatabaseManagerTest { TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); } - void testSetGetPreferredAudioProfilesCase(boolean stored, Bundle preferencesToSet, - Bundle expectedPreferences, int expectedSetResult) { + void testSetGetPreferredAudioProfilesCase( + boolean stored, + Bundle preferencesToSet, + Bundle expectedPreferences, + int expectedSetResult) { if (stored) { Metadata data = new Metadata(TEST_BT_ADDR); Metadata data2 = new Metadata(TEST_BT_ADDR2); @@ -1698,19 +1773,22 @@ public final class DatabaseManagerTest { groupDevices.add(mTestDevice); groupDevices.add(mTestDevice2); - Assert.assertEquals(expectedSetResult, + Assert.assertEquals( + expectedSetResult, mDatabaseManager.setPreferredAudioProfiles(groupDevices, preferencesToSet)); Bundle testDevicePreferences = mDatabaseManager.getPreferredAudioProfiles(mTestDevice); Bundle testDevice2Preferences = mDatabaseManager.getPreferredAudioProfiles(mTestDevice2); Assert.assertNotNull(testDevicePreferences); Assert.assertNotNull(testDevice2Preferences); - Assert.assertEquals(expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY), + Assert.assertEquals( + expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY), testDevicePreferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY)); - Assert.assertEquals(expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX), + Assert.assertEquals( + expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX), testDevicePreferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX)); - Assert.assertEquals(0, - testDevice2Preferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY)); + Assert.assertEquals( + 0, testDevice2Preferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY)); Assert.assertEquals(0, testDevice2Preferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX)); // Wait for database update @@ -1732,12 +1810,14 @@ public final class DatabaseManagerTest { Assert.assertNotNull(testDevicePreferences); Assert.assertNotNull(testDevice2Preferences); - Assert.assertEquals(expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY), + Assert.assertEquals( + expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY), testDevicePreferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY)); - Assert.assertEquals(expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX), + Assert.assertEquals( + expectedPreferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX), testDevicePreferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX)); - Assert.assertEquals(0, - testDevice2Preferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY)); + Assert.assertEquals( + 0, testDevice2Preferences.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY)); Assert.assertEquals(0, testDevice2Preferences.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX)); mDatabaseManager.factoryReset(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java index 2f2b075ef33..181a735d2d3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java @@ -38,8 +38,7 @@ public class BluetoothCsisBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private CsipSetCoordinatorService mService; + @Mock private CsipSetCoordinatorService mService; private AttributionSource mAttributionSource; private BluetoothDevice mTestDevice; @@ -73,7 +72,7 @@ public class BluetoothCsisBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] { BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource); verify(mService).getDevicesMatchingConnectionStates(states); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java index d212f044b04..34de5db973c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java @@ -78,8 +78,7 @@ public class CsipSetCoordinatorServiceTest { @Mock private AdapterService mAdapterService; @Mock private LeAudioService mLeAudioService; - @Spy - private ServiceFactory mServiceFactory = new ServiceFactory(); + @Spy private ServiceFactory mServiceFactory = new ServiceFactory(); @Mock private DatabaseManager mDatabaseManager; @Mock private CsipSetCoordinatorNativeInterface mCsipSetCoordinatorNativeInterface; @Mock private IBluetoothCsipSetCoordinatorLockCallback mCsipSetCoordinatorLockCallback; @@ -96,7 +95,6 @@ public class CsipSetCoordinatorServiceTest { } Assert.assertNotNull(Looper.myLooper()); - TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); @@ -175,17 +173,13 @@ public class CsipSetCoordinatorServiceTest { Assert.assertNull(mService); } - /** - * Test getting CsipSetCoordinator Service - */ + /** Test getting CsipSetCoordinator Service */ @Test public void testGetService() { Assert.assertEquals(mService, CsipSetCoordinatorService.getCsipSetCoordinatorService()); } - /** - * Test stop CsipSetCoordinator Service - */ + /** Test stop CsipSetCoordinator Service */ @Test public void testStopService() { Assert.assertEquals(mService, CsipSetCoordinatorService.getCsipSetCoordinatorService()); @@ -198,67 +192,95 @@ public class CsipSetCoordinatorServiceTest { @Test public void testGetSetPolicy() { when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + Assert.assertEquals( + "Initial device policy", + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mService.getConnectionPolicy(mTestDevice)); when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - Assert.assertEquals("Setting device policy to POLICY_FORBIDDEN", + Assert.assertEquals( + "Setting device policy to POLICY_FORBIDDEN", BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, mService.getConnectionPolicy(mTestDevice)); when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - Assert.assertEquals("Setting device policy to POLICY_ALLOWED", + Assert.assertEquals( + "Setting device policy to POLICY_ALLOWED", BluetoothProfile.CONNECTION_POLICY_ALLOWED, mService.getConnectionPolicy(mTestDevice)); } - /** - * Test if getProfileConnectionPolicy works after the service is stopped. - */ + /** Test if getProfileConnectionPolicy works after the service is stopped. */ @Test public void testGetPolicyAfterStopped() { mService.stop(); - when(mDatabaseManager - .getProfileConnectionPolicy(mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + when(mDatabaseManager.getProfileConnectionPolicy( + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", + Assert.assertEquals( + "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mService.getConnectionPolicy(mTestDevice)); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testOkToConnect() { int badPolicyValue = 1024; int badBondState = 42; - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_NONE, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_NONE, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_NONE, - BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_NONE, badPolicyValue, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDING, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDING, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDING, - BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDING, badPolicyValue, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDED, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDED, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDED, - BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDED, badPolicyValue, false); testOkToConnectCase( mTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); @@ -269,10 +291,7 @@ public class CsipSetCoordinatorServiceTest { testOkToConnectCase(mTestDevice, badBondState, badPolicyValue, false); } - /** - * Test that call to groupLockSet method calls corresponding native interface - * method - */ + /** Test that call to groupLockSet method calls corresponding native interface method */ @Test public void testGroupLockSetNative() { int group_id = 0x01; @@ -283,8 +302,8 @@ public class CsipSetCoordinatorServiceTest { doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), - anyLong()); + .onDeviceAvailable( + any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()); mCsipSetCoordinatorNativeInterface.onDeviceAvailable( getByteAddress(mTestDevice), group_id, group_size, 1, uuidLsb, uuidMsb); Assert.assertFalse(mService.isGroupLocked(group_id)); @@ -302,8 +321,7 @@ public class CsipSetCoordinatorServiceTest { try { verify(mCsipSetCoordinatorLockCallback, times(1)) - .onGroupLockSet(group_id, BluetoothStatusCodes.SUCCESS, - true); + .onGroupLockSet(group_id, BluetoothStatusCodes.SUCCESS, true); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -317,17 +335,13 @@ public class CsipSetCoordinatorServiceTest { try { verify(mCsipSetCoordinatorLockCallback, times(1)) - .onGroupLockSet(group_id, BluetoothStatusCodes.SUCCESS, - false); + .onGroupLockSet(group_id, BluetoothStatusCodes.SUCCESS, false); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } - /** - * Test that call to groupLockSet method calls corresponding native interface - * method - */ + /** Test that call to groupLockSet method calls corresponding native interface method */ @Test public void testGroupExclusiveLockSet() { int group_id = 0x01; @@ -338,8 +352,8 @@ public class CsipSetCoordinatorServiceTest { doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), - anyLong()); + .onDeviceAvailable( + any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()); mCsipSetCoordinatorNativeInterface.onDeviceAvailable( getByteAddress(mTestDevice), group_id, group_size, 1, uuidLsb, uuidMsb); Assert.assertFalse(mService.isGroupLocked(group_id)); @@ -358,23 +372,20 @@ public class CsipSetCoordinatorServiceTest { try { verify(mCsipSetCoordinatorLockCallback, times(1)) - .onGroupLockSet(group_id, - BluetoothStatusCodes.ERROR_CSIP_GROUP_LOCKED_BY_OTHER, true); + .onGroupLockSet( + group_id, BluetoothStatusCodes.ERROR_CSIP_GROUP_LOCKED_BY_OTHER, true); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Assert.assertNull(lock_uuid); } - /** - * Test that an outgoing connection to device that does not have MICS UUID is - * rejected - */ + /** Test that an outgoing connection to device that does not have MICS UUID is rejected */ @Test public void testOutgoingConnectMissingUuid() { // Update the device policy so okToConnect() returns true when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mCsipSetCoordinatorNativeInterface).connect(any(BluetoothDevice.class)); doReturn(true).when(mCsipSetCoordinatorNativeInterface).connect(any(BluetoothDevice.class)); @@ -388,14 +399,12 @@ public class CsipSetCoordinatorServiceTest { Assert.assertFalse("Connect expected to fail", mService.connect(mTestDevice)); } - /** - * Test that an outgoing connection to device that have MICS UUID is successful - */ + /** Test that an outgoing connection to device that have MICS UUID is successful */ @Test public void testOutgoingConnectExistingUuid() { // Update the device policy so okToConnect() returns true when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mCsipSetCoordinatorNativeInterface).connect(any(BluetoothDevice.class)); doReturn(true) @@ -412,9 +421,7 @@ public class CsipSetCoordinatorServiceTest { TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mTestDevice)); } - /** - * Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected - */ + /** Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected */ @Test public void testOutgoingConnectPolicyForbidden() { doReturn(true).when(mCsipSetCoordinatorNativeInterface).connect(any(BluetoothDevice.class)); @@ -424,22 +431,20 @@ public class CsipSetCoordinatorServiceTest { // Set the device policy to POLICY_FORBIDDEN so connect() should fail when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Send a connect request Assert.assertFalse("Connect expected to fail", mService.connect(mTestDevice)); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() { // Update the device policy so okToConnect() returns true when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mCsipSetCoordinatorNativeInterface).connect(any(BluetoothDevice.class)); doReturn(true) @@ -450,22 +455,25 @@ public class CsipSetCoordinatorServiceTest { Assert.assertTrue("Connect failed", mService.connect(mTestDevice)); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mTestDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals( BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mTestDevice)); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(CsipSetCoordinatorStateMachine.sConnectTimeoutMs * 2, - mTestDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + CsipSetCoordinatorStateMachine.sConnectTimeoutMs * 2, + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); Assert.assertEquals( BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mTestDevice)); } - /** - * Test that native callback generates proper intent. - */ + /** Test that native callback generates proper intent. */ @Test public void testStackEventDeviceAvailable() { int group_id = 0x01; @@ -476,8 +484,8 @@ public class CsipSetCoordinatorServiceTest { doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), - anyLong()); + .onDeviceAvailable( + any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()); mCsipSetCoordinatorNativeInterface.onDeviceAvailable( getByteAddress(mTestDevice), group_id, group_size, 0x02, uuidLsb, uuidMsb); @@ -488,9 +496,11 @@ public class CsipSetCoordinatorServiceTest { Assert.assertEquals(mTestDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); Assert.assertEquals( group_id, intent.getIntExtra(BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_ID, -1)); - Assert.assertEquals(group_size, + Assert.assertEquals( + group_size, intent.getIntExtra(BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_SIZE, -1)); - Assert.assertEquals(uuid, + Assert.assertEquals( + uuid, intent.getSerializableExtra( BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_TYPE_UUID)); @@ -509,9 +519,7 @@ public class CsipSetCoordinatorServiceTest { Assert.assertEquals(2, devices.indexOf(mTestDevice3)); } - /** - * Test that native callback generates proper intent after group connected. - */ + /** Test that native callback generates proper intent after group connected. */ @Test public void testStackEventSetMemberAvailableAfterGroupConnected() { int group_id = 0x01; @@ -522,8 +530,8 @@ public class CsipSetCoordinatorServiceTest { // Make sure to use real methods when needed below doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), - anyLong()); + .onDeviceAvailable( + any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()); doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) .onConnectionStateChanged(any(byte[].class), anyInt()); @@ -538,8 +546,8 @@ public class CsipSetCoordinatorServiceTest { getByteAddress(mTestDevice), BluetoothProfile.STATE_CONNECTED); // Comes from state machine - mService.connectionStateChanged(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_CONNECTED); + mService.connectionStateChanged( + mTestDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED); mCsipSetCoordinatorNativeInterface.onSetMemberAvailable( getByteAddress(mTestDevice2), group_id); @@ -553,9 +561,7 @@ public class CsipSetCoordinatorServiceTest { group_id, intent.getIntExtra(BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_ID, -1)); } - /** - * Test that native callback generates proper intent before group connected. - */ + /** Test that native callback generates proper intent before group connected. */ @Test public void testStackEventSetMemberAvailableBeforeGroupConnected() { int group_id = 0x01; @@ -566,8 +572,8 @@ public class CsipSetCoordinatorServiceTest { // Make sure to use real methods when needed below doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), - anyLong()); + .onDeviceAvailable( + any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()); doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) .onSetMemberAvailable(any(byte[].class), anyInt()); @@ -587,9 +593,9 @@ public class CsipSetCoordinatorServiceTest { Intent intent = TestUtils.waitForNoIntent(TIMEOUT_MS, mIntentQueue.get(mTestDevice2)); Assert.assertNull(intent); - // Comes from state machine - mService.connectionStateChanged(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_CONNECTED); + // Comes from state machine + mService.connectionStateChanged( + mTestDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED); intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mTestDevice2)); Assert.assertNotNull(intent); @@ -614,47 +620,55 @@ public class CsipSetCoordinatorServiceTest { doCallRealMethod() .when(mCsipSetCoordinatorNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), - anyLong()); - when(mLeAudioService.getConnectionPolicy(any())).thenReturn( - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + .onDeviceAvailable( + any(byte[].class), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()); + when(mLeAudioService.getConnectionPolicy(any())) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Make first set device available and connected mCsipSetCoordinatorNativeInterface.onDeviceAvailable( getByteAddress(mTestDevice), group_id, group_size, 0x02, uuidLsb, uuidMsb); - mService.connectionStateChanged(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_CONNECTED); + mService.connectionStateChanged( + mTestDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED); // Another device with the highest rank mCsipSetCoordinatorNativeInterface.onDeviceAvailable( getByteAddress(mTestDevice2), group_id, group_size, 0x01, uuidLsb, uuidMsb); // When LEA is FORBIDDEN, verify we don't disable CSIP until all set devices are available - verify(mDatabaseManager, never()).setProfileConnectionPolicy(mTestDevice, - BluetoothProfile.CSIP_SET_COORDINATOR, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - verify(mDatabaseManager, never()).setProfileConnectionPolicy(mTestDevice2, - BluetoothProfile.CSIP_SET_COORDINATOR, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mDatabaseManager, never()) + .setProfileConnectionPolicy( + mTestDevice, + BluetoothProfile.CSIP_SET_COORDINATOR, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mDatabaseManager, never()) + .setProfileConnectionPolicy( + mTestDevice2, + BluetoothProfile.CSIP_SET_COORDINATOR, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Mark the second device as connected - mService.connectionStateChanged(mTestDevice2, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_CONNECTED); + mService.connectionStateChanged( + mTestDevice2, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED); // When LEA is FORBIDDEN, verify we disable CSIP once all set devices are available - verify(mDatabaseManager, times(1)).setProfileConnectionPolicy(mTestDevice, - BluetoothProfile.CSIP_SET_COORDINATOR, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - verify(mDatabaseManager, times(1)).setProfileConnectionPolicy(mTestDevice2, - BluetoothProfile.CSIP_SET_COORDINATOR, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mDatabaseManager, times(1)) + .setProfileConnectionPolicy( + mTestDevice, + BluetoothProfile.CSIP_SET_COORDINATOR, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mDatabaseManager, times(1)) + .setProfileConnectionPolicy( + mTestDevice2, + BluetoothProfile.CSIP_SET_COORDINATOR, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } @Test public void testDump_doesNotCrash() { // Update the device policy so okToConnect() returns true when(mDatabaseManager.getProfileConnectionPolicy( - mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) + mTestDevice, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mCsipSetCoordinatorNativeInterface).connect(any(BluetoothDevice.class)); doReturn(true) @@ -671,14 +685,13 @@ public class CsipSetCoordinatorServiceTest { mService.dump(new StringBuilder()); } - /** - * Helper function to test ConnectionStateIntent() method - */ + /** Helper function to test ConnectionStateIntent() method */ private void verifyConnectionStateIntent( int timeoutMs, BluetoothDevice device, int newState, int prevState) { Intent intent = TestUtils.waitForIntent(timeoutMs, mIntentQueue.get(device)); Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothCsipSetCoordinator.ACTION_CSIS_CONNECTION_STATE_CHANGED, + Assert.assertEquals( + BluetoothCsipSetCoordinator.ACTION_CSIS_CONNECTION_STATE_CHANGED, intent.getAction()); Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); @@ -686,21 +699,17 @@ public class CsipSetCoordinatorServiceTest { prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); } - /** - * Helper function to test okToConnect() method - */ + /** Helper function to test okToConnect() method */ private void testOkToConnectCase( BluetoothDevice device, int bondState, int policy, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mDatabaseManager.getProfileConnectionPolicy( - device, BluetoothProfile.CSIP_SET_COORDINATOR)) + device, BluetoothProfile.CSIP_SET_COORDINATOR)) .thenReturn(policy); Assert.assertEquals(expected, mService.okToConnect(device)); } - /** - * Helper function to get byte array for a device address - */ + /** Helper function to get byte array for a device address */ private byte[] getByteAddress(BluetoothDevice device) { if (device == null) { return Utils.getBytesFromAddress("00:00:00:00:00:00"); diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java index 8afde812ba5..85871a331af 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java @@ -84,8 +84,13 @@ public class CsipSetCoordinatorStateMachineTest { // Set up thread and looper mHandlerThread = new HandlerThread("CsipSetCoordinatorServiceTestHandlerThread"); mHandlerThread.start(); - mStateMachine = spy(new CsipSetCoordinatorStateMachineWrapper( - mTestDevice, mService, mNativeInterface, mHandlerThread.getLooper())); + mStateMachine = + spy( + new CsipSetCoordinatorStateMachineWrapper( + mTestDevice, + mService, + mNativeInterface, + mHandlerThread.getLooper())); // Override the timeout value to speed up the test CsipSetCoordinatorStateMachine.sConnectTimeoutMs = 1000; @@ -102,13 +107,10 @@ public class CsipSetCoordinatorStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { - Assert.assertEquals( - STATE_DISCONNECTED, mStateMachine.getConnectionState()); + Assert.assertEquals(STATE_DISCONNECTED, mStateMachine.getConnectionState()); } /** @@ -120,17 +122,15 @@ public class CsipSetCoordinatorStateMachineTest { doReturn(allow).when(mService).okToConnect(any(BluetoothDevice.class)); } - /** - * Test that an incoming connection with policy forbidding connection is - * rejected - */ + /** Test that an incoming connection with policy forbidding connection is rejected */ @Test public void testIncomingPolicyReject() { allowConnection(false); // Inject an event for when incoming connection is requested - CsipSetCoordinatorStackEvent connStCh = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent connStCh = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, connStCh); @@ -138,20 +138,20 @@ public class CsipSetCoordinatorStateMachineTest { // Verify that no connection state broadcast is executed verify(mService, after(TIMEOUT_MS).never()).sendBroadcast(any(Intent.class), anyString()); // Check that we are in Disconnected state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Disconnected.class)); } - /** - * Test that an incoming connection with policy allowing connection is accepted - */ + /** Test that an incoming connection with policy allowing connection is accepted */ @Test public void testIncomingPolicyAccept() { allowConnection(true); // Inject an event for when incoming connection is requested - CsipSetCoordinatorStackEvent connStCh = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent connStCh = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = connStCh.CONNECTION_STATE_CONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, connStCh); @@ -160,16 +160,19 @@ public class CsipSetCoordinatorStateMachineTest { ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); verify(mService, timeout(TIMEOUT_MS).times(1)) .sendBroadcast(intentArgument1.capture(), anyString()); - Assert.assertEquals(STATE_CONNECTING, + Assert.assertEquals( + STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Connecting.class)); // Send a message to trigger connection completed - CsipSetCoordinatorStackEvent connCompletedEvent = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent connCompletedEvent = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mTestDevice; connCompletedEvent.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, connCompletedEvent); @@ -181,13 +184,12 @@ public class CsipSetCoordinatorStateMachineTest { verify(mService, timeout(TIMEOUT_MS).times(2)) .sendBroadcast(intentArgument2.capture(), anyString()); // Check that we are in Connected state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Connected.class)); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingTimeout() { allowConnection(true); @@ -201,29 +203,31 @@ public class CsipSetCoordinatorStateMachineTest { ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); verify(mService, timeout(TIMEOUT_MS).times(1)) .sendBroadcast(intentArgument1.capture(), anyString()); - Assert.assertEquals(STATE_CONNECTING, + Assert.assertEquals( + STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); verify(mService, timeout(CsipSetCoordinatorStateMachine.sConnectTimeoutMs * 2).times(2)) .sendBroadcast(intentArgument2.capture(), anyString()); - Assert.assertEquals(STATE_DISCONNECTED, + Assert.assertEquals( + STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Disconnected state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Disconnected.class)); verify(mNativeInterface).disconnect(eq(mTestDevice)); } - /** - * Test that an incoming connection times out - */ + /** Test that an incoming connection times out */ @Test public void testIncomingTimeout() { allowConnection(true); @@ -231,8 +235,9 @@ public class CsipSetCoordinatorStateMachineTest { doReturn(true).when(mNativeInterface).disconnect(any(BluetoothDevice.class)); // Inject an event for when incoming connection is requested - CsipSetCoordinatorStackEvent connStCh = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent connStCh = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, connStCh); @@ -241,22 +246,26 @@ public class CsipSetCoordinatorStateMachineTest { ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); verify(mService, timeout(TIMEOUT_MS).times(1)) .sendBroadcast(intentArgument1.capture(), anyString()); - Assert.assertEquals(STATE_CONNECTING, + Assert.assertEquals( + STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); verify(mService, timeout(CsipSetCoordinatorStateMachine.sConnectTimeoutMs * 2).times(2)) .sendBroadcast(intentArgument2.capture(), anyString()); - Assert.assertEquals(STATE_DISCONNECTED, + Assert.assertEquals( + STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Disconnected state - Assert.assertThat(mStateMachine.getCurrentState(), + Assert.assertThat( + mStateMachine.getCurrentState(), IsInstanceOf.instanceOf(CsipSetCoordinatorStateMachine.Disconnected.class)); verify(mNativeInterface).disconnect(eq(mTestDevice)); } @@ -314,15 +323,17 @@ public class CsipSetCoordinatorStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_DISCONNECTED, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_DISCONNECTED, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -330,23 +341,26 @@ public class CsipSetCoordinatorStateMachineTest { verify(mNativeInterface).disconnect(mTestDevice); Mockito.clearInvocations(mNativeInterface); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_DISCONNECTED, mStateMachine.getConnectionState()); verify(mNativeInterface).disconnect(mTestDevice); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_DISCONNECTED, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = -1; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -356,8 +370,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toConnectingState_onDisconnectedState() { allowConnection(true); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -367,8 +382,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toConnectedState_onDisconnectedState() { allowConnection(true); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -380,8 +396,9 @@ public class CsipSetCoordinatorStateMachineTest { initToConnectingState(); mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.CONNECT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertTrue(mStateMachine.doesSuperHaveDeferredMessages( - CsipSetCoordinatorStateMachine.CONNECT)); + Assert.assertTrue( + mStateMachine.doesSuperHaveDeferredMessages( + CsipSetCoordinatorStateMachine.CONNECT)); } @Test @@ -406,15 +423,17 @@ public class CsipSetCoordinatorStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_CONNECTING, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_CONNECTING, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = 10000; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -424,8 +443,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toDisconnectedState_onConnectingState() { initToConnectingState(); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTED; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -435,8 +455,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toConnectedState_onConnectingState() { initToConnectingState(); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -446,8 +467,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toDisconnectingState_onConnectingState() { initToConnectingState(); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTING; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -488,8 +510,9 @@ public class CsipSetCoordinatorStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_CONNECTED, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -499,8 +522,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toDisconnectedState_onConnectedState() { initToConnectedState(); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTED; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -510,8 +534,9 @@ public class CsipSetCoordinatorStateMachineTest { @Test public void testStackEvent_toDisconnectingState_onConnectedState() { initToConnectedState(); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTING; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -552,30 +577,34 @@ public class CsipSetCoordinatorStateMachineTest { Assert.assertEquals(STATE_DISCONNECTING, mStateMachine.getConnectionState()); allowConnection(false); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mNativeInterface).disconnect(any()); Mockito.clearInvocations(mNativeInterface); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mNativeInterface).disconnect(any()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTING; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertEquals(STATE_DISCONNECTING, mStateMachine.getConnectionState()); - event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = 10000; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -586,8 +615,9 @@ public class CsipSetCoordinatorStateMachineTest { public void testStackEvent_toConnectedState_onDisconnectingState() { initToDisconnectingState(); allowConnection(true); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -598,8 +628,9 @@ public class CsipSetCoordinatorStateMachineTest { public void testStackEvent_toConnectedState_butNotAllowed_onDisconnectingState() { initToDisconnectingState(); allowConnection(false); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -610,8 +641,9 @@ public class CsipSetCoordinatorStateMachineTest { public void testStackEvent_toConnectingState_onDisconnectingState() { initToDisconnectingState(); allowConnection(true); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -622,8 +654,9 @@ public class CsipSetCoordinatorStateMachineTest { public void testStackEvent_toConnectingState_butNotAllowed_onDisconnectingState() { initToDisconnectingState(); allowConnection(false); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; mStateMachine.sendMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -632,8 +665,9 @@ public class CsipSetCoordinatorStateMachineTest { private void initToConnectingState() { allowConnection(true); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -643,8 +677,9 @@ public class CsipSetCoordinatorStateMachineTest { private void initToConnectedState() { allowConnection(true); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -654,8 +689,9 @@ public class CsipSetCoordinatorStateMachineTest { private void initToDisconnectingState() { initToConnectingState(); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTING; sendMessageAndVerifyTransition( mStateMachine.obtainMessage(CsipSetCoordinatorStateMachine.STACK_EVENT, event), @@ -673,9 +709,11 @@ public class CsipSetCoordinatorStateMachineTest { public static class CsipSetCoordinatorStateMachineWrapper extends CsipSetCoordinatorStateMachine { - CsipSetCoordinatorStateMachineWrapper(BluetoothDevice device, + CsipSetCoordinatorStateMachineWrapper( + BluetoothDevice device, CsipSetCoordinatorService svc, - CsipSetCoordinatorNativeInterface nativeInterface, Looper looper) { + CsipSetCoordinatorNativeInterface nativeInterface, + Looper looper) { super(device, svc, nativeInterface, looper); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java index f432c3f2192..5f89c4b4cad 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java @@ -32,9 +32,7 @@ import org.junit.runner.RunWith; import java.util.UUID; -/** - * Test cases for {@link AdvertiseHelper}. - */ +/** Test cases for {@link AdvertiseHelper}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AdvertiseHelperTest { @@ -46,27 +44,23 @@ public class AdvertiseHelperTest { assertThat(emptyBytes.length).isEqualTo(0); int manufacturerId = 1; - byte[] manufacturerData = new byte[]{ - 0x30, 0x31, 0x32, 0x34 - }; - - byte[] serviceData = new byte[]{ - 0x10, 0x12, 0x14 - }; - - byte[] transportDiscoveryData = new byte[]{ - 0x40, 0x44, 0x48 - }; - - AdvertiseData advertiseData = new AdvertiseData.Builder() - .setIncludeDeviceName(true) - .addManufacturerData(manufacturerId, manufacturerData) - .setIncludeTxPowerLevel(true) - .addServiceUuid(new ParcelUuid(UUID.randomUUID())) - .addServiceData(new ParcelUuid(UUID.randomUUID()), serviceData) - .addServiceSolicitationUuid(new ParcelUuid(UUID.randomUUID())) - .addTransportDiscoveryData(new TransportDiscoveryData(transportDiscoveryData)) - .build(); + byte[] manufacturerData = new byte[] {0x30, 0x31, 0x32, 0x34}; + + byte[] serviceData = new byte[] {0x10, 0x12, 0x14}; + + byte[] transportDiscoveryData = new byte[] {0x40, 0x44, 0x48}; + + AdvertiseData advertiseData = + new AdvertiseData.Builder() + .setIncludeDeviceName(true) + .addManufacturerData(manufacturerId, manufacturerData) + .setIncludeTxPowerLevel(true) + .addServiceUuid(new ParcelUuid(UUID.randomUUID())) + .addServiceData(new ParcelUuid(UUID.randomUUID()), serviceData) + .addServiceSolicitationUuid(new ParcelUuid(UUID.randomUUID())) + .addTransportDiscoveryData( + new TransportDiscoveryData(transportDiscoveryData)) + .build(); String deviceName = "TestDeviceName"; int expectedAdvDataBytesLength = 86; @@ -77,17 +71,14 @@ public class AdvertiseHelperTest { assertThat(advDataBytes.length).isEqualTo(expectedAdvDataBytesLength); int expectedAdvDataBytesLongNameLength = 98; - byte[] advDataBytesLongName = AdvertiseHelper - .advertiseDataToBytes(advertiseData, deviceNameLong); + byte[] advDataBytesLongName = + AdvertiseHelper.advertiseDataToBytes(advertiseData, deviceNameLong); assertThat(advDataBytesLongName.length).isEqualTo(expectedAdvDataBytesLongNameLength); } @Test public void checkLength_withGT255_throwsException() { - assertThrows( - IllegalArgumentException.class, - () -> AdvertiseHelper.check_length(0X00, 256) - ); + assertThrows(IllegalArgumentException.class, () -> AdvertiseHelper.check_length(0X00, 256)); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java index 0fdfd3cd8a0..ecafc2c88d2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java @@ -16,7 +16,6 @@ package com.android.bluetooth.gatt; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; @@ -44,31 +43,24 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -/** - * Test cases for {@link AdvertiseManager}. - */ +/** Test cases for {@link AdvertiseManager}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AdvertiseManagerTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AdapterService mAdapterService; + @Mock private AdapterService mAdapterService; - @Mock - private GattService mService; + @Mock private GattService mService; - @Mock - private GattService.AdvertiserMap mAdvertiserMap; + @Mock private GattService.AdvertiserMap mAdvertiserMap; @Mock private AdvertiseManagerNativeInterface mNativeInterface; - @Mock - private IAdvertisingSetCallback mCallback; + @Mock private IAdvertisingSetCallback mCallback; - @Mock - private IBinder mBinder; + @Mock private IBinder mBinder; private AdvertiseManager mAdvertiseManager; private int mAdvertiserId; @@ -92,8 +84,16 @@ public class AdvertiseManagerTest { doReturn(mBinder).when(mCallback).asBinder(); doNothing().when(mBinder).linkToDeath(any(), eq(0)); - mAdvertiseManager.startAdvertisingSet(parameters, advertiseData, scanResponse, - periodicParameters, periodicData, duration, maxExtAdvEvents, 0, mCallback); + mAdvertiseManager.startAdvertisingSet( + parameters, + advertiseData, + scanResponse, + periodicParameters, + periodicData, + duration, + maxExtAdvEvents, + 0, + mCallback); mAdvertiserId = AdvertiseManager.sTempRegistrationId; } @@ -111,8 +111,8 @@ public class AdvertiseManagerTest { mAdvertiseManager.enableAdvertisingSet(mAdvertiserId, enable, duration, maxExtAdvEvents); - verify(mAdvertiserMap).enableAdvertisingSet(mAdvertiserId, enable, duration, - maxExtAdvEvents); + verify(mAdvertiserMap) + .enableAdvertisingSet(mAdvertiserId, enable, duration, maxExtAdvEvents); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java index 6c6ad1cf562..eee79a79043 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java @@ -42,23 +42,18 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -/** - * Test cases for {@link AppAdvertiseStats}. - */ +/** Test cases for {@link AppAdvertiseStats}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AppAdvertiseStatsTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private ContextMap map; + @Mock private ContextMap map; - @Mock - private GattService service; + @Mock private GattService service; - @Mock - private MetricsLogger mMetricsLogger; + @Mock private MetricsLogger mMetricsLogger; @Before public void setUp() throws Exception { @@ -89,8 +84,7 @@ public class AppAdvertiseStatsTest { AppAdvertiseStats appAdvertiseStats = new AppAdvertiseStats(id, name, map, service); - assertThat(appAdvertiseStats.mAdvertiserRecords.size()) - .isEqualTo(0); + assertThat(appAdvertiseStats.mAdvertiserRecords.size()).isEqualTo(0); int duration = 1; int maxExtAdvEvents = 2; @@ -111,13 +105,11 @@ public class AppAdvertiseStatsTest { periodicParameters, periodicData, duration, - maxExtAdvEvents - ); + maxExtAdvEvents); int numOfExpectedRecords = 2; - assertThat(appAdvertiseStats.mAdvertiserRecords.size()) - .isEqualTo(numOfExpectedRecords); + assertThat(appAdvertiseStats.mAdvertiserRecords.size()).isEqualTo(numOfExpectedRecords); } @Test @@ -130,8 +122,7 @@ public class AppAdvertiseStatsTest { int duration = 1; int maxExtAdvEvents = 2; - assertThat(appAdvertiseStats.mAdvertiserRecords.size()) - .isEqualTo(0); + assertThat(appAdvertiseStats.mAdvertiserRecords.size()).isEqualTo(0); appAdvertiseStats.recordAdvertiseStart(duration, maxExtAdvEvents); @@ -149,15 +140,13 @@ public class AppAdvertiseStatsTest { periodicParameters, periodicData, duration, - maxExtAdvEvents - ); + maxExtAdvEvents); appAdvertiseStats.recordAdvertiseStop(); int numOfExpectedRecords = 2; - assertThat(appAdvertiseStats.mAdvertiserRecords.size()) - .isEqualTo(numOfExpectedRecords); + assertThat(appAdvertiseStats.mAdvertiserRecords.size()).isEqualTo(numOfExpectedRecords); } @Test @@ -170,16 +159,14 @@ public class AppAdvertiseStatsTest { int duration = 1; int maxExtAdvEvents = 2; - assertThat(appAdvertiseStats.mAdvertiserRecords.size()) - .isEqualTo(0); + assertThat(appAdvertiseStats.mAdvertiserRecords.size()).isEqualTo(0); appAdvertiseStats.enableAdvertisingSet(true, duration, maxExtAdvEvents); appAdvertiseStats.enableAdvertisingSet(false, duration, maxExtAdvEvents); int numOfExpectedRecords = 1; - assertThat(appAdvertiseStats.mAdvertiserRecords.size()) - .isEqualTo(numOfExpectedRecords); + assertThat(appAdvertiseStats.mAdvertiserRecords.size()).isEqualTo(numOfExpectedRecords); } @Test @@ -269,8 +256,7 @@ public class AppAdvertiseStatsTest { periodicParameters, periodicData, duration, - maxExtAdvEvents - ); + maxExtAdvEvents); AppAdvertiseStats.dumpToString(sb, appAdvertiseStats); } @@ -282,8 +268,8 @@ public class AppAdvertiseStatsTest { AppAdvertiseStats appAdvertiseStats = new AppAdvertiseStats(id, name, map, service); - AdvertisingSetParameters parameters = new AdvertisingSetParameters.Builder() - .setConnectable(true).build(); + AdvertisingSetParameters parameters = + new AdvertisingSetParameters.Builder().setConnectable(true).build(); AdvertiseData advertiseData = new AdvertiseData.Builder().build(); AdvertiseData scanResponse = new AdvertiseData.Builder().build(); PeriodicAdvertisingParameters periodicParameters = @@ -291,34 +277,29 @@ public class AppAdvertiseStatsTest { AdvertiseData periodicData = new AdvertiseData.Builder().build(); appAdvertiseStats.recordAdvertiseStart( - parameters, - advertiseData, - scanResponse, - periodicParameters, - periodicData, - 0, - 0 - ); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_COUNT_ENABLE), eq((long) 1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_ENABLE), eq((long)1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_ENABLE), eq((long) 1)); + parameters, advertiseData, scanResponse, periodicParameters, periodicData, 0, 0); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_COUNT_ENABLE), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_ENABLE), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_ENABLE), eq((long) 1)); Mockito.clearInvocations(mMetricsLogger); appAdvertiseStats.recordAdvertiseStop(); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_COUNT_DISABLE), eq((long) 1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_DISABLE), eq((long)1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_DISABLE), eq((long) 1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_1M), eq((long) 1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_1M), eq((long) 1)); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_1M), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_COUNT_DISABLE), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_DISABLE), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_DISABLE), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_1M), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount( + eq(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_1M), eq((long) 1)); + verify(mMetricsLogger, times(1)) + .cacheCount( + eq(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_1M), eq((long) 1)); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/CallbackInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/CallbackInfoTest.java index dea410cd8a3..b23cbc8b8fb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/CallbackInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/CallbackInfoTest.java @@ -26,9 +26,7 @@ import org.junit.runner.RunWith; import java.util.Arrays; -/** - * Test cases for {@link CallbackInfo}. - */ +/** Test cases for {@link CallbackInfo}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class CallbackInfoTest { @@ -40,10 +38,8 @@ public class CallbackInfoTest { int handle = 1; byte[] value = "Test Value Byte Array".getBytes(); - CallbackInfo callbackInfo = new CallbackInfo.Builder(address, status) - .setHandle(handle) - .setValue(value) - .build(); + CallbackInfo callbackInfo = + new CallbackInfo.Builder(address, status).setHandle(handle).setValue(value).build(); assertThat(callbackInfo.address).isEqualTo(address); assertThat(callbackInfo.status).isEqualTo(status); diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java index 2dc195687cc..4c6f758db0f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java @@ -49,16 +49,13 @@ import org.mockito.junit.MockitoRule; import java.util.UUID; -/** - * Test cases for {@link ContextMap}. - */ +/** Test cases for {@link ContextMap}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class ContextMapTest { private static final String APP_NAME = "com.android.what.a.name"; - @Rule - public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -68,8 +65,7 @@ public class ContextMapTest { @Mock private TransitionalScanHelper mMockScanHelper; @Mock private PackageManager mMockPackageManager; - @Spy - private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); + @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); @Before public void setUp() throws Exception { diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java index 077d2b9f4b4..829b39e9c7a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java @@ -50,9 +50,7 @@ import org.mockito.junit.MockitoRule; import java.util.UUID; -/** - * Test cases for {@link DistanceMeasurementManager}. - */ +/** Test cases for {@link DistanceMeasurementManager}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class DistanceMeasurementManagerTest { @@ -85,98 +83,119 @@ public class DistanceMeasurementManagerTest { @Test public void testStartRssiTracker() { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - verify(mDistanceMeasurementNativeInterface).startDistanceMeasurement( - IDENTITY_ADDRESS, RSSI_FREQUENCY_LOW, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + verify(mDistanceMeasurementNativeInterface) + .startDistanceMeasurement( + IDENTITY_ADDRESS, + RSSI_FREQUENCY_LOW, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); } @Test public void testStopRssiTracker() { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - mDistanceMeasurementManager.stopDistanceMeasurement(mUuid, mDevice, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI, false); - verify(mDistanceMeasurementNativeInterface).stopDistanceMeasurement( - IDENTITY_ADDRESS, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementManager.stopDistanceMeasurement( + mUuid, mDevice, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI, false); + verify(mDistanceMeasurementNativeInterface) + .stopDistanceMeasurement( + IDENTITY_ADDRESS, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); } @Test public void testHandleRssiStarted() throws RemoteException { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - verify(mDistanceMeasurementNativeInterface).startDistanceMeasurement( - IDENTITY_ADDRESS, RSSI_FREQUENCY_LOW, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); - mDistanceMeasurementManager.onDistanceMeasurementStarted(IDENTITY_ADDRESS, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + verify(mDistanceMeasurementNativeInterface) + .startDistanceMeasurement( + IDENTITY_ADDRESS, + RSSI_FREQUENCY_LOW, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementManager.onDistanceMeasurementStarted( + IDENTITY_ADDRESS, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); verify(mCallback).onStarted(mDevice); } @Test public void testHandleRssiStartFail() throws RemoteException { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - verify(mDistanceMeasurementNativeInterface).startDistanceMeasurement( - IDENTITY_ADDRESS, RSSI_FREQUENCY_LOW, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); - mDistanceMeasurementManager.onDistanceMeasurementStartFail(IDENTITY_ADDRESS, + verify(mDistanceMeasurementNativeInterface) + .startDistanceMeasurement( + IDENTITY_ADDRESS, + RSSI_FREQUENCY_LOW, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementManager.onDistanceMeasurementStartFail( + IDENTITY_ADDRESS, BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); - verify(mCallback).onStartFail(mDevice, - BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL); + verify(mCallback) + .onStartFail(mDevice, BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL); } @Test public void testHandleRssiStopped() throws RemoteException { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - mDistanceMeasurementManager.onDistanceMeasurementStarted(IDENTITY_ADDRESS, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementManager.onDistanceMeasurementStarted( + IDENTITY_ADDRESS, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); verify(mCallback).onStarted(mDevice); - mDistanceMeasurementManager.onDistanceMeasurementStopped(IDENTITY_ADDRESS, + mDistanceMeasurementManager.onDistanceMeasurementStopped( + IDENTITY_ADDRESS, BluetoothStatusCodes.REASON_REMOTE_REQUEST, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); - verify(mCallback).onStopped(mDevice, - BluetoothStatusCodes.REASON_REMOTE_REQUEST); + verify(mCallback).onStopped(mDevice, BluetoothStatusCodes.REASON_REMOTE_REQUEST); } @Test public void testHandleRssiResult() throws RemoteException { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - mDistanceMeasurementManager.onDistanceMeasurementStarted(IDENTITY_ADDRESS, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementManager.onDistanceMeasurementStarted( + IDENTITY_ADDRESS, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); verify(mCallback).onStarted(mDevice); - mDistanceMeasurementManager.onDistanceMeasurementResult(IDENTITY_ADDRESS, - 100, 100, -1, -1, -1, -1, + mDistanceMeasurementManager.onDistanceMeasurementResult( + IDENTITY_ADDRESS, + 100, + 100, + -1, + -1, + -1, + -1, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); ArgumentCaptor result = ArgumentCaptor.forClass(DistanceMeasurementResult.class); @@ -191,21 +210,31 @@ public class DistanceMeasurementManagerTest { @Test public void testReceivedResultAfterStopped() throws RemoteException { - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(1000) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setDurationSeconds(DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(1000) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setDurationSeconds( + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); mDistanceMeasurementManager.startDistanceMeasurement(mUuid, params, mCallback); - mDistanceMeasurementManager.stopDistanceMeasurement(mUuid, mDevice, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI, false); - verify(mDistanceMeasurementNativeInterface).stopDistanceMeasurement( - IDENTITY_ADDRESS, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); - mDistanceMeasurementManager.onDistanceMeasurementResult(IDENTITY_ADDRESS, - 100, 100, -1, -1, -1, -1, + mDistanceMeasurementManager.stopDistanceMeasurement( + mUuid, mDevice, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI, false); + verify(mDistanceMeasurementNativeInterface) + .stopDistanceMeasurement( + IDENTITY_ADDRESS, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementManager.onDistanceMeasurementResult( + IDENTITY_ADDRESS, + 100, + 100, + -1, + -1, + -1, + -1, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); - DistanceMeasurementResult result = new DistanceMeasurementResult.Builder( - 1.00, 1.00).build(); + DistanceMeasurementResult result = + new DistanceMeasurementResult.Builder(1.00, 1.00).build(); verify(mCallback, after(100).never()).onResult(mDevice, result); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java index 603b20fe457..28bc62038da 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java @@ -43,9 +43,7 @@ import org.mockito.junit.MockitoRule; import java.util.UUID; -/** - * Test cases for {@link DistanceMeasurementTracker}. - */ +/** Test cases for {@link DistanceMeasurementTracker}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class DistanceMeasurementTrackerTest { @@ -67,13 +65,20 @@ public class DistanceMeasurementTrackerTest { public void setUp() throws Exception { mUuid = UUID.randomUUID(); mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(IDENTITY_ADDRESS); - mParams = new DistanceMeasurementParams.Builder(mDevice) - .setDurationSeconds(TIMEOUT_S) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .setMethodId(mMethod) - .build(); - mTracker = new DistanceMeasurementTracker( - mDistanceMeasurementManager, mParams, IDENTITY_ADDRESS, mUuid, 1000, mCallback); + mParams = + new DistanceMeasurementParams.Builder(mDevice) + .setDurationSeconds(TIMEOUT_S) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .setMethodId(mMethod) + .build(); + mTracker = + new DistanceMeasurementTracker( + mDistanceMeasurementManager, + mParams, + IDENTITY_ADDRESS, + mUuid, + 1000, + mCallback); mHandlerThread = new HandlerThread("DistanceMeasurementTrackerTestHandlerThread"); mHandlerThread.start(); } @@ -95,21 +100,33 @@ public class DistanceMeasurementTrackerTest { public void testCancelTimer() { mTracker.startTimer(mHandlerThread.getLooper()); mTracker.cancelTimer(); - verify(mDistanceMeasurementManager, after(TIMEOUT_MS).never()).stopDistanceMeasurement( - mUuid, mDevice, mMethod, true); + verify(mDistanceMeasurementManager, after(TIMEOUT_MS).never()) + .stopDistanceMeasurement(mUuid, mDevice, mMethod, true); } @Test public void testEquals() { - DistanceMeasurementTracker tracker = new DistanceMeasurementTracker( - mDistanceMeasurementManager, mParams, IDENTITY_ADDRESS, mUuid, 1000, mCallback); + DistanceMeasurementTracker tracker = + new DistanceMeasurementTracker( + mDistanceMeasurementManager, + mParams, + IDENTITY_ADDRESS, + mUuid, + 1000, + mCallback); assertThat(mTracker.equals(tracker)).isTrue(); } @Test public void testHashCode() { - DistanceMeasurementTracker tracker = new DistanceMeasurementTracker( - mDistanceMeasurementManager, mParams, IDENTITY_ADDRESS, mUuid, 1000, mCallback); + DistanceMeasurementTracker tracker = + new DistanceMeasurementTracker( + mDistanceMeasurementManager, + mParams, + IDENTITY_ADDRESS, + mUuid, + 1000, + mCallback); assertThat(mTracker.hashCode()).isEqualTo(tracker.hashCode()); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/FilterParamsTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/FilterParamsTest.java index 3033c12a5d0..84aebeafa6f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/FilterParamsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/FilterParamsTest.java @@ -24,9 +24,7 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; -/** - * Test cases for {@link FilterParams}. - */ +/** Test cases for {@link FilterParams}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class FilterParamsTest { @@ -46,20 +44,20 @@ public class FilterParamsTest { int foundTimeOutCnt = 10; int numOfTrackEntries = 11; - FilterParams filterParams = new FilterParams( - clientIf, - filtIndex, - featSeln, - listLogicType, - filtLogicType, - rssiHighValue, - rssiLowValue, - delyMode, - foundTimeOut, - lostTimeOut, - foundTimeOutCnt, - numOfTrackEntries - ); + FilterParams filterParams = + new FilterParams( + clientIf, + filtIndex, + featSeln, + listLogicType, + filtLogicType, + rssiHighValue, + rssiLowValue, + delyMode, + foundTimeOut, + lostTimeOut, + foundTimeOutCnt, + numOfTrackEntries); assertThat(filterParams).isNotNull(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java index 8d7f4aafe7d..dbf2e5c167c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java @@ -32,17 +32,14 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -/** - * Test cases for {@link GattDebugUtils}. - */ +/** Test cases for {@link GattDebugUtils}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class GattDebugUtilsTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private GattService mService; + @Mock private GattService mService; @Test public void handleDebugAction() { @@ -79,7 +76,7 @@ public class GattDebugUtilsTest { int initKey = 7; int respKey = 7; int maxKey = 16; - verify(mService).gattTestCommand(0xF0, null, null, authReq, ioCap, initKey, respKey, - maxKey); + verify(mService) + .gattTestCommand(0xF0, null, null, authReq, ioCap, initKey, respKey, maxKey); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java index 218dce7bc9f..0e2a2de3728 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java @@ -68,8 +68,7 @@ public class GattServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private GattService mService; + @Mock private GattService mService; @Mock private TransitionalScanHelper mScanHelper; private Context mContext; @@ -83,8 +82,8 @@ public class GattServiceBinderTest { public void setUp() throws Exception { mContext = InstrumentationRegistry.getTargetContext(); Intent intent = new Intent(); - mPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_IMMUTABLE); + mPendingIntent = + PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE); when(mService.isAvailable()).thenReturn(true); when(mService.getTransitionalScanHelper()).thenReturn(mScanHelper); mBinder = new GattService.BluetoothGattBinder(mService); @@ -207,8 +206,16 @@ public class GattServiceBinderTest { phy, mAttributionSource); - verify(mService).clientConnect(clientIf, address, addressType, isDirect, transport, - opportunistic, phy, mAttributionSource); + verify(mService) + .clientConnect( + clientIf, + address, + addressType, + isDirect, + transport, + opportunistic, + phy, + mAttributionSource); } @Test @@ -232,8 +239,9 @@ public class GattServiceBinderTest { mBinder.clientSetPreferredPhy( clientIf, address, txPhy, rxPhy, phyOptions, mAttributionSource); - verify(mService).clientSetPreferredPhy(clientIf, address, txPhy, rxPhy, phyOptions, - mAttributionSource); + verify(mService) + .clientSetPreferredPhy( + clientIf, address, txPhy, rxPhy, phyOptions, mAttributionSource); } @Test @@ -307,8 +315,15 @@ public class GattServiceBinderTest { authReq, mAttributionSource); - verify(mService).readUsingCharacteristicUuid(clientIf, address, uuid, startHandle, - endHandle, authReq, mAttributionSource); + verify(mService) + .readUsingCharacteristicUuid( + clientIf, + address, + uuid, + startHandle, + endHandle, + authReq, + mAttributionSource); } @Test @@ -323,8 +338,9 @@ public class GattServiceBinderTest { mBinder.writeCharacteristic( clientIf, address, handle, writeType, authReq, value, mAttributionSource); - verify(mService).writeCharacteristic(clientIf, address, handle, writeType, authReq, value, - mAttributionSource); + verify(mService) + .writeCharacteristic( + clientIf, address, handle, writeType, authReq, value, mAttributionSource); } @Test @@ -349,8 +365,8 @@ public class GattServiceBinderTest { mBinder.writeDescriptor(clientIf, address, handle, authReq, value, mAttributionSource); - verify(mService).writeDescriptor(clientIf, address, handle, authReq, value, - mAttributionSource); + verify(mService) + .writeDescriptor(clientIf, address, handle, authReq, value, mAttributionSource); } @Test @@ -383,8 +399,8 @@ public class GattServiceBinderTest { mBinder.registerForNotification(clientIf, address, handle, enable, mAttributionSource); - verify(mService).registerForNotification(clientIf, address, handle, enable, - mAttributionSource); + verify(mService) + .registerForNotification(clientIf, address, handle, enable, mAttributionSource); } @Test @@ -417,8 +433,9 @@ public class GattServiceBinderTest { mBinder.connectionParameterUpdate( clientIf, address, connectionPriority, mAttributionSource); - verify(mService).connectionParameterUpdate(clientIf, address, connectionPriority, - mAttributionSource); + verify(mService) + .connectionParameterUpdate( + clientIf, address, connectionPriority, mAttributionSource); } @Test @@ -443,10 +460,17 @@ public class GattServiceBinderTest { maxConnectionEventLen, mAttributionSource); - verify(mService).leConnectionUpdate( - clientIf, address, minConnectionInterval, maxConnectionInterval, - peripheralLatency, supervisionTimeout, minConnectionEventLen, - maxConnectionEventLen, mAttributionSource); + verify(mService) + .leConnectionUpdate( + clientIf, + address, + minConnectionInterval, + maxConnectionInterval, + peripheralLatency, + supervisionTimeout, + minConnectionEventLen, + maxConnectionEventLen, + mAttributionSource); } @Test @@ -506,8 +530,9 @@ public class GattServiceBinderTest { mBinder.serverSetPreferredPhy( serverIf, address, txPhy, rxPhy, phyOptions, mAttributionSource); - verify(mService).serverSetPreferredPhy(serverIf, address, txPhy, rxPhy, phyOptions, - mAttributionSource); + verify(mService) + .serverSetPreferredPhy( + serverIf, address, txPhy, rxPhy, phyOptions, mAttributionSource); } @Test @@ -561,8 +586,9 @@ public class GattServiceBinderTest { mBinder.sendResponse( serverIf, address, requestId, status, offset, value, mAttributionSource); - verify(mService).sendResponse(serverIf, address, requestId, status, offset, value, - mAttributionSource); + verify(mService) + .sendResponse( + serverIf, address, requestId, status, offset, value, mAttributionSource); } @Test @@ -575,8 +601,8 @@ public class GattServiceBinderTest { mBinder.sendNotification(serverIf, address, handle, confirm, value, mAttributionSource); - verify(mService).sendNotification(serverIf, address, handle, confirm, value, - mAttributionSource); + verify(mService) + .sendNotification(serverIf, address, handle, confirm, value, mAttributionSource); } @Test @@ -604,9 +630,18 @@ public class GattServiceBinderTest { callback, mAttributionSource); - verify(mService).startAdvertisingSet(parameters, advertiseData, scanResponse, - periodicParameters, periodicData, duration, maxExtAdvEvents, - serverIf, callback, mAttributionSource); + verify(mService) + .startAdvertisingSet( + parameters, + advertiseData, + scanResponse, + periodicParameters, + periodicData, + duration, + maxExtAdvEvents, + serverIf, + callback, + mAttributionSource); } @Test @@ -637,8 +672,9 @@ public class GattServiceBinderTest { mBinder.enableAdvertisingSet( advertiserId, enable, duration, maxExtAdvEvents, mAttributionSource); - verify(mService).enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents, - mAttributionSource); + verify(mService) + .enableAdvertisingSet( + advertiserId, enable, duration, maxExtAdvEvents, mAttributionSource); } @Test @@ -679,8 +715,8 @@ public class GattServiceBinderTest { mBinder.setPeriodicAdvertisingParameters(advertiserId, parameters, mAttributionSource); - verify(mService).setPeriodicAdvertisingParameters(advertiserId, parameters, - mAttributionSource); + verify(mService) + .setPeriodicAdvertisingParameters(advertiserId, parameters, mAttributionSource); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java index d3b15802e03..8d33f570630 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java @@ -69,9 +69,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -/** - * Test cases for {@link GattService}. - */ +/** Test cases for {@link GattService}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class GattServiceTest { @@ -120,7 +118,8 @@ public class GattServiceTest { GattObjectsFactory.setInstanceForTesting(mFactory); doReturn(mNativeInterface).when(mFactory).getNativeInterface(); doReturn(mScanManager).when(mFactory).createScanManager(any(), any(), any(), any(), any()); - doReturn(mDistanceMeasurementManager).when(mFactory) + doReturn(mDistanceMeasurementManager) + .when(mFactory) .createDistanceMeasurementManager(any()); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -130,8 +129,10 @@ public class GattServiceTest { when(mAdapterService.getResources()).thenReturn(mResources); when(mResources.getInteger(anyInt())).thenReturn(0); when(mAdapterService.getSharedPreferences(anyString(), anyInt())) - .thenReturn(InstrumentationRegistry.getTargetContext() - .getSharedPreferences("GattServiceTestPrefs", Context.MODE_PRIVATE)); + .thenReturn( + InstrumentationRegistry.getTargetContext() + .getSharedPreferences( + "GattServiceTestPrefs", Context.MODE_PRIVATE)); TestUtils.mockGetSystemService( mAdapterService, Context.LOCATION_SERVICE, LocationManager.class); @@ -205,10 +206,10 @@ public class GattServiceTest { Integer connId = 1; doReturn(connId).when(mClientMap).connIdByAddress(clientIf, address); - mService.clientSetPreferredPhy(clientIf, address, txPhy, rxPhy, phyOptions, - mAttributionSource); - verify(mNativeInterface).gattClientSetPreferredPhy(clientIf, address, txPhy, rxPhy, - phyOptions); + mService.clientSetPreferredPhy( + clientIf, address, txPhy, rxPhy, phyOptions, mAttributionSource); + verify(mNativeInterface) + .gattClientSetPreferredPhy(clientIf, address, txPhy, rxPhy, phyOptions); } @Test @@ -217,19 +218,27 @@ public class GattServiceTest { String address = REMOTE_DEVICE_ADDRESS; int connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_HIGH; - mService.connectionParameterUpdate(clientIf, address, connectionPriority, - mAttributionSource); + mService.connectionParameterUpdate( + clientIf, address, connectionPriority, mAttributionSource); connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER; - mService.connectionParameterUpdate(clientIf, address, connectionPriority, - mAttributionSource); + mService.connectionParameterUpdate( + clientIf, address, connectionPriority, mAttributionSource); connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED; - mService.connectionParameterUpdate(clientIf, address, connectionPriority, - mAttributionSource); + mService.connectionParameterUpdate( + clientIf, address, connectionPriority, mAttributionSource); - verify(mNativeInterface, times(3)).gattConnectionParameterUpdate(eq(clientIf), - eq(address), anyInt(), anyInt(), anyInt(), anyInt(), eq(0), eq(0)); + verify(mNativeInterface, times(3)) + .gattConnectionParameterUpdate( + eq(clientIf), + eq(address), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + eq(0), + eq(0)); } @Test @@ -247,11 +256,19 @@ public class GattServiceTest { boolean opportunistic = true; int phy = 3; - mService.clientConnect(clientIf, address, addressType, isDirect, transport, - opportunistic, phy, mAttributionSource); + mService.clientConnect( + clientIf, + address, + addressType, + isDirect, + transport, + opportunistic, + phy, + mAttributionSource); - verify(mNativeInterface).gattClientConnect(clientIf, address, addressType, - isDirect, transport, opportunistic, phy); + verify(mNativeInterface) + .gattClientConnect( + clientIf, address, addressType, isDirect, transport, opportunistic, phy); } @Test @@ -322,7 +339,7 @@ public class GattServiceTest { int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; BluetoothDevice testDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); - BluetoothDevice[] bluetoothDevices = new BluetoothDevice[]{testDevice}; + BluetoothDevice[] bluetoothDevices = new BluetoothDevice[] {testDevice}; doReturn(bluetoothDevices).when(mAdapterService).getBondedDevices(); Set connectedDevices = new HashSet<>(); @@ -347,8 +364,9 @@ public class GattServiceTest { boolean eattSupport = true; mService.registerClient(uuid, callback, eattSupport, mAttributionSource); - verify(mNativeInterface).gattClientRegisterApp(uuid.getLeastSignificantBits(), - uuid.getMostSignificantBits(), eattSupport); + verify(mNativeInterface) + .gattClientRegisterApp( + uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(), eattSupport); } @Test @@ -386,11 +404,16 @@ public class GattServiceTest { Integer connId = 1; doReturn(connId).when(mClientMap).connIdByAddress(clientIf, address); - mService.readUsingCharacteristicUuid(clientIf, address, uuid, startHandle, endHandle, - authReq, mAttributionSource); - verify(mNativeInterface).gattClientReadUsingCharacteristicUuid(connId, - uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(), startHandle, - endHandle, authReq); + mService.readUsingCharacteristicUuid( + clientIf, address, uuid, startHandle, endHandle, authReq, mAttributionSource); + verify(mNativeInterface) + .gattClientReadUsingCharacteristicUuid( + connId, + uuid.getLeastSignificantBits(), + uuid.getMostSignificantBits(), + startHandle, + endHandle, + authReq); } @Test @@ -405,8 +428,9 @@ public class GattServiceTest { Integer connId = 1; doReturn(connId).when(mClientMap).connIdByAddress(clientIf, address); - int writeCharacteristicResult = mService.writeCharacteristic(clientIf, address, handle, - writeType, authReq, value, mAttributionSource); + int writeCharacteristicResult = + mService.writeCharacteristic( + clientIf, address, handle, writeType, authReq, value, mAttributionSource); assertThat(writeCharacteristicResult) .isEqualTo(BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED); } @@ -460,8 +484,8 @@ public class GattServiceTest { mService.registerForNotification(clientIf, address, handle, enable, mAttributionSource); - verify(mNativeInterface).gattClientRegisterForNotifications(clientIf, address, handle, - enable); + verify(mNativeInterface) + .gattClientRegisterForNotifications(clientIf, address, handle, enable); } @Test @@ -497,13 +521,27 @@ public class GattServiceTest { int minConnectionEventLen = 7; int maxConnectionEventLen = 8; - mService.leConnectionUpdate(clientIf, address, minInterval, maxInterval, - peripheralLatency, supervisionTimeout, minConnectionEventLen, - maxConnectionEventLen, mAttributionSource); + mService.leConnectionUpdate( + clientIf, + address, + minInterval, + maxInterval, + peripheralLatency, + supervisionTimeout, + minConnectionEventLen, + maxConnectionEventLen, + mAttributionSource); - verify(mNativeInterface).gattConnectionParameterUpdate(clientIf, address, minInterval, - maxInterval, peripheralLatency, supervisionTimeout, minConnectionEventLen, - maxConnectionEventLen); + verify(mNativeInterface) + .gattConnectionParameterUpdate( + clientIf, + address, + minInterval, + maxInterval, + peripheralLatency, + supervisionTimeout, + minConnectionEventLen, + maxConnectionEventLen); } @Test @@ -540,10 +578,10 @@ public class GattServiceTest { int rxPhy = 1; int phyOptions = 3; - mService.serverSetPreferredPhy(serverIf, address, txPhy, rxPhy, phyOptions, - mAttributionSource); - verify(mNativeInterface).gattServerSetPreferredPhy(serverIf, address, txPhy, rxPhy, - phyOptions); + mService.serverSetPreferredPhy( + serverIf, address, txPhy, rxPhy, phyOptions, mAttributionSource); + verify(mNativeInterface) + .gattServerSetPreferredPhy(serverIf, address, txPhy, rxPhy, phyOptions); } @Test @@ -589,8 +627,8 @@ public class GattServiceTest { int duration = 3; int maxExtAdvEvents = 4; - mService.enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents, - mAttributionSource); + mService.enableAdvertisingSet( + advertiserId, enable, duration, maxExtAdvEvents, mAttributionSource); } @Test @@ -621,10 +659,11 @@ public class GattServiceTest { public void startDistanceMeasurement() { UUID uuid = UUID.randomUUID(); BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05"); - DistanceMeasurementParams params = new DistanceMeasurementParams.Builder(device) - .setDurationSeconds(123) - .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) - .build(); + DistanceMeasurementParams params = + new DistanceMeasurementParams.Builder(device) + .setDurationSeconds(123) + .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW) + .build(); IDistanceMeasurementCallback callback = mock(IDistanceMeasurementCallback.class); mService.startDistanceMeasurement(uuid, params, callback); verify(mDistanceMeasurementManager).startDistanceMeasurement(uuid, params, callback); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java index 813a55a3097..7b219591ce6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java @@ -35,11 +35,10 @@ import org.mockito.junit.MockitoRule; public class HapClientNativeInterfaceTest { private static final byte[] TEST_DEVICE_ADDRESS = - new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - HapClientService mService; + @Mock HapClientService mService; private HapClientNativeInterface mNativeInterface; @@ -63,8 +62,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); assertThat(event.getValue().valueInt1).isEqualTo(state); } @@ -76,8 +75,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); assertThat(event.getValue().valueInt1).isEqualTo(features); } @@ -89,8 +88,7 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); + assertThat(event.getValue().type).isEqualTo(HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); assertThat(event.getValue().valueInt1).isEqualTo(features); } @@ -102,8 +100,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); assertThat(event.getValue().valueInt1).isEqualTo(presetIndex); } @@ -116,13 +114,12 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); assertThat(event.getValue().valueInt1).isEqualTo(presetIndex); assertThat(event.getValue().valueInt2).isEqualTo(groupId); } - @Test public void onActivePresetSelectError() { int resultCode = -1; @@ -131,8 +128,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); assertThat(event.getValue().valueInt1).isEqualTo(resultCode); } @@ -145,8 +142,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); assertThat(event.getValue().valueInt1).isEqualTo(resultCode); assertThat(event.getValue().valueInt2).isEqualTo(groupId); } @@ -154,18 +151,18 @@ public class HapClientNativeInterfaceTest { @Test public void onPresetInfo() { int infoReason = HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO; - BluetoothHapPresetInfo[] presets = - {new BluetoothHapPresetInfo.Builder(0x01, "onPresetInfo") - .setWritable(true) - .setAvailable(false) - .build()}; + BluetoothHapPresetInfo[] presets = { + new BluetoothHapPresetInfo.Builder(0x01, "onPresetInfo") + .setWritable(true) + .setAvailable(false) + .build() + }; mNativeInterface.onPresetInfo(TEST_DEVICE_ADDRESS, infoReason, presets); ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); + assertThat(event.getValue().type).isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); assertThat(event.getValue().valueInt2).isEqualTo(infoReason); assertThat(event.getValue().valueList.toArray()).isEqualTo(presets); } @@ -174,18 +171,18 @@ public class HapClientNativeInterfaceTest { public void onGroupPresetInfo() { int groupId = 100; int infoReason = HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO; - BluetoothHapPresetInfo[] presets = - {new BluetoothHapPresetInfo.Builder(0x01, "onPresetInfo") - .setWritable(true) - .setAvailable(false) - .build()}; + BluetoothHapPresetInfo[] presets = { + new BluetoothHapPresetInfo.Builder(0x01, "onPresetInfo") + .setWritable(true) + .setAvailable(false) + .build() + }; mNativeInterface.onGroupPresetInfo(groupId, infoReason, presets); ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); + assertThat(event.getValue().type).isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); assertThat(event.getValue().valueInt2).isEqualTo(infoReason); assertThat(event.getValue().valueInt3).isEqualTo(groupId); assertThat(event.getValue().valueList.toArray()).isEqualTo(presets); @@ -200,8 +197,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); assertThat(event.getValue().valueInt1).isEqualTo(resultCode); assertThat(event.getValue().valueInt2).isEqualTo(presetIndex); } @@ -216,8 +213,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); assertThat(event.getValue().valueInt1).isEqualTo(resultCode); assertThat(event.getValue().valueInt2).isEqualTo(presetIndex); assertThat(event.getValue().valueInt3).isEqualTo(groupId); @@ -232,8 +229,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); assertThat(event.getValue().valueInt1).isEqualTo(resultCode); assertThat(event.getValue().valueInt2).isEqualTo(presetIndex); } @@ -248,8 +245,8 @@ public class HapClientNativeInterfaceTest { ArgumentCaptor event = ArgumentCaptor.forClass(HapClientStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); + assertThat(event.getValue().type) + .isEqualTo(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); assertThat(event.getValue().valueInt1).isEqualTo(resultCode); assertThat(event.getValue().valueInt2).isEqualTo(presetIndex); assertThat(event.getValue().valueInt3).isEqualTo(groupId); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java index 20a6790e5a0..d307a5ce9e0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java @@ -25,141 +25,146 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public final class HapClientStackEventTest { - @Test - public void toString_containsProperSubStrings() { - HapClientStackEvent event; - String eventStr; - event = new HapClientStackEvent(0 /* EVENT_TYPE_NONE */); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_NONE"); - - event = new HapClientStackEvent(10000); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_UNKNOWN"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - event.valueInt1 = -1; - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_CONNECTION_STATE_CHANGED"); - assertThat(eventStr).contains("CONNECTION_STATE_UNKNOWN"); - - event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTED; - eventStr = event.toString(); - assertThat(eventStr).contains("CONNECTION_STATE_DISCONNECTED"); - - event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTING; - eventStr = event.toString(); - assertThat(eventStr).contains("CONNECTION_STATE_CONNECTING"); - - event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; - eventStr = event.toString(); - assertThat(eventStr).contains("CONNECTION_STATE_CONNECTED"); - - event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTING; - eventStr = event.toString(); - assertThat(eventStr).contains("CONNECTION_STATE_DISCONNECTING"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_DEVICE_AVAILABLE"); - - event.valueInt1 = 1 << HapClientStackEvent.FEATURE_BIT_NUM_TYPE_MONAURAL - | 1 << HapClientStackEvent.FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS; - eventStr = event.toString(); - assertThat(eventStr).contains("TYPE_MONAURAL"); - assertThat(eventStr).contains("SYNCHRONIZATED_PRESETS"); - - event.valueInt1 = 1 << HapClientStackEvent.FEATURE_BIT_NUM_TYPE_BANDED - | 1 << HapClientStackEvent.FEATURE_BIT_NUM_INDEPENDENT_PRESETS; - eventStr = event.toString(); - assertThat(eventStr).contains("TYPE_BANDED"); - assertThat(eventStr).contains("INDEPENDENT_PRESETS"); - - event.valueInt1 = 1 << HapClientStackEvent.FEATURE_BIT_NUM_DYNAMIC_PRESETS - | 1 << HapClientStackEvent.FEATURE_BIT_NUM_WRITABLE_PRESETS; - eventStr = event.toString(); - assertThat(eventStr).contains("TYPE_BINAURAL"); - assertThat(eventStr).contains("DYNAMIC_PRESETS"); - assertThat(eventStr).contains("WRITABLE_PRESETS"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_DEVICE_FEATURES"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); - event.valueInt1 = -1; - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR"); - assertThat(eventStr).contains("ERROR_UNKNOWN"); - - event.valueInt1 = HapClientStackEvent.STATUS_NO_ERROR; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_NO_ERROR"); - - event.valueInt1 = HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_SET_NAME_NOT_ALLOWED"); - - event.valueInt1 = HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_OPERATION_NOT_SUPPORTED"); - - event.valueInt1 = HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_OPERATION_NOT_POSSIBLE"); - - event.valueInt1 = HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_INVALID_PRESET_NAME_LENGTH"); - - event.valueInt1 = HapClientStackEvent.STATUS_INVALID_PRESET_INDEX; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_INVALID_PRESET_INDEX"); - - event.valueInt1 = HapClientStackEvent.STATUS_GROUP_OPERATION_NOT_SUPPORTED; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_GROUP_OPERATION_NOT_SUPPORTED"); - - event.valueInt1 = HapClientStackEvent.STATUS_PROCEDURE_ALREADY_IN_PROGRESS; - eventStr = event.toString(); - assertThat(eventStr).contains("STATUS_PROCEDURE_ALREADY_IN_PROGRESS"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); - event.valueInt2 = -1; - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_ON_PRESET_INFO"); - assertThat(eventStr).contains("UNKNOWN"); - - event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO; - eventStr = event.toString(); - assertThat(eventStr).contains("PRESET_INFO_REASON_ALL_PRESET_INFO"); - - event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE; - eventStr = event.toString(); - assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_INFO_UPDATE"); - - event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED; - eventStr = event.toString(); - assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_DELETED"); - - event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED; - eventStr = event.toString(); - assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED"); - - event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE; - eventStr = event.toString(); - assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_ON_PRESET_NAME_SET_ERROR"); - - event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); - eventStr = event.toString(); - assertThat(eventStr).contains("EVENT_TYPE_ON_PRESET_INFO_ERROR"); - } + @Test + public void toString_containsProperSubStrings() { + HapClientStackEvent event; + String eventStr; + event = new HapClientStackEvent(0 /* EVENT_TYPE_NONE */); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_NONE"); + + event = new HapClientStackEvent(10000); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_UNKNOWN"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event.valueInt1 = -1; + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_CONNECTION_STATE_CHANGED"); + assertThat(eventStr).contains("CONNECTION_STATE_UNKNOWN"); + + event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTED; + eventStr = event.toString(); + assertThat(eventStr).contains("CONNECTION_STATE_DISCONNECTED"); + + event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTING; + eventStr = event.toString(); + assertThat(eventStr).contains("CONNECTION_STATE_CONNECTING"); + + event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; + eventStr = event.toString(); + assertThat(eventStr).contains("CONNECTION_STATE_CONNECTED"); + + event.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTING; + eventStr = event.toString(); + assertThat(eventStr).contains("CONNECTION_STATE_DISCONNECTING"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_DEVICE_AVAILABLE"); + + event.valueInt1 = + 1 << HapClientStackEvent.FEATURE_BIT_NUM_TYPE_MONAURAL + | 1 << HapClientStackEvent.FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS; + eventStr = event.toString(); + assertThat(eventStr).contains("TYPE_MONAURAL"); + assertThat(eventStr).contains("SYNCHRONIZATED_PRESETS"); + + event.valueInt1 = + 1 << HapClientStackEvent.FEATURE_BIT_NUM_TYPE_BANDED + | 1 << HapClientStackEvent.FEATURE_BIT_NUM_INDEPENDENT_PRESETS; + eventStr = event.toString(); + assertThat(eventStr).contains("TYPE_BANDED"); + assertThat(eventStr).contains("INDEPENDENT_PRESETS"); + + event.valueInt1 = + 1 << HapClientStackEvent.FEATURE_BIT_NUM_DYNAMIC_PRESETS + | 1 << HapClientStackEvent.FEATURE_BIT_NUM_WRITABLE_PRESETS; + eventStr = event.toString(); + assertThat(eventStr).contains("TYPE_BINAURAL"); + assertThat(eventStr).contains("DYNAMIC_PRESETS"); + assertThat(eventStr).contains("WRITABLE_PRESETS"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_DEVICE_FEATURES"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED"); + + event = + new HapClientStackEvent( + HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); + event.valueInt1 = -1; + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR"); + assertThat(eventStr).contains("ERROR_UNKNOWN"); + + event.valueInt1 = HapClientStackEvent.STATUS_NO_ERROR; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_NO_ERROR"); + + event.valueInt1 = HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_SET_NAME_NOT_ALLOWED"); + + event.valueInt1 = HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_OPERATION_NOT_SUPPORTED"); + + event.valueInt1 = HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_OPERATION_NOT_POSSIBLE"); + + event.valueInt1 = HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_INVALID_PRESET_NAME_LENGTH"); + + event.valueInt1 = HapClientStackEvent.STATUS_INVALID_PRESET_INDEX; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_INVALID_PRESET_INDEX"); + + event.valueInt1 = HapClientStackEvent.STATUS_GROUP_OPERATION_NOT_SUPPORTED; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_GROUP_OPERATION_NOT_SUPPORTED"); + + event.valueInt1 = HapClientStackEvent.STATUS_PROCEDURE_ALREADY_IN_PROGRESS; + eventStr = event.toString(); + assertThat(eventStr).contains("STATUS_PROCEDURE_ALREADY_IN_PROGRESS"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); + event.valueInt2 = -1; + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_ON_PRESET_INFO"); + assertThat(eventStr).contains("UNKNOWN"); + + event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO; + eventStr = event.toString(); + assertThat(eventStr).contains("PRESET_INFO_REASON_ALL_PRESET_INFO"); + + event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE; + eventStr = event.toString(); + assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_INFO_UPDATE"); + + event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED; + eventStr = event.toString(); + assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_DELETED"); + + event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED; + eventStr = event.toString(); + assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED"); + + event.valueInt2 = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE; + eventStr = event.toString(); + assertThat(eventStr).contains("PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_ON_PRESET_NAME_SET_ERROR"); + + event = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); + eventStr = event.toString(); + assertThat(eventStr).contains("EVENT_TYPE_ON_PRESET_INFO_ERROR"); + } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java index 4c878d896fa..808acc5bd4a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java @@ -63,12 +63,9 @@ public class HapClientStateMachineTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AdapterService mAdapterService; - @Mock - private HapClientService mHapClientService; - @Mock - private HapClientNativeInterface mHearingAccessGattClientInterface; + @Mock private AdapterService mAdapterService; + @Mock private HapClientService mHapClientService; + @Mock private HapClientNativeInterface mHearingAccessGattClientInterface; @Before public void setUp() throws Exception { @@ -83,10 +80,14 @@ public class HapClientStateMachineTest { // Set up thread and looper mHandlerThread = new HandlerThread("HapClientStateMachineTestHandlerThread"); mHandlerThread.start(); - mHapClientStateMachine = new HapClientStateMachine(mTestDevice, - mHapClientService, mHearingAccessGattClientInterface, mHandlerThread.getLooper()); + mHapClientStateMachine = + new HapClientStateMachine( + mTestDevice, + mHapClientService, + mHearingAccessGattClientInterface, + mHandlerThread.getLooper()); // Override the timeout value to speed up the test - HapClientStateMachine.sConnectTimeoutMs = 1000; // 1s + HapClientStateMachine.sConnectTimeoutMs = 1000; // 1s mHapClientStateMachine.start(); } @@ -102,13 +103,11 @@ public class HapClientStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mHapClientStateMachine.getConnectionState()); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mHapClientStateMachine.getConnectionState()); } /** @@ -120,53 +119,50 @@ public class HapClientStateMachineTest { doReturn(allow).when(mHapClientService).okToConnect(any(BluetoothDevice.class)); } - /** - * Test that an incoming connection with policy forbidding connection is rejected - */ + /** Test that an incoming connection with policy forbidding connection is rejected */ @Test public void testIncomingPolicyReject() { allowConnection(false); // Inject an event for when incoming connection is requested HapClientStackEvent connStCh = - new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; mHapClientStateMachine.sendMessage(HapClientStateMachine.STACK_EVENT, connStCh); // Verify that no connection state broadcast is executed - verify(mHapClientService, after(TIMEOUT_MS).never()).sendBroadcast(any(Intent.class), - anyString()); + verify(mHapClientService, after(TIMEOUT_MS).never()) + .sendBroadcast(any(Intent.class), anyString()); // Check that we are in Disconnected state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Disconnected.class)); } - /** - * Test that an incoming connection with policy allowing connection is accepted - */ + /** Test that an incoming connection with policy allowing connection is accepted */ @Test public void testIncomingPolicyAccept() { allowConnection(true); // Inject an event for when incoming connection is requested HapClientStackEvent connStCh = - new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTING; mHapClientStateMachine.sendMessage(HapClientStateMachine.STACK_EVENT, connStCh); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mHapClientService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), anyString()); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mHapClientService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString()); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Connecting.class)); // Send a message to trigger connection completed @@ -174,98 +170,103 @@ public class HapClientStateMachineTest { new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mTestDevice; connCompletedEvent.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; - mHapClientStateMachine.sendMessage(HapClientStateMachine.STACK_EVENT, - connCompletedEvent); + mHapClientStateMachine.sendMessage(HapClientStateMachine.STACK_EVENT, connCompletedEvent); // Verify that the expected number of broadcasts are executed: // - two calls to broadcastConnectionState(): Disconnected -> Connecting -> Connected ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHapClientService, timeout(TIMEOUT_MS).times(2)).sendBroadcast( - intentArgument2.capture(), anyString()); + verify(mHapClientService, timeout(TIMEOUT_MS).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString()); // Check that we are in Connected state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Connected.class)); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingTimeout() { allowConnection(true); - doReturn(true).when(mHearingAccessGattClientInterface).connectHapClient(any( - BluetoothDevice.class)); - doReturn(true).when(mHearingAccessGattClientInterface).disconnectHapClient(any( - BluetoothDevice.class)); + doReturn(true) + .when(mHearingAccessGattClientInterface) + .connectHapClient(any(BluetoothDevice.class)); + doReturn(true) + .when(mHearingAccessGattClientInterface) + .disconnectHapClient(any(BluetoothDevice.class)); // Send a connect request mHapClientStateMachine.sendMessage(HapClientStateMachine.CONNECT, mTestDevice); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mHapClientService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), - anyString()); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mHapClientService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString()); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHapClientService, timeout(HapClientStateMachine.sConnectTimeoutMs * 2).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString()); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + verify(mHapClientService, timeout(HapClientStateMachine.sConnectTimeoutMs * 2).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString()); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Disconnected state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Disconnected.class)); verify(mHearingAccessGattClientInterface).disconnectHapClient(eq(mTestDevice)); } - /** - * Test that an incoming connection times out - */ + /** Test that an incoming connection times out */ @Test public void testIncomingTimeout() { allowConnection(true); - doReturn(true).when(mHearingAccessGattClientInterface).connectHapClient(any( - BluetoothDevice.class)); - doReturn(true).when(mHearingAccessGattClientInterface).disconnectHapClient(any( - BluetoothDevice.class)); + doReturn(true) + .when(mHearingAccessGattClientInterface) + .connectHapClient(any(BluetoothDevice.class)); + doReturn(true) + .when(mHearingAccessGattClientInterface) + .disconnectHapClient(any(BluetoothDevice.class)); // Inject an event for when incoming connection is requested HapClientStackEvent connStCh = - new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTING; mHapClientStateMachine.sendMessage(HapClientStateMachine.STACK_EVENT, connStCh); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mHapClientService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), - anyString()); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mHapClientService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString()); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHapClientService, timeout(HapClientStateMachine.sConnectTimeoutMs * 2).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString()); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + verify(mHapClientService, timeout(HapClientStateMachine.sConnectTimeoutMs * 2).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString()); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Disconnected state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Disconnected.class)); verify(mHearingAccessGattClientInterface).disconnectHapClient(eq(mTestDevice)); } @@ -273,11 +274,13 @@ public class HapClientStateMachineTest { @Test public void testStatesChangesWithMessages() { allowConnection(true); - doReturn(true).when(mHearingAccessGattClientInterface).connectHapClient(any( - BluetoothDevice.class)); + doReturn(true) + .when(mHearingAccessGattClientInterface) + .connectHapClient(any(BluetoothDevice.class)); // Check that we are in Disconnected state - Assert.assertThat(mHapClientStateMachine.getCurrentState(), + Assert.assertThat( + mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HapClientStateMachine.Disconnected.class)); mHapClientStateMachine.sendMessage(HapClientStateMachine.DISCONNECT); @@ -308,32 +311,29 @@ public class HapClientStateMachineTest { mHapClientStateMachine.obtainMessage(HapClientStateMachine.CONNECT), HapClientStateMachine.Connecting.class); // connecting -> disconnecting - HapClientStackEvent connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + HapClientStackEvent connStCh = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTING; sendMessageAndVerifyTransition( mHapClientStateMachine.obtainMessage(HapClientStateMachine.STACK_EVENT, connStCh), HapClientStateMachine.Disconnecting.class); // disconnecting -> connecting - connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connStCh = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTING; sendMessageAndVerifyTransition( mHapClientStateMachine.obtainMessage(HapClientStateMachine.STACK_EVENT, connStCh), HapClientStateMachine.Connecting.class); // connecting -> connected - connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connStCh = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( mHapClientStateMachine.obtainMessage(HapClientStateMachine.STACK_EVENT, connStCh), HapClientStateMachine.Connected.class); // connected -> disconnecting - connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connStCh = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTING; sendMessageAndVerifyTransition( @@ -345,8 +345,7 @@ public class HapClientStateMachineTest { HapClientStateMachine.Disconnected.class); // disconnected -> connected - connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connStCh = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( @@ -358,16 +357,14 @@ public class HapClientStateMachineTest { HapClientStateMachine.Disconnected.class); // disconnected -> connected - connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connStCh = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_CONNECTED; sendMessageAndVerifyTransition( mHapClientStateMachine.obtainMessage(HapClientStateMachine.STACK_EVENT, connStCh), HapClientStateMachine.Connected.class); // connected -> disconnected - connStCh = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connStCh = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTED; sendMessageAndVerifyTransition( @@ -379,8 +376,8 @@ public class HapClientStateMachineTest { Mockito.clearInvocations(mHapClientService); mHapClientStateMachine.sendMessage(msg); // Verify that one connection state broadcast is executed - verify(mHapClientService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - any(Intent.class), anyString()); + verify(mHapClientService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(any(Intent.class), anyString()); Assert.assertThat(mHapClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(type)); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java index 9188a640fee..4b8f108a06e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java @@ -117,7 +117,6 @@ public class HapClientTest { System.setProperty("dexmaker.share_classloader", "true"); } - HapClientStateMachine.sConnectTimeoutMs = TIMEOUT_MS; doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); @@ -141,19 +140,25 @@ public class HapClientTest { mDevice3 = TestUtils.getTestDevice(mAdapter, 2); when(mNativeInterface.getDevice(getByteAddress(mDevice3))).thenReturn(mDevice3); - doCallRealMethod().when(mNativeInterface) + doCallRealMethod() + .when(mNativeInterface) .sendMessageToService(any(HapClientStackEvent.class)); doCallRealMethod().when(mNativeInterface).onFeaturesUpdate(any(byte[].class), anyInt()); doCallRealMethod().when(mNativeInterface).onDeviceAvailable(any(byte[].class), anyInt()); - doCallRealMethod().when(mNativeInterface) + doCallRealMethod() + .when(mNativeInterface) .onActivePresetSelected(any(byte[].class), anyInt()); - doCallRealMethod().when(mNativeInterface) + doCallRealMethod() + .when(mNativeInterface) .onActivePresetSelectError(any(byte[].class), anyInt()); - doCallRealMethod().when(mNativeInterface) + doCallRealMethod() + .when(mNativeInterface) .onPresetNameSetError(any(byte[].class), anyInt(), anyInt()); - doCallRealMethod().when(mNativeInterface) + doCallRealMethod() + .when(mNativeInterface) .onPresetInfo(any(byte[].class), anyInt(), any(BluetoothHapPresetInfo[].class)); - doCallRealMethod().when(mNativeInterface) + doCallRealMethod() + .when(mNativeInterface) .onGroupPresetNameSetError(anyInt(), anyInt(), anyInt()); /* Prepare CAS groups */ @@ -165,11 +170,11 @@ public class HapClientTest { int groupId3 = 0x03; Map groups3 = new HashMap(); - groups3.put(groupId3, - ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB")); + groups3.put(groupId3, ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB")); - doReturn(Arrays.asList(mDevice, mDevice2)).when(mCsipService) - .getGroupDevicesOrdered(groupId2); + doReturn(Arrays.asList(mDevice, mDevice2)) + .when(mCsipService) + .getGroupDevicesOrdered(groupId2); doReturn(groups2).when(mCsipService).getGroupUuidMapByDevice(mDevice); doReturn(groups2).when(mCsipService).getGroupUuidMapByDevice(mDevice2); @@ -178,9 +183,11 @@ public class HapClientTest { doReturn(Arrays.asList(mDevice)).when(mCsipService).getGroupDevicesOrdered(0x01); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); } @@ -214,17 +221,13 @@ public class HapClientTest { Assert.assertNull(mService); } - /** - * Test getting HA Service Client - */ + /** Test getting HA Service Client */ @Test public void testGetHapService() { Assert.assertEquals(mService, HapClientService.getHapClientService()); } - /** - * Test stop HA Service Client - */ + /** Test stop HA Service Client */ @Test public void testStopHapService() { Assert.assertEquals(mService, HapClientService.getHapClientService()); @@ -236,117 +239,133 @@ public class HapClientTest { /** Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() throws Exception { - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", + Assert.assertEquals( + "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mService.getConnectionPolicy(mDevice)); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - Assert.assertEquals("Setting device policy to POLICY_FORBIDDEN", + Assert.assertEquals( + "Setting device policy to POLICY_FORBIDDEN", BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, mService.getConnectionPolicy(mDevice)); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // call getConnectionPolicy via binder int policy = mServiceBinder.getConnectionPolicy(mDevice, mAttributionSource); - Assert.assertEquals("Setting device policy to POLICY_ALLOWED", - BluetoothProfile.CONNECTION_POLICY_ALLOWED, policy); + Assert.assertEquals( + "Setting device policy to POLICY_ALLOWED", + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + policy); } - /** - * Test if getProfileConnectionPolicy works after the service is stopped. - */ + /** Test if getProfileConnectionPolicy works after the service is stopped. */ @Test public void testGetPolicyAfterStopped() { mService.stop(); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device policy", + Assert.assertEquals( + "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mService.getConnectionPolicy(mDevice)); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testOkToConnect() { int badPolicyValue = 1024; int badBondState = 42; - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_NONE, badPolicyValue, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDING, badPolicyValue, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testOkToConnectCase(mDevice, - BluetoothDevice.BOND_BONDED, badPolicyValue, false); - testOkToConnectCase(mDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mDevice, - badBondState, badPolicyValue, false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mDevice, BluetoothDevice.BOND_NONE, badPolicyValue, false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mDevice, BluetoothDevice.BOND_BONDING, badPolicyValue, false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testOkToConnectCase(mDevice, BluetoothDevice.BOND_BONDED, badPolicyValue, false); + testOkToConnectCase( + mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testOkToConnectCase( + mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); + testOkToConnectCase( + mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase(mDevice, badBondState, badPolicyValue, false); } - /** - * Test that an outgoing connection to device that does not have HAS UUID is rejected - */ + /** Test that an outgoing connection to device that does not have HAS UUID is rejected */ @Test public void testOutgoingConnectMissingHasUuid() { // Update the device policy so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHapClient(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); // Return No UUID - doReturn(new ParcelUuid[]{}).when(mAdapterService) + doReturn(new ParcelUuid[] {}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request Assert.assertFalse("Connect expected to fail", mService.connect(mDevice)); } - /** - * Test that an outgoing connection to device that have HAS UUID is successful - */ + /** Test that an outgoing connection to device that have HAS UUID is successful */ @Test public void testOutgoingConnectExistingHasUuid() { // Update the device policy so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHapClient(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request @@ -355,33 +374,27 @@ public class HapClientTest { verify(mAdapterService, timeout(TIMEOUT_MS)).sendBroadcast(any(), any()); } - /** - * Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected - */ + /** Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected */ @Test public void testOutgoingConnectPolicyForbidden() { doReturn(true).when(mNativeInterface).connectHapClient(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); // Set the device policy to POLICY_FORBIDDEN so connect() should fail - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Send a connect request Assert.assertFalse("Connect expected to fail", mService.connect(mDevice)); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() throws Exception { InOrder order = inOrder(mAdapterService); // Update the device policy so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHapClient(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); @@ -399,8 +412,8 @@ public class HapClientTest { hasExtra(EXTRA_PREVIOUS_STATE, STATE_DISCONNECTED))), any()); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mDevice)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); // Verify the connection state broadcast, and that we are in Disconnected state via binder order.verify(mAdapterService, timeout(HapClientStateMachine.sConnectTimeoutMs * 2)) @@ -417,13 +430,12 @@ public class HapClientTest { Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, state); } - /** - * Test that an outgoing connection to two device that have HAS UUID is successful - */ + /** Test that an outgoing connection to two device that have HAS UUID is successful */ @Test public void testConnectTwo() throws Exception { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request for the 1st device @@ -445,17 +457,17 @@ public class HapClientTest { */ @Test public void testCallsForNotConnectedDevice() { - Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE, + Assert.assertEquals( + BluetoothHapClient.PRESET_INDEX_UNAVAILABLE, mService.getActivePresetIndex(mDevice)); } - /** - * Test getting HAS coordinated sets. - */ + /** Test getting HAS coordinated sets. */ @Test public void testGetHapGroupCoordinatedOps() throws Exception { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); testConnectingDevice(order, mDevice2); @@ -483,39 +495,36 @@ public class HapClientTest { Assert.assertEquals(2, hapGroup); } - /** - * Test that selectPreset properly calls the native method. - */ + /** Test that selectPreset properly calls the native method. */ @Test public void testSelectPresetNative() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); // Verify Native Interface call mService.selectPreset(mDevice, 0x00); - verify(mNativeInterface, times(0)) - .selectActivePreset(eq(mDevice), eq(0x00)); + verify(mNativeInterface, times(0)).selectActivePreset(eq(mDevice), eq(0x00)); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetSelectionFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onPresetSelectionFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mServiceBinder.selectPreset(mDevice, 0x01, mAttributionSource); - verify(mNativeInterface, times(1)) - .selectActivePreset(eq(mDevice), eq(0x01)); + verify(mNativeInterface, times(1)).selectActivePreset(eq(mDevice), eq(0x01)); } - /** - * Test that groupSelectActivePreset properly calls the native method. - */ + /** Test that groupSelectActivePreset properly calls the native method. */ @Test public void testGroupSelectActivePresetNative() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice3); @@ -525,40 +534,37 @@ public class HapClientTest { // Verify Native Interface call mService.selectPresetForGroup(0x03, 0x00); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetSelectionForGroupFailed( - eq(0x03), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onPresetSelectionForGroupFailed( + eq(0x03), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mServiceBinder.selectPresetForGroup(0x03, 0x01, mAttributionSource); - verify(mNativeInterface, times(1)) - .groupSelectActivePreset(eq(0x03), eq(0x01)); + verify(mNativeInterface, times(1)).groupSelectActivePreset(eq(0x03), eq(0x01)); } - /** - * Test that nextActivePreset properly calls the native method. - */ + /** Test that nextActivePreset properly calls the native method. */ @Test public void testSwitchToNextPreset() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); // Verify Native Interface call mServiceBinder.switchToNextPreset(mDevice, mAttributionSource); - verify(mNativeInterface, times(1)) - .nextActivePreset(eq(mDevice)); + verify(mNativeInterface, times(1)).nextActivePreset(eq(mDevice)); } - /** - * Test that groupNextActivePreset properly calls the native method. - */ + /** Test that groupNextActivePreset properly calls the native method. */ @Test public void testSwitchToNextPresetForGroup() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice3); int flags = 0x01; @@ -569,29 +575,26 @@ public class HapClientTest { verify(mNativeInterface, times(1)).groupNextActivePreset(eq(0x03)); } - /** - * Test that previousActivePreset properly calls the native method. - */ + /** Test that previousActivePreset properly calls the native method. */ @Test public void testSwitchToPreviousPreset() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); // Verify Native Interface call mServiceBinder.switchToPreviousPreset(mDevice, mAttributionSource); - verify(mNativeInterface, times(1)) - .previousActivePreset(eq(mDevice)); + verify(mNativeInterface, times(1)).previousActivePreset(eq(mDevice)); } - /** - * Test that groupPreviousActivePreset properly calls the native method. - */ + /** Test that groupPreviousActivePreset properly calls the native method. */ @Test public void testSwitchToPreviousPresetForGroup() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); testConnectingDevice(order, mDevice2); @@ -604,13 +607,12 @@ public class HapClientTest { verify(mNativeInterface, times(1)).groupPreviousActivePreset(eq(0x02)); } - /** - * Test that getActivePresetIndex returns cached value. - */ + /** Test that getActivePresetIndex returns cached value. */ @Test public void testGetActivePresetIndex() throws Exception { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); testOnPresetSelected(mDevice, 0x01); @@ -620,13 +622,12 @@ public class HapClientTest { Assert.assertEquals(0x01, presetIndex); } - /** - * Test that getActivePresetInfo returns cached value for valid parameters. - */ + /** Test that getActivePresetInfo returns cached value for valid parameters. */ @Test public void testGetPresetInfoAndActivePresetInfo() throws Exception { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice2); @@ -639,7 +640,8 @@ public class HapClientTest { Assert.assertTrue(presetList.contains(presetInfo)); Assert.assertEquals(0x01, presetInfo.getIndex()); - Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE, + Assert.assertEquals( + BluetoothHapClient.PRESET_INDEX_UNAVAILABLE, mService.getActivePresetIndex(mDevice2)); Assert.assertEquals(null, mService.getActivePresetInfo(mDevice2)); @@ -654,13 +656,12 @@ public class HapClientTest { Assert.assertEquals("One", info.getName()); } - /** - * Test that setPresetName properly calls the native method for the valid parameters. - */ + /** Test that setPresetName properly calls the native method for the valid parameters. */ @Test public void testSetPresetNameNative() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(order, mDevice); @@ -668,8 +669,9 @@ public class HapClientTest { verify(mNativeInterface, times(0)) .setPresetName(eq(mDevice), eq(0x00), eq("ExamplePresetName")); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -686,7 +688,8 @@ public class HapClientTest { @Test public void testSetPresetNameForGroup() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); int test_group = 0x02; for (BluetoothDevice device : mCsipService.getGroupDevicesOrdered(test_group)) { @@ -699,16 +702,19 @@ public class HapClientTest { mServiceBinder.setPresetNameForGroup( test_group, 0x00, "ExamplePresetName", mAttributionSource); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(eq(test_group), - eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameForGroupFailed( + eq(test_group), + eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mService.setPresetNameForGroup(-1, 0x01, "ExamplePresetName"); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(eq(-1), - eq(BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameForGroupFailed( + eq(-1), eq(BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -719,17 +725,14 @@ public class HapClientTest { .groupSetPresetName(eq(test_group), eq(0x01), eq("ExamplePresetName")); } - /** - * Test that native callback generates proper intent. - */ + /** Test that native callback generates proper intent. */ @Test public void testStackEventDeviceAvailable() { - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - doCallRealMethod() - .when(mNativeInterface) - .onDeviceAvailable(any(byte[].class), anyInt()); + doCallRealMethod().when(mNativeInterface).onDeviceAvailable(any(byte[].class), anyInt()); mNativeInterface.onDeviceAvailable(getByteAddress(mDevice), 0x03); verify(mAdapterService, timeout(TIMEOUT_MS)) @@ -742,12 +745,11 @@ public class HapClientTest { any()); } - /** - * Test that native callback generates proper callback call. - */ + /** Test that native callback generates proper callback call. */ @Test public void testStackEventOnPresetSelected() { - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doCallRealMethod() @@ -756,8 +758,11 @@ public class HapClientTest { mNativeInterface.onActivePresetSelected(getByteAddress(mDevice), 0x01); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetSelected(eq(mDevice), - eq(0x01), eq(BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onPresetSelected( + eq(mDevice), + eq(0x01), + eq(BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -766,15 +771,13 @@ public class HapClientTest { Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice)); } - /** - * Test that native callback generates proper callback call. - */ + /** Test that native callback generates proper callback call. */ @Test public void testStackEventOnActivePresetSelectError() { - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - doCallRealMethod() .when(mNativeInterface) .onActivePresetSelectError(any(byte[].class), anyInt()); @@ -782,126 +785,132 @@ public class HapClientTest { mNativeInterface.onActivePresetSelectError(getByteAddress(mDevice), 0x05); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetSelectionFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onPresetSelectionFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } - /** - * Test that native callback generates proper callback call. - */ + /** Test that native callback generates proper callback call. */ @Test public void testStackEventOnPresetInfo() { InOrder order = inOrder(mAdapterService); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Connect and inject initial presets testConnectingDevice(order, mDevice); int info_reason = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE; - BluetoothHapPresetInfo[] info = - {new BluetoothHapPresetInfo.Builder(0x01, "OneChangedToUnavailable") - .setWritable(true) - .setAvailable(false) - .build()}; - - doCallRealMethod() - .when(mNativeInterface) - .onPresetInfo(any(byte[].class), anyInt(), any()); + BluetoothHapPresetInfo[] info = { + new BluetoothHapPresetInfo.Builder(0x01, "OneChangedToUnavailable") + .setWritable(true) + .setAvailable(false) + .build() + }; + + doCallRealMethod().when(mNativeInterface).onPresetInfo(any(byte[].class), anyInt(), any()); mNativeInterface.onPresetInfo(getByteAddress(mDevice), info_reason, info); ArgumentCaptor> presetsCaptor = ArgumentCaptor.forClass(List.class); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetInfoChanged(eq(mDevice), - presetsCaptor.capture(), eq(BluetoothStatusCodes.REASON_REMOTE_REQUEST)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onPresetInfoChanged( + eq(mDevice), + presetsCaptor.capture(), + eq(BluetoothStatusCodes.REASON_REMOTE_REQUEST)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } List presets = presetsCaptor.getValue(); Assert.assertEquals(3, presets.size()); - Optional preset = presetsCaptor.getValue() - .stream() - .filter(p -> 0x01 == p.getIndex()) - .findFirst(); + Optional preset = + presetsCaptor.getValue().stream().filter(p -> 0x01 == p.getIndex()).findFirst(); Assert.assertEquals("OneChangedToUnavailable", preset.get().getName()); Assert.assertFalse(preset.get().isAvailable()); Assert.assertTrue(preset.get().isWritable()); } - /** - * Test that native callback generates proper callback call. - */ + /** Test that native callback generates proper callback call. */ @Test public void testStackEventOnPresetNameSetError() { - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doCallRealMethod() .when(mNativeInterface) .onPresetNameSetError(any(byte[].class), anyInt(), anyInt()); /* Not a valid name length */ - mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01, + mNativeInterface.onPresetNameSetError( + getByteAddress(mDevice), + 0x01, HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Invalid preset index provided */ - mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01, - HapClientStackEvent.STATUS_INVALID_PRESET_INDEX); + mNativeInterface.onPresetNameSetError( + getByteAddress(mDevice), 0x01, HapClientStackEvent.STATUS_INVALID_PRESET_INDEX); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Not allowed on this particular preset */ - mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01, - HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED); + mNativeInterface.onPresetNameSetError( + getByteAddress(mDevice), 0x01, HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Not allowed on this particular preset at this time, might be possible later on */ - mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01, - HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE); + mNativeInterface.onPresetNameSetError( + getByteAddress(mDevice), 0x01, HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE); try { - verify(mCallback, after(TIMEOUT_MS).times(2)).onSetPresetNameFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED)); + verify(mCallback, after(TIMEOUT_MS).times(2)) + .onSetPresetNameFailed( + eq(mDevice), eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Not allowed on all presets - for example missing characteristic */ - mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01, - HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED); + mNativeInterface.onPresetNameSetError( + getByteAddress(mDevice), 0x01, HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice), - eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameFailed( + eq(mDevice), + eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED)); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } - /** - * Test that native callback generates proper callback call. - */ + /** Test that native callback generates proper callback call. */ @Test public void testStackEventOnGroupPresetNameSetError() { - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doCallRealMethod() @@ -909,53 +918,58 @@ public class HapClientTest { .onGroupPresetNameSetError(anyInt(), anyInt(), anyInt()); /* Not a valid name length */ - mNativeInterface.onGroupPresetNameSetError(0x01, 0x01, - HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH); + mNativeInterface.onGroupPresetNameSetError( + 0x01, 0x01, HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01, - BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameForGroupFailed( + 0x01, BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Invalid preset index provided */ - mNativeInterface.onGroupPresetNameSetError(0x01, 0x01, - HapClientStackEvent.STATUS_INVALID_PRESET_INDEX); + mNativeInterface.onGroupPresetNameSetError( + 0x01, 0x01, HapClientStackEvent.STATUS_INVALID_PRESET_INDEX); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01, - BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameForGroupFailed( + 0x01, BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Not allowed on this particular preset */ - mNativeInterface.onGroupPresetNameSetError(0x01, 0x01, - HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED); + mNativeInterface.onGroupPresetNameSetError( + 0x01, 0x01, HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01, - BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameForGroupFailed( + 0x01, BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Not allowed on this particular preset at this time, might be possible later on */ - mNativeInterface.onGroupPresetNameSetError(0x01, 0x01, - HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE); + mNativeInterface.onGroupPresetNameSetError( + 0x01, 0x01, HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE); try { - verify(mCallback, after(TIMEOUT_MS).times(2)).onSetPresetNameForGroupFailed(0x01, - BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED); + verify(mCallback, after(TIMEOUT_MS).times(2)) + .onSetPresetNameForGroupFailed( + 0x01, BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } /* Not allowed on all presets - for example if peer is missing optional CP characteristic */ - mNativeInterface.onGroupPresetNameSetError(0x01, 0x01, - HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED); + mNativeInterface.onGroupPresetNameSetError( + 0x01, 0x01, HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01, - BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onSetPresetNameForGroupFailed( + 0x01, BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -971,8 +985,11 @@ public class HapClientTest { Assert.assertTrue( mServiceBinder.setConnectionPolicy( mDevice, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mAttributionSource)); - verify(mDatabaseManager).setProfileConnectionPolicy( - mDevice, BluetoothProfile.HAP_CLIENT, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + verify(mDatabaseManager) + .setProfileConnectionPolicy( + mDevice, + BluetoothProfile.HAP_CLIENT, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } @Test @@ -993,19 +1010,18 @@ public class HapClientTest { mServiceBinder.unregisterCallback(callback, mAttributionSource); Assert.assertEquals(size, mService.mCallbacks.getRegisteredCallbackCount()); - } @Test public void testDumpDoesNotCrash() { // Update the device policy so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHapClient(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); - doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HAS}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Add state machine for testing dump() @@ -1016,14 +1032,11 @@ public class HapClientTest { mService.dump(new StringBuilder()); } - /** - * Helper function to test device connecting - */ + /** Helper function to test device connecting */ private void prepareConnectingDevice(BluetoothDevice device) { // Prepare intent queue and all the mocks when(mNativeInterface.getDevice(getByteAddress(device))).thenReturn(device); - when(mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT)) + when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHapClient(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); @@ -1072,7 +1085,7 @@ public class HapClientTest { evt = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); evt.device = device; - evt.valueInt1 = 0x01; // features + evt.valueInt1 = 0x01; // features mService.messageFromNative(evt); order.verify(mAdapterService, timeout(TIMEOUT_MS)) @@ -1091,21 +1104,22 @@ public class HapClientTest { // Inject some initial presets List presets = - new ArrayList(Arrays.asList( - new BluetoothHapPresetInfo.Builder(0x01, "One") - .setAvailable(true) - .setWritable(false) - .build(), - new BluetoothHapPresetInfo.Builder(0x02, "Two") - .setAvailable(true) - .setWritable(true) - .build(), - new BluetoothHapPresetInfo.Builder(0x03, "Three") - .setAvailable(false) - .setWritable(false) - .build())); - mService.updateDevicePresetsCache(device, - HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO, presets); + new ArrayList( + Arrays.asList( + new BluetoothHapPresetInfo.Builder(0x01, "One") + .setAvailable(true) + .setWritable(false) + .build(), + new BluetoothHapPresetInfo.Builder(0x02, "Two") + .setAvailable(true) + .setWritable(true) + .build(), + new BluetoothHapPresetInfo.Builder(0x03, "Three") + .setAvailable(false) + .setWritable(false) + .build())); + mService.updateDevicePresetsCache( + device, HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO, presets); } private void testOnPresetSelected(BluetoothDevice device, int index) { @@ -1116,27 +1130,26 @@ public class HapClientTest { mService.messageFromNative(evt); try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetSelected(eq(device), - eq(evt.valueInt1), eq(BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST)); + verify(mCallback, after(TIMEOUT_MS).times(1)) + .onPresetSelected( + eq(device), + eq(evt.valueInt1), + eq(BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } - /** - * Helper function to test okToConnect() method - */ - private void testOkToConnectCase(BluetoothDevice device, int bondState, int policy, - boolean expected) { + /** Helper function to test okToConnect() method */ + private void testOkToConnectCase( + BluetoothDevice device, int bondState, int policy, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT)) .thenReturn(policy); Assert.assertEquals(expected, mService.okToConnect(device)); } - /** - * Helper function to get byte array for a device address - */ + /** Helper function to get byte array for a device address */ private byte[] getByteAddress(BluetoothDevice device) { if (device == null) { return Utils.getBytesFromAddress("00:00:00:00:00:00"); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java index c730910e334..a49b1d53c5d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java @@ -75,20 +75,20 @@ public class HearingAidNativeInterfaceTest { @Test public void onConnectionStateChanged() { BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - mNativeInterface.onConnectionStateChanged(BluetoothProfile.STATE_CONNECTED, - mNativeInterface.getByteAddress(device)); + mNativeInterface.onConnectionStateChanged( + BluetoothProfile.STATE_CONNECTED, mNativeInterface.getByteAddress(device)); ArgumentCaptor event = ArgumentCaptor.forClass(HearingAidStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); assertThat(event.getValue().valueInt1).isEqualTo(BluetoothProfile.STATE_CONNECTED); Mockito.clearInvocations(mService); HearingAidService.setHearingAidService(null); - mNativeInterface.onConnectionStateChanged(BluetoothProfile.STATE_CONNECTED, - mNativeInterface.getByteAddress(device)); + mNativeInterface.onConnectionStateChanged( + BluetoothProfile.STATE_CONNECTED, mNativeInterface.getByteAddress(device)); verify(mService, never()).messageFromNative(any()); } @@ -97,21 +97,21 @@ public class HearingAidNativeInterfaceTest { BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); byte capabilities = 0; long hiSyncId = 100; - mNativeInterface.onDeviceAvailable(capabilities, hiSyncId, - mNativeInterface.getByteAddress(device)); + mNativeInterface.onDeviceAvailable( + capabilities, hiSyncId, mNativeInterface.getByteAddress(device)); ArgumentCaptor event = ArgumentCaptor.forClass(HearingAidStackEvent.class); verify(mService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + assertThat(event.getValue().type) + .isEqualTo(HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); assertThat(event.getValue().valueInt1).isEqualTo(capabilities); assertThat(event.getValue().valueLong2).isEqualTo(hiSyncId); Mockito.clearInvocations(mService); HearingAidService.setHearingAidService(null); - mNativeInterface.onDeviceAvailable(capabilities, hiSyncId, - mNativeInterface.getByteAddress(device)); + mNativeInterface.onDeviceAvailable( + capabilities, hiSyncId, mNativeInterface.getByteAddress(device)); verify(mService, never()).messageFromNative(any()); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java index f35f6b34359..3c58462a17e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java @@ -74,10 +74,14 @@ public class HearingAidStateMachineTest { // Set up thread and looper mHandlerThread = new HandlerThread("HearingAidStateMachineTestHandlerThread"); mHandlerThread.start(); - mHearingAidStateMachine = new HearingAidStateMachine(mTestDevice, mHearingAidService, - mHearingAidNativeInterface, mHandlerThread.getLooper()); + mHearingAidStateMachine = + new HearingAidStateMachine( + mTestDevice, + mHearingAidService, + mHearingAidNativeInterface, + mHandlerThread.getLooper()); // Override the timeout value to speed up the test - mHearingAidStateMachine.sConnectTimeoutMs = 1000; // 1s + mHearingAidStateMachine.sConnectTimeoutMs = 1000; // 1s mHearingAidStateMachine.start(); } @@ -88,13 +92,11 @@ public class HearingAidStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mHearingAidStateMachine.getConnectionState()); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mHearingAidStateMachine.getConnectionState()); } /** @@ -106,9 +108,7 @@ public class HearingAidStateMachineTest { doReturn(allow).when(mHearingAidService).okToConnect(any(BluetoothDevice.class)); } - /** - * Test that an incoming connection with low priority is rejected - */ + /** Test that an incoming connection with low priority is rejected */ @Test public void testIncomingPriorityReject() { allowConnection(false); @@ -121,16 +121,15 @@ public class HearingAidStateMachineTest { mHearingAidStateMachine.sendMessage(HearingAidStateMachine.STACK_EVENT, connStCh); // Verify that no connection state broadcast is executed - verify(mHearingAidService, after(TIMEOUT_MS).never()).sendBroadcast(any(Intent.class), - anyString(), any(Bundle.class)); + verify(mHearingAidService, after(TIMEOUT_MS).never()) + .sendBroadcast(any(Intent.class), anyString(), any(Bundle.class)); // Check that we are in Disconnected state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Disconnected.class)); } - /** - * Test that an incoming connection with high priority is accepted - */ + /** Test that an incoming connection with high priority is accepted */ @Test public void testIncomingPriorityAccept() { allowConnection(true); @@ -144,13 +143,15 @@ public class HearingAidStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mHearingAidService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mHearingAidService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Connecting.class)); // Send a message to trigger connection completed @@ -163,23 +164,24 @@ public class HearingAidStateMachineTest { // Verify that the expected number of broadcasts are executed: // - two calls to broadcastConnectionState(): Disconnected -> Conecting -> Connected ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)).sendBroadcast( - intentArgument2.capture(), anyString(), any(Bundle.class)); + verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); // Check that we are in Connected state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Connected.class)); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingTimeout() { allowConnection(true); - doReturn(true).when(mHearingAidNativeInterface).connectHearingAid(any( - BluetoothDevice.class)); - doReturn(true).when(mHearingAidNativeInterface).disconnectHearingAid(any( - BluetoothDevice.class)); + doReturn(true) + .when(mHearingAidNativeInterface) + .connectHearingAid(any(BluetoothDevice.class)); + doReturn(true) + .when(mHearingAidNativeInterface) + .disconnectHearingAid(any(BluetoothDevice.class)); when(mHearingAidService.isConnectedPeerDevices(mTestDevice)).thenReturn(true); // Send a connect request @@ -187,40 +189,42 @@ public class HearingAidStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mHearingAidService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), - anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mHearingAidService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHearingAidService, timeout(HearingAidStateMachine.sConnectTimeoutMs * 2).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString(), - any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + verify(mHearingAidService, timeout(HearingAidStateMachine.sConnectTimeoutMs * 2).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Disconnected state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Disconnected.class)); verify(mHearingAidNativeInterface).addToAcceptlist(eq(mTestDevice)); } - /** - * Test that an incoming connection times out - */ + /** Test that an incoming connection times out */ @Test public void testIncomingTimeout() { allowConnection(true); - doReturn(true).when(mHearingAidNativeInterface).connectHearingAid(any( - BluetoothDevice.class)); - doReturn(true).when(mHearingAidNativeInterface).disconnectHearingAid(any( - BluetoothDevice.class)); + doReturn(true) + .when(mHearingAidNativeInterface) + .connectHearingAid(any(BluetoothDevice.class)); + doReturn(true) + .when(mHearingAidNativeInterface) + .disconnectHearingAid(any(BluetoothDevice.class)); when(mHearingAidService.isConnectedPeerDevices(mTestDevice)).thenReturn(true); // Inject an event for when incoming connection is requested @@ -232,26 +236,28 @@ public class HearingAidStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); - verify(mHearingAidService, timeout(TIMEOUT_MS).times(1)).sendBroadcast( - intentArgument1.capture(), - anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify(mHearingAidService, timeout(TIMEOUT_MS).times(1)) + .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Connecting state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHearingAidService, timeout(HearingAidStateMachine.sConnectTimeoutMs * 2).times( - 2)).sendBroadcast(intentArgument2.capture(), anyString(), - any(Bundle.class)); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + verify(mHearingAidService, timeout(HearingAidStateMachine.sConnectTimeoutMs * 2).times(2)) + .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check that we are in Disconnected state - Assert.assertThat(mHearingAidStateMachine.getCurrentState(), + Assert.assertThat( + mHearingAidStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HearingAidStateMachine.Disconnected.class)); verify(mHearingAidNativeInterface).addToAcceptlist(eq(mTestDevice)); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java index 1ca0830d79e..78a838fffeb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java @@ -67,8 +67,7 @@ public class AtPhonebookTest { @Mock private HeadsetNativeInterface mNativeInterface; private AtPhonebook mAtPhonebook; - @Spy - private BluetoothMethodProxy mHfpMethodProxy = BluetoothMethodProxy.getInstance(); + @Spy private BluetoothMethodProxy mHfpMethodProxy = BluetoothMethodProxy.getInstance(); @Before public void setUp() throws Exception { @@ -90,8 +89,8 @@ public class AtPhonebookTest { @Test public void checkAccessPermission_returnsCorrectPermission() { - assertThat(mAtPhonebook.checkAccessPermission(mTestDevice)).isEqualTo( - BluetoothDevice.ACCESS_UNKNOWN); + assertThat(mAtPhonebook.checkAccessPermission(mTestDevice)) + .isEqualTo(BluetoothDevice.ACCESS_UNKNOWN); } @Test @@ -104,28 +103,33 @@ public class AtPhonebookTest { @Test public void handleCscsCommand() { mAtPhonebook.handleCscsCommand(INVALID_COMMAND, AtPhonebook.TYPE_READ, mTestDevice); - verify(mNativeInterface).atResponseString(mTestDevice, - "+CSCS: \"" + "UTF-8" + "\""); + verify(mNativeInterface).atResponseString(mTestDevice, "+CSCS: \"" + "UTF-8" + "\""); mAtPhonebook.handleCscsCommand(INVALID_COMMAND, AtPhonebook.TYPE_TEST, mTestDevice); - verify(mNativeInterface).atResponseString(mTestDevice, - "+CSCS: (\"UTF-8\",\"IRA\",\"GSM\")"); + verify(mNativeInterface) + .atResponseString(mTestDevice, "+CSCS: (\"UTF-8\",\"IRA\",\"GSM\")"); mAtPhonebook.handleCscsCommand(INVALID_COMMAND, AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface, atLeastOnce()).atResponseCode(mTestDevice, - HeadsetHalConstants.AT_RESPONSE_ERROR, -1); + verify(mNativeInterface, atLeastOnce()) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, -1); mAtPhonebook.handleCscsCommand("command=GSM", AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface, atLeastOnce()).atResponseCode(mTestDevice, - HeadsetHalConstants.AT_RESPONSE_OK, -1); + verify(mNativeInterface, atLeastOnce()) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, -1); mAtPhonebook.handleCscsCommand("command=ERR", AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.OPERATION_NOT_SUPPORTED); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.OPERATION_NOT_SUPPORTED); mAtPhonebook.handleCscsCommand(INVALID_COMMAND, AtPhonebook.TYPE_UNKNOWN, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.TEXT_HAS_INVALID_CHARS); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.TEXT_HAS_INVALID_CHARS); } @Test @@ -133,28 +137,37 @@ public class AtPhonebookTest { mAtPhonebook.handleCpbsCommand(INVALID_COMMAND, AtPhonebook.TYPE_READ, mTestDevice); int size = mAtPhonebook.getPhonebookResult("ME", true).cursor.getCount(); int maxSize = mAtPhonebook.getMaxPhoneBookSize(size); - verify(mNativeInterface).atResponseString(mTestDevice, - "+CPBS: \"" + "ME" + "\"," + size + "," + maxSize); + verify(mNativeInterface) + .atResponseString(mTestDevice, "+CPBS: \"" + "ME" + "\"," + size + "," + maxSize); mAtPhonebook.handleCpbsCommand(INVALID_COMMAND, AtPhonebook.TYPE_TEST, mTestDevice); - verify(mNativeInterface).atResponseString(mTestDevice, - "+CPBS: (\"ME\",\"SM\",\"DC\",\"RC\",\"MC\")"); + verify(mNativeInterface) + .atResponseString(mTestDevice, "+CPBS: (\"ME\",\"SM\",\"DC\",\"RC\",\"MC\")"); mAtPhonebook.handleCpbsCommand(INVALID_COMMAND, AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.OPERATION_NOT_SUPPORTED); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.OPERATION_NOT_SUPPORTED); mAtPhonebook.handleCpbsCommand("command=ERR", AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.OPERATION_NOT_ALLOWED); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.OPERATION_NOT_ALLOWED); mAtPhonebook.handleCpbsCommand("command=SM", AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface, atLeastOnce()).atResponseCode(mTestDevice, - HeadsetHalConstants.AT_RESPONSE_OK, -1); + verify(mNativeInterface, atLeastOnce()) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, -1); mAtPhonebook.handleCpbsCommand(INVALID_COMMAND, AtPhonebook.TYPE_UNKNOWN, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.TEXT_HAS_INVALID_CHARS); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.TEXT_HAS_INVALID_CHARS); } @Test @@ -165,53 +178,60 @@ public class AtPhonebookTest { size = 1; } verify(mNativeInterface).atResponseString(mTestDevice, "+CPBR: (1-" + size + "),30,30"); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, - -1); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, -1); mAtPhonebook.handleCpbrCommand(INVALID_COMMAND, AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - -1); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, -1); mAtPhonebook.handleCpbrCommand("command=ERR", AtPhonebook.TYPE_SET, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.TEXT_HAS_INVALID_CHARS); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.TEXT_HAS_INVALID_CHARS); mAtPhonebook.handleCpbrCommand("command=123,123", AtPhonebook.TYPE_SET, mTestDevice); assertThat(mAtPhonebook.getCheckingAccessPermission()).isTrue(); mAtPhonebook.handleCpbrCommand(INVALID_COMMAND, AtPhonebook.TYPE_UNKNOWN, mTestDevice); - verify(mNativeInterface, atLeastOnce()).atResponseCode(mTestDevice, - HeadsetHalConstants.AT_RESPONSE_ERROR, BluetoothCmeError.TEXT_HAS_INVALID_CHARS); + verify(mNativeInterface, atLeastOnce()) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.TEXT_HAS_INVALID_CHARS); } @Test public void processCpbrCommand() { mAtPhonebook.handleCpbsCommand("command=SM", AtPhonebook.TYPE_SET, mTestDevice); - assertThat(mAtPhonebook.processCpbrCommand(mTestDevice)).isEqualTo( - HeadsetHalConstants.AT_RESPONSE_OK); + assertThat(mAtPhonebook.processCpbrCommand(mTestDevice)) + .isEqualTo(HeadsetHalConstants.AT_RESPONSE_OK); mAtPhonebook.handleCpbsCommand("command=ME", AtPhonebook.TYPE_SET, mTestDevice); - assertThat(mAtPhonebook.processCpbrCommand(mTestDevice)).isEqualTo( - HeadsetHalConstants.AT_RESPONSE_OK); + assertThat(mAtPhonebook.processCpbrCommand(mTestDevice)) + .isEqualTo(HeadsetHalConstants.AT_RESPONSE_OK); mAtPhonebook.mCurrentPhonebook = "ER"; - assertThat(mAtPhonebook.processCpbrCommand(mTestDevice)).isEqualTo( - HeadsetHalConstants.AT_RESPONSE_ERROR); + assertThat(mAtPhonebook.processCpbrCommand(mTestDevice)) + .isEqualTo(HeadsetHalConstants.AT_RESPONSE_ERROR); } @Test public void processCpbrCommand_withMobilePhonebook() { Cursor mockCursorOne = mock(Cursor.class); when(mockCursorOne.getCount()).thenReturn(1); - when(mockCursorOne.getColumnIndex(Phone.TYPE)).thenReturn(1); //TypeColumn - when(mockCursorOne.getColumnIndex(Phone.NUMBER)).thenReturn(2); //numberColumn + when(mockCursorOne.getColumnIndex(Phone.TYPE)).thenReturn(1); // TypeColumn + when(mockCursorOne.getColumnIndex(Phone.NUMBER)).thenReturn(2); // numberColumn when(mockCursorOne.getColumnIndex(Phone.DISPLAY_NAME)).thenReturn(3); // nameColumn when(mockCursorOne.getInt(1)).thenReturn(Phone.TYPE_WORK); when(mockCursorOne.getString(2)).thenReturn(null); when(mockCursorOne.getString(3)).thenReturn(null); when(mockCursorOne.moveToNext()).thenReturn(false); - doReturn(mockCursorOne).when(mHfpMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any()); + doReturn(mockCursorOne) + .when(mHfpMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any()); mAtPhonebook.mCurrentPhonebook = "ME"; mAtPhonebook.mCpbrIndex1 = 1; @@ -219,8 +239,19 @@ public class AtPhonebookTest { mAtPhonebook.processCpbrCommand(mTestDevice); - String expected = "+CPBR: " + 1 + ",\"" + "" + "\"," + PhoneNumberUtils.toaFromString("") - + ",\"" + "" + "/" + AtPhonebook.getPhoneType(Phone.TYPE_WORK) + "\"" + "\r\n\r\n"; + String expected = + "+CPBR: " + + 1 + + ",\"" + + "" + + "\"," + + PhoneNumberUtils.toaFromString("") + + ",\"" + + "" + + "/" + + AtPhonebook.getPhoneType(Phone.TYPE_WORK) + + "\"" + + "\r\n\r\n"; verify(mNativeInterface).atResponseString(mTestDevice, expected); } @@ -233,16 +264,18 @@ public class AtPhonebookTest { String number = "1".repeat(31); when(mockCursorOne.getString(1)).thenReturn(number); when(mockCursorOne.getInt(2)).thenReturn(CallLog.Calls.PRESENTATION_RESTRICTED); - doReturn(mockCursorOne).when(mHfpMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any()); + doReturn(mockCursorOne) + .when(mHfpMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any()); Cursor mockCursorTwo = mock(Cursor.class); when(mockCursorTwo.moveToFirst()).thenReturn(true); String name = "k".repeat(30); when(mockCursorTwo.getString(0)).thenReturn(name); when(mockCursorTwo.getInt(1)).thenReturn(1); - doReturn(mockCursorTwo).when(mHfpMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any(), any()); + doReturn(mockCursorTwo) + .when(mHfpMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mAtPhonebook.mCurrentPhonebook = "MC"; mAtPhonebook.mCpbrIndex1 = 1; @@ -250,9 +283,17 @@ public class AtPhonebookTest { mAtPhonebook.processCpbrCommand(mTestDevice); - String expected = "+CPBR: " + 1 + ",\"" + "" + "\"," + PhoneNumberUtils.toaFromString( - number) + ",\"" + mTargetContext.getString(R.string.unknownNumber) + "\"" - + "\r\n\r\n"; + String expected = + "+CPBR: " + + 1 + + ",\"" + + "" + + "\"," + + PhoneNumberUtils.toaFromString(number) + + ",\"" + + mTargetContext.getString(R.string.unknownNumber) + + "\"" + + "\r\n\r\n"; verify(mNativeInterface).atResponseString(mTestDevice, expected); } @@ -265,16 +306,18 @@ public class AtPhonebookTest { String number = "1".repeat(31); when(mockCursorOne.getString(1)).thenReturn(number); when(mockCursorOne.getInt(2)).thenReturn(CallLog.Calls.PRESENTATION_RESTRICTED); - doReturn(mockCursorOne).when(mHfpMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any()); + doReturn(mockCursorOne) + .when(mHfpMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any()); Cursor mockCursorTwo = mock(Cursor.class); when(mockCursorTwo.moveToFirst()).thenReturn(true); String name = "k".repeat(30); when(mockCursorTwo.getString(0)).thenReturn(name); when(mockCursorTwo.getInt(1)).thenReturn(1); - doReturn(mockCursorTwo).when(mHfpMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any(), any()); + doReturn(mockCursorTwo) + .when(mHfpMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mAtPhonebook.mCurrentPhonebook = "RC"; mAtPhonebook.mCpbrIndex1 = 1; @@ -284,8 +327,17 @@ public class AtPhonebookTest { mAtPhonebook.processCpbrCommand(mTestDevice); String expectedName = new String(GsmAlphabet.stringToGsm8BitPacked(name.substring(0, 28))); - String expected = "+CPBR: " + 1 + ",\"" + number.substring(0, 30) + "\"," - + PhoneNumberUtils.toaFromString(number) + ",\"" + expectedName + "\"" + "\r\n\r\n"; + String expected = + "+CPBR: " + + 1 + + ",\"" + + number.substring(0, 30) + + "\"," + + PhoneNumberUtils.toaFromString(number) + + ",\"" + + expectedName + + "\"" + + "\r\n\r\n"; verify(mNativeInterface).atResponseString(mTestDevice, expected); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java index 3034d5edb37..a97c4f15db1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java @@ -35,8 +35,7 @@ public class BluetoothHeadsetBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private HeadsetService mService; + @Mock private HeadsetService mService; private AttributionSource mAttributionSource; private BluetoothDevice mTestDevice; @@ -70,7 +69,7 @@ public class BluetoothHeadsetBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] { BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource); verify(mService).getDevicesMatchingConnectionStates(states); } @@ -190,7 +189,7 @@ public class BluetoothHeadsetBinderTest { String name = "Unknown"; mBinder.phoneStateChanged( numActive, numHeld, callState, number, type, name, mAttributionSource); - verify(mService).phoneStateChanged( - numActive, numHeld, callState, number, type, name, false); + verify(mService) + .phoneStateChanged(numActive, numHeld, callState, number, type, name, false); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java index 5c2850472ea..f034bf44cf9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java @@ -30,8 +30,8 @@ public class HeadsetAgIndicatorEnableStateTest { @Test public void hashCode_returnsCorrectResult() { - HeadsetAgIndicatorEnableState state = new HeadsetAgIndicatorEnableState(true, true, true, - true); + HeadsetAgIndicatorEnableState state = + new HeadsetAgIndicatorEnableState(true, true, true, true); assertThat(state.hashCode()).isEqualTo(15); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java index 9e5788afe52..3f6603ff3af 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java @@ -37,8 +37,15 @@ public class HeadsetClccResponseTest { @Test public void constructor() { - HeadsetClccResponse response = new HeadsetClccResponse(TEST_INDEX, TEST_DIRECTION, - TEST_STATUS, TEST_MODE, TEST_MPTY, TEST_NUMBER, TEST_TYPE); + HeadsetClccResponse response = + new HeadsetClccResponse( + TEST_INDEX, + TEST_DIRECTION, + TEST_STATUS, + TEST_MODE, + TEST_MPTY, + TEST_NUMBER, + TEST_TYPE); assertThat(response.mIndex).isEqualTo(TEST_INDEX); assertThat(response.mDirection).isEqualTo(TEST_DIRECTION); @@ -51,33 +58,71 @@ public class HeadsetClccResponseTest { @Test public void buildString() { - HeadsetClccResponse response = new HeadsetClccResponse(TEST_INDEX, TEST_DIRECTION, - TEST_STATUS, TEST_MODE, TEST_MPTY, TEST_NUMBER, TEST_TYPE); + HeadsetClccResponse response = + new HeadsetClccResponse( + TEST_INDEX, + TEST_DIRECTION, + TEST_STATUS, + TEST_MODE, + TEST_MPTY, + TEST_NUMBER, + TEST_TYPE); StringBuilder builder = new StringBuilder(); response.buildString(builder); String expectedString = - response.getClass().getSimpleName() + "[index=" + TEST_INDEX + ", direction=" - + TEST_DIRECTION + ", status=" + TEST_STATUS + ", callMode=" + TEST_MODE - + ", isMultiParty=" + TEST_MPTY + ", number=" + "***" + ", type=" - + TEST_TYPE + "]"; + response.getClass().getSimpleName() + + "[index=" + + TEST_INDEX + + ", direction=" + + TEST_DIRECTION + + ", status=" + + TEST_STATUS + + ", callMode=" + + TEST_MODE + + ", isMultiParty=" + + TEST_MPTY + + ", number=" + + "***" + + ", type=" + + TEST_TYPE + + "]"; assertThat(response.toString()).isEqualTo(expectedString); } @Test public void buildString_withNoNumber() { - HeadsetClccResponse response = new HeadsetClccResponse(TEST_INDEX, TEST_DIRECTION, - TEST_STATUS, TEST_MODE, TEST_MPTY, null, TEST_TYPE); + HeadsetClccResponse response = + new HeadsetClccResponse( + TEST_INDEX, + TEST_DIRECTION, + TEST_STATUS, + TEST_MODE, + TEST_MPTY, + null, + TEST_TYPE); StringBuilder builder = new StringBuilder(); response.buildString(builder); String expectedString = - response.getClass().getSimpleName() + "[index=" + TEST_INDEX + ", direction=" - + TEST_DIRECTION + ", status=" + TEST_STATUS + ", callMode=" + TEST_MODE - + ", isMultiParty=" + TEST_MPTY + ", number=" + "null" + ", type=" - + TEST_TYPE + "]"; + response.getClass().getSimpleName() + + "[index=" + + TEST_INDEX + + ", direction=" + + TEST_DIRECTION + + ", status=" + + TEST_STATUS + + ", callMode=" + + TEST_MODE + + ", isMultiParty=" + + TEST_MPTY + + ", number=" + + "null" + + ", type=" + + TEST_TYPE + + "]"; assertThat(response.toString()).isEqualTo(expectedString); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java index 2fb01939b7f..7a9c409fb3c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java @@ -48,9 +48,7 @@ import org.mockito.junit.MockitoRule; import java.util.HashMap; -/** - * Unit test to verify various methods in {@link HeadsetPhoneState} - */ +/** Unit test to verify various methods in {@link HeadsetPhoneState} */ @MediumTest @RunWith(AndroidJUnit4.class) public class HeadsetPhoneStateTest { @@ -81,18 +79,18 @@ public class HeadsetPhoneStateTest { when(mISubBinder.queryLocalInterface(anyString())).thenReturn(mISub); mServiceManagerMockedServices.put("isub", mISubBinder); mServiceManagerOriginalServices = - TestUtils.replaceField(ServiceManager.class, "sCache", null, - mServiceManagerMockedServices); + TestUtils.replaceField( + ServiceManager.class, "sCache", null, mServiceManagerMockedServices); // Stub other methods - when(mHeadsetService.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn( - mTelephonyManager); - when(mHeadsetService.getSystemServiceName(TelephonyManager.class)).thenReturn( - Context.TELEPHONY_SERVICE); + when(mHeadsetService.getSystemService(Context.TELEPHONY_SERVICE)) + .thenReturn(mTelephonyManager); + when(mHeadsetService.getSystemServiceName(TelephonyManager.class)) + .thenReturn(Context.TELEPHONY_SERVICE); when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); - when(mHeadsetService.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)).thenReturn( - mSubscriptionManager); - when(mHeadsetService.getSystemServiceName(SubscriptionManager.class)).thenReturn( - Context.TELEPHONY_SUBSCRIPTION_SERVICE); + when(mHeadsetService.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)) + .thenReturn(mSubscriptionManager); + when(mHeadsetService.getSystemServiceName(SubscriptionManager.class)) + .thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE); mHandlerThread = new HandlerThread("HeadsetStateMachineTestHandlerThread"); mHandlerThread.start(); when(mHeadsetService.getStateMachinesThreadLooper()).thenReturn(mHandlerThread.getLooper()); @@ -104,16 +102,14 @@ public class HeadsetPhoneStateTest { mHeadsetPhoneState.cleanup(); mHandlerThread.quit(); if (mServiceManagerOriginalServices != null) { - TestUtils.replaceField(ServiceManager.class, "sCache", null, - mServiceManagerOriginalServices); + TestUtils.replaceField( + ServiceManager.class, "sCache", null, mServiceManagerOriginalServices); mServiceManagerOriginalServices = null; } TelephonyManager.enableServiceHandleCaching(); } - /** - * Verify that {@link PhoneStateListener#LISTEN_NONE} should result in no subscription - */ + /** Verify that {@link PhoneStateListener#LISTEN_NONE} should result in no subscription */ @Test public void testListenForPhoneState_NoneResultsNoListen() { BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1); @@ -130,25 +126,30 @@ public class HeadsetPhoneStateTest { BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1); mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - verify(mTelephonyManager).clearSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager) + .clearSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); verifyNoMoreInteractions(mTelephonyManager); } /** - * Verify that {@link PhoneStateListener#LISTEN_SERVICE_STATE} and - * {@link PhoneStateListener#LISTEN_SIGNAL_STRENGTHS} should result in corresponding - * subscription + * Verify that {@link PhoneStateListener#LISTEN_SERVICE_STATE} and {@link + * PhoneStateListener#LISTEN_SIGNAL_STRENGTHS} should result in corresponding subscription */ @Test public void testListenForPhoneState_ServiceAndSignalStrength() { BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1); - mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); - verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); - verify(mTelephonyManager).setSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + mHeadsetPhoneState.listenForPhoneState( + device1, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + verify(mTelephonyManager) + .listen( + any(), + eq( + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); + verify(mTelephonyManager) + .setSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); } /** @@ -158,37 +159,47 @@ public class HeadsetPhoneStateTest { @Test public void testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffSignalStrengh() { BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1); - mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); - verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); - verify(mTelephonyManager).setSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + mHeadsetPhoneState.listenForPhoneState( + device1, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + verify(mTelephonyManager) + .listen( + any(), + eq( + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); + verify(mTelephonyManager) + .setSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - verify(mTelephonyManager, times(2)).clearSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager, times(2)) + .clearSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); } - /** - * Verify that completely disabling all updates should unsubscribe from everything - */ + /** Verify that completely disabling all updates should unsubscribe from everything */ @Test public void testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffAll() { BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1); - mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); - verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); - verify(mTelephonyManager).setSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + mHeadsetPhoneState.listenForPhoneState( + device1, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + verify(mTelephonyManager) + .listen( + any(), + eq( + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); + verify(mTelephonyManager) + .setSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - verify(mTelephonyManager, times(2)).clearSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager, times(2)) + .clearSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); } /** @@ -201,23 +212,31 @@ public class HeadsetPhoneStateTest { BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1); BluetoothDevice device2 = TestUtils.getTestDevice(mAdapter, 2); // Enabling updates from first device should trigger subscription - mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); - verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); - verify(mTelephonyManager).setSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + mHeadsetPhoneState.listenForPhoneState( + device1, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + verify(mTelephonyManager) + .listen( + any(), + eq( + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); + verify(mTelephonyManager) + .setSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); // Enabling updates from second device should not trigger the same subscription - mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + mHeadsetPhoneState.listenForPhoneState( + device2, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); // Disabling updates from first device should not cancel subscription mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE); // Disabling updates from second device should cancel subscription mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_NONE); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - verify(mTelephonyManager, times(2)).clearSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager, times(2)) + .clearSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); } /** @@ -232,27 +251,29 @@ public class HeadsetPhoneStateTest { // Partially enabling updates from first device should trigger partial subscription mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - verify(mTelephonyManager).clearSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager) + .clearSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); verifyNoMoreInteractions(mTelephonyManager); // Partially enabling updates from second device should trigger partial subscription - mHeadsetPhoneState.listenForPhoneState(device2, - PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); - verify(mTelephonyManager).setSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager) + .listen( + any(), + eq( + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); + verify(mTelephonyManager) + .setSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); // Partially disabling updates from first device should not cancel all subscription mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE); verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - verify(mTelephonyManager).listen( - any(), eq(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); + verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)); // Partially disabling updates from second device should cancel subscription mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_NONE); verify(mTelephonyManager, times(3)).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - verify(mTelephonyManager, times(4)).clearSignalStrengthUpdateRequest( - any(SignalStrengthUpdateRequest.class)); + verify(mTelephonyManager, times(4)) + .clearSignalStrengthUpdateRequest(any(SignalStrengthUpdateRequest.class)); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java index b0016203f90..2d3e4cd9371 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java @@ -39,8 +39,9 @@ public class HeadsetStackEventTest { HeadsetStackEvent event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_NONE, device); assertThat(event.getTypeString()).isEqualTo("EVENT_TYPE_NONE"); - event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - device); + event = + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, device); assertThat(event.getTypeString()).isEqualTo("EVENT_TYPE_CONNECTION_STATE_CHANGED"); event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, device); @@ -70,8 +71,9 @@ public class HeadsetStackEventTest { event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AT_CHLD, device); assertThat(event.getTypeString()).isEqualTo("EVENT_TYPE_AT_CHLD"); - event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST, - device); + event = + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST, device); assertThat(event.getTypeString()).isEqualTo("EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST"); event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AT_CIND, device); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java index 6c09a44c079..602339c9d5f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java @@ -75,9 +75,7 @@ import org.mockito.junit.MockitoRule; import java.util.ArrayList; -/** - * Tests for {@link HeadsetStateMachine} - */ +/** Tests for {@link HeadsetStateMachine} */ @MediumTest @RunWith(AndroidJUnit4.class) public class HeadsetStateMachineTest { @@ -138,29 +136,36 @@ public class HeadsetStateMachineTest { // Stub headset service mMockContentResolver = new MockContentResolver(); when(mHeadsetService.getContentResolver()).thenReturn(mMockContentResolver); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); when(mHeadsetService.bindService(any(Intent.class), any(ServiceConnection.class), anyInt())) .thenReturn(true); - when(mHeadsetService.getResources()).thenReturn( - InstrumentationRegistry.getTargetContext().getResources()); - when(mHeadsetService.getPackageManager()).thenReturn( - InstrumentationRegistry.getContext().getPackageManager()); - when(mHeadsetService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetService.getResources()) + .thenReturn(InstrumentationRegistry.getTargetContext().getResources()); + when(mHeadsetService.getPackageManager()) + .thenReturn(InstrumentationRegistry.getContext().getPackageManager()); + when(mHeadsetService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); when(mHeadsetService.getForceScoAudio()).thenReturn(true); when(mHeadsetService.okToAcceptConnection(any(BluetoothDevice.class), anyBoolean())) .thenReturn(true); - when(mHeadsetService.isScoAcceptable(any(BluetoothDevice.class))).thenReturn( - BluetoothStatusCodes.SUCCESS); + when(mHeadsetService.isScoAcceptable(any(BluetoothDevice.class))) + .thenReturn(BluetoothStatusCodes.SUCCESS); // Setup thread and looper mHandlerThread = new HandlerThread("HeadsetStateMachineTestHandlerThread"); mHandlerThread.start(); // Modify CONNECT timeout to a smaller value for test only HeadsetStateMachine.sConnectTimeoutMs = CONNECT_TIMEOUT_TEST_MILLIS; - mHeadsetStateMachine = HeadsetObjectsFactory.getInstance() - .makeStateMachine(mTestDevice, mHandlerThread.getLooper(), mHeadsetService, - mAdapterService, mNativeInterface, mSystemInterface); + mHeadsetStateMachine = + HeadsetObjectsFactory.getInstance() + .makeStateMachine( + mTestDevice, + mHandlerThread.getLooper(), + mHeadsetService, + mAdapterService, + mNativeInterface, + mSystemInterface); } @After @@ -170,42 +175,44 @@ public class HeadsetStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is Disconnected - */ + /** Test that default state is Disconnected */ @Test public void testDefaultDisconnectedState() { - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mHeadsetStateMachine.getConnectionState()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mHeadsetStateMachine.getConnectionState()); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } - /** - * Test that state is Connected after calling setUpConnectedState() - */ + /** Test that state is Connected after calling setUpConnectedState() */ @Test public void testSetupConnectedState() { setUpConnectedState(); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mHeadsetStateMachine.getConnectionState()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mHeadsetStateMachine.getConnectionState()); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } - /** - * Test state transition from Disconnected to Connecting state via CONNECT message - */ + /** Test state transition from Disconnected to Connecting state via CONNECT message */ @Test public void testStateTransition_DisconnectedToConnecting_Connect() { mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT, mTestDevice); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); } @@ -214,16 +221,25 @@ public class HeadsetStateMachineTest { */ @Test public void testStateTransition_DisconnectedToConnecting_StackConnected() { - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice)); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); } @@ -232,16 +248,25 @@ public class HeadsetStateMachineTest { */ @Test public void testStateTransition_DisconnectedToConnecting_StackConnecting() { - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_CONNECTING, mTestDevice)); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_CONNECTING, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); } @@ -253,49 +278,64 @@ public class HeadsetStateMachineTest { public void testStateTransition_ConnectingToDisconnected_StackDisconnected() { int numBroadcastsSent = setUpConnectingState(); // Indicate disconnecting to test state machine, which should do nothing - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, + mTestDevice)); // Should do nothing new - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); // Indicate connection failed to test state machine - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, + mTestDevice)); numBroadcastsSent++; - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } - /** - * Test state transition from Connecting to Disconnected state via CONNECT_TIMEOUT message - */ + /** Test state transition from Connecting to Disconnected state via CONNECT_TIMEOUT message */ @Test public void testStateTransition_ConnectingToDisconnected_Timeout() { int numBroadcastsSent = setUpConnectingState(); // Let the connection timeout numBroadcastsSent++; - verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( - numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), - eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING, + verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } @@ -306,40 +346,56 @@ public class HeadsetStateMachineTest { public void testStateTransition_ConnectingToConnected_StackSlcConnected() { int numBroadcastsSent = setUpConnectingState(); // Indicate connecting to test state machine - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_CONNECTING, mTestDevice)); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_CONNECTING, + mTestDevice)); // Should do nothing - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); // Indicate RFCOMM connection is successful to test state machine - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice)); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_CONNECTED, + mTestDevice)); // Should do nothing - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); // Indicate SLC connection is successful to test state machine numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } @@ -352,37 +408,49 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpDisconnectingState(); // Send StackEvent.DISCONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } /** - * Test state transition from Disconnecting to Disconnected state via CONNECT_TIMEOUT - * message + * Test state transition from Disconnecting to Disconnected state via CONNECT_TIMEOUT message */ @Test public void testStateTransition_DisconnectingToDisconnected_Timeout() { int numBroadcastsSent = setUpDisconnectingState(); // Let the connection timeout numBroadcastsSent++; - verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( - numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), - eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING, + verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } @@ -395,37 +463,48 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpDisconnectingState(); // Send StackEvent.SLC_CONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } - /** - * Test state transition from Connected to Disconnecting state via DISCONNECT message - */ + /** Test state transition from Connected to Disconnecting state via DISCONNECT message */ @Test public void testStateTransition_ConnectedToDisconnecting_Disconnect() { int numBroadcastsSent = setUpConnectedState(); // Send DISCONNECT message numBroadcastsSent++; mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, mTestDevice); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); } @@ -438,17 +517,25 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpConnectedState(); // Send StackEvent.DISCONNECTING message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); } @@ -461,60 +548,79 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpConnectedState(); // Send StackEvent.DISCONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } - /** - * Test state transition from Connected to AudioConnecting state via CONNECT_AUDIO message - */ + /** Test state transition from Connected to AudioConnecting state via CONNECT_AUDIO message */ @Test public void testStateTransition_ConnectedToAudioConnecting_ConnectAudio() { int numBroadcastsSent = setUpConnectedState(); // Send CONNECT_AUDIO message numBroadcastsSent++; mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mTestDevice); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTING, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class)); } /** - * Test state transition from Connected to AudioConnecting state via - * StackEvent.AUDIO_CONNECTING message + * Test state transition from Connected to AudioConnecting state via StackEvent.AUDIO_CONNECTING + * message */ @Test public void testStateTransition_ConnectedToAudioConnecting_StackAudioConnecting() { int numBroadcastsSent = setUpConnectedState(); // Send StackEvent.AUDIO_CONNECTING message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_CONNECTING, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_CONNECTING, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTING, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class)); } @@ -526,36 +632,47 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpConnectedState(); // Send StackEvent.AUDIO_CONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTED, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); } - /** - * Test state transition from AudioConnecting to Connected state via CONNECT_TIMEOUT message - */ + /** Test state transition from AudioConnecting to Connected state via CONNECT_TIMEOUT message */ @Test public void testStateTransition_AudioConnectingToConnected_Timeout() { int numBroadcastsSent = setUpAudioConnectingState(); // Wait for connection to timeout numBroadcastsSent++; - verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( - numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), - eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, + verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } @@ -568,43 +685,61 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpAudioConnectingState(); // Send StackEvent.AUDIO_DISCONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } /** - * Test state transition from AudioConnecting to Disconnected state via - * StackEvent.DISCONNECTED message + * Test state transition from AudioConnecting to Disconnected state via StackEvent.DISCONNECTED + * message */ @Test public void testStateTransition_AudioConnectingToDisconnected_StackDisconnected() { int numBroadcastsSent = setUpAudioConnectingState(); // Send StackEvent.DISCONNECTED message numBroadcastsSent += 2; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTING, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } @@ -617,43 +752,61 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpAudioConnectingState(); // Send StackEvent.DISCONNECTED message numBroadcastsSent += 2; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTING, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); } /** - * Test state transition from AudioConnecting to AudioOn state via - * StackEvent.AUDIO_CONNECTED message + * Test state transition from AudioConnecting to AudioOn state via StackEvent.AUDIO_CONNECTED + * message */ @Test public void testStateTransition_AudioConnectingToAudioOn_StackAudioConnected() { int numBroadcastsSent = setUpAudioConnectingState(); // Send StackEvent.AUDIO_DISCONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); } @@ -665,20 +818,25 @@ public class HeadsetStateMachineTest { public void testStateTransition_AudioOnToAudioDisconnecting_StackAudioDisconnecting() { int numBroadcastsSent = setUpAudioOnState(); // Send StackEvent.AUDIO_DISCONNECTING message - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_DISCONNECTING, mTestDevice)); - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_DISCONNECTING, + mTestDevice)); + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); } /** - * Test state transition from AudioOn to AudioDisconnecting state via - * DISCONNECT_AUDIO message + * Test state transition from AudioOn to AudioDisconnecting state via DISCONNECT_AUDIO message */ @Test public void testStateTransition_AudioOnToAudioDisconnecting_DisconnectAudio() { @@ -686,86 +844,111 @@ public class HeadsetStateMachineTest { // Send DISCONNECT_AUDIO message mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice); // Should not sent any broadcast due to lack of AUDIO_DISCONNECTING intent value - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); } /** - * Test state transition from AudioOn to AudioDisconnecting state via - * Stack.AUDIO_DISCONNECTED message + * Test state transition from AudioOn to AudioDisconnecting state via Stack.AUDIO_DISCONNECTED + * message */ @Test public void testStateTransition_AudioOnToConnected_StackAudioDisconnected() { int numBroadcastsSent = setUpAudioOnState(); // Send DISCONNECT_AUDIO message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } - /** - * Test state transition from AudioOn to Disconnected state via - * Stack.DISCONNECTED message - */ + /** Test state transition from AudioOn to Disconnected state via Stack.DISCONNECTED message */ @Test public void testStateTransition_AudioOnToDisconnected_StackDisconnected() { int numBroadcastsSent = setUpAudioOnState(); // Send StackEvent.DISCONNECTED message numBroadcastsSent += 2; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } - /** - * Test state transition from AudioOn to Disconnecting state via - * Stack.DISCONNECTING message - */ + /** Test state transition from AudioOn to Disconnecting state via Stack.DISCONNECTING message */ @Test public void testStateTransition_AudioOnToDisconnecting_StackDisconnecting() { int numBroadcastsSent = setUpAudioOnState(); // Send StackEvent.DISCONNECTING message numBroadcastsSent += 2; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); } @@ -782,11 +965,14 @@ public class HeadsetStateMachineTest { if (i > 0) { // Skip first AUDIO_DISCONNECTING init as it was setup before the loop mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice); // No new broadcast due to lack of AUDIO_DISCONNECTING intent variable - verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS) - .times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); if (i == MAX_RETRY_DISCONNECT_AUDIO) { // Increment twice numBroadcastsSent as DISCONNECT message is added on max retry @@ -795,122 +981,167 @@ public class HeadsetStateMachineTest { numBroadcastsSent++; } } - verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( - numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), - eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify( + mHeadsetService, + timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); if (i < MAX_RETRY_DISCONNECT_AUDIO) { // Test if state is AudioOn before max retry - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); } else { // Max retry count reached, test Disconnecting state - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, BluetoothHeadset.STATE_DISCONNECTING, BluetoothHeadset.STATE_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); } } } /** - * Test state transition from AudioDisconnecting to Connected state via - * Stack.AUDIO_DISCONNECTED message + * Test state transition from AudioDisconnecting to Connected state via Stack.AUDIO_DISCONNECTED + * message */ @Test public void testStateTransition_AudioDisconnectingToConnected_StackAudioDisconnected() { int numBroadcastsSent = setUpAudioDisconnectingState(); // Send Stack.AUDIO_DISCONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); } /** - * Test state transition from AudioDisconnecting to AudioOn state via - * Stack.AUDIO_CONNECTED message + * Test state transition from AudioDisconnecting to AudioOn state via Stack.AUDIO_CONNECTED + * message */ @Test public void testStateTransition_AudioDisconnectingToAudioOn_StackAudioConnected() { int numBroadcastsSent = setUpAudioDisconnectingState(); // Send Stack.AUDIO_CONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_CONNECTED, + mTestDevice)); + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); } /** - * Test state transition from AudioDisconnecting to Disconnecting state via - * Stack.DISCONNECTING message + * Test state transition from AudioDisconnecting to Disconnecting state via Stack.DISCONNECTING + * message */ @Test public void testStateTransition_AudioDisconnectingToDisconnecting_StackDisconnecting() { int numBroadcastsSent = setUpAudioDisconnectingState(); // Send StackEvent.DISCONNECTING message numBroadcastsSent += 2; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); } /** - * Test state transition from AudioDisconnecting to Disconnecting state via - * Stack.DISCONNECTED message + * Test state transition from AudioDisconnecting to Disconnecting state via Stack.DISCONNECTED + * message */ @Test public void testStateTransition_AudioDisconnectingToDisconnected_StackDisconnected() { int numBroadcastsSent = setUpAudioDisconnectingState(); // Send StackEvent.DISCONNECTED message numBroadcastsSent += 2; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); } @@ -921,28 +1152,38 @@ public class HeadsetStateMachineTest { @Test public void testAtBiaEvent_initialSubscriptionWithUpdates() { setUpConnectedState(); - verify(mPhoneState).listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, - new HeadsetAgIndicatorEnableState(true, true, false, false), mTestDevice)); - verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice, - PhoneStateListener.LISTEN_SERVICE_STATE); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, - new HeadsetAgIndicatorEnableState(false, true, true, false), mTestDevice)); - verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice, - PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, - new HeadsetAgIndicatorEnableState(false, true, false, false), mTestDevice)); - verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice, - PhoneStateListener.LISTEN_NONE); + verify(mPhoneState) + .listenForPhoneState( + mTestDevice, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_BIA, + new HeadsetAgIndicatorEnableState(true, true, false, false), + mTestDevice)); + verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_SERVICE_STATE); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_BIA, + new HeadsetAgIndicatorEnableState(false, true, true, false), + mTestDevice)); + verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_BIA, + new HeadsetAgIndicatorEnableState(false, true, false, false), + mTestDevice)); + verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_NONE); } - /** - * A test to verify that we correctly handles key pressed event from a HSP headset - */ + /** A test to verify that we correctly handles key pressed event from a HSP headset */ @Test public void testKeyPressedEventWhenIdleAndAudioOff_dialCall() { setUpConnectedState(); @@ -952,70 +1193,75 @@ public class HeadsetStateMachineTest { int magicNumber = 42; when(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER)).thenReturn(magicNumber); when(cursor.getString(magicNumber)).thenReturn(TEST_PHONE_NUMBER); - MockContentProvider mockContentProvider = new MockContentProvider() { - @Override - public Cursor query(Uri uri, String[] projection, Bundle queryArgs, - CancellationSignal cancellationSignal) { - if (uri == null || !uri.equals(CallLog.Calls.CONTENT_URI)) { - return null; - } - if (projection == null || (projection.length == 0) || !projection[0].equals( - CallLog.Calls.NUMBER)) { - return null; - } - if (queryArgs == null - || !queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SELECTION).equals( - Calls.TYPE + "=" + Calls.OUTGOING_TYPE) - || !queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER).equals( - Calls.DEFAULT_SORT_ORDER) - || queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT) != 1) { - return null; - } - if (cancellationSignal != null) { - return null; - } - return cursor; - } - }; + MockContentProvider mockContentProvider = + new MockContentProvider() { + @Override + public Cursor query( + Uri uri, + String[] projection, + Bundle queryArgs, + CancellationSignal cancellationSignal) { + if (uri == null || !uri.equals(CallLog.Calls.CONTENT_URI)) { + return null; + } + if (projection == null + || (projection.length == 0) + || !projection[0].equals(CallLog.Calls.NUMBER)) { + return null; + } + if (queryArgs == null + || !queryArgs + .getString(ContentResolver.QUERY_ARG_SQL_SELECTION) + .equals(Calls.TYPE + "=" + Calls.OUTGOING_TYPE) + || !queryArgs + .getString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER) + .equals(Calls.DEFAULT_SORT_ORDER) + || queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT) != 1) { + return null; + } + if (cancellationSignal != null) { + return null; + } + return cursor; + } + }; mMockContentResolver.addProvider(CallLog.AUTHORITY, mockContentProvider); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).dialOutgoingCall(mTestDevice, - TEST_PHONE_NUMBER); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .dialOutgoingCall(mTestDevice, TEST_PHONE_NUMBER); } - /** - * A test to verify that we correctly handles key pressed event from a HSP headset - */ + /** A test to verify that we correctly handles key pressed event from a HSP headset */ @Test public void testKeyPressedEventDuringRinging_answerCall() { setUpConnectedState(); when(mSystemInterface.isRinging()).thenReturn(true); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).answerCall(mTestDevice); } - /** - * A test to verify that we correctly handles key pressed event from a HSP headset - */ + /** A test to verify that we correctly handles key pressed event from a HSP headset */ @Test public void testKeyPressedEventInCallButAudioOff_setActiveDevice() { setUpConnectedState(); when(mSystemInterface.isInCall()).thenReturn(true); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setActiveDevice(mTestDevice); } - /** - * A test to verify that we correctly handles key pressed event from a HSP headset - */ + /** A test to verify that we correctly handles key pressed event from a HSP headset */ @Test public void testKeyPressedEventInCallAndAudioOn_hangupCall() { setUpAudioOnState(); when(mSystemInterface.isInCall()).thenReturn(true); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).hangupCall(mTestDevice); } @@ -1060,111 +1306,119 @@ public class HeadsetStateMachineTest { } } - /** - * A test to verify that we correctly handles key pressed event from a HSP headset - */ + /** A test to verify that we correctly handles key pressed event from a HSP headset */ @Test public void testKeyPressedEventWhenIdleAndAudioOn_disconnectAudio() { setUpAudioOnState(); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).disconnectAudio(mTestDevice); } - /** - * A test to verfiy that we correctly handles AT+BIND event with driver safety case from HF - */ + /** A test to verfiy that we correctly handles AT+BIND event with driver safety case from HF */ @Test public void testAtBindWithDriverSafetyEventWhenConnecting() { setUpConnectingState(); String atString = "1"; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, mTestDevice)); ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( - intentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), - any()); - Assert.assertEquals(mTestDevice, intentArgument.getValue().getExtra( - BluetoothDevice.EXTRA_DEVICE, null)); - Assert.assertEquals(HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY, - intentArgument.getValue().getIntExtra( - BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); - Assert.assertEquals(-1, intentArgument.getValue().getIntExtra( - BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); - } - - /** - * A test to verfiy that we correctly handles AT+BIND event with battery level case from HF - */ + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcast(intentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), any()); + Assert.assertEquals( + mTestDevice, + intentArgument.getValue().getExtra(BluetoothDevice.EXTRA_DEVICE, null)); + Assert.assertEquals( + HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); + Assert.assertEquals( + -1, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); + } + + /** A test to verfiy that we correctly handles AT+BIND event with battery level case from HF */ @Test public void testAtBindEventWithBatteryLevelEventWhenConnecting() { setUpConnectingState(); String atString = "2"; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, mTestDevice)); ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( - intentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), - any()); - Assert.assertEquals(mTestDevice, intentArgument.getValue().getExtra( - BluetoothDevice.EXTRA_DEVICE, null)); - Assert.assertEquals(HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS, - intentArgument.getValue().getIntExtra( - BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); - Assert.assertEquals(-1, intentArgument.getValue().getIntExtra( - BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); - } - - /** - * A test to verfiy that we correctly handles AT+BIND event with error case from HF - */ + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcast(intentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), any()); + Assert.assertEquals( + mTestDevice, + intentArgument.getValue().getExtra(BluetoothDevice.EXTRA_DEVICE, null)); + Assert.assertEquals( + HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); + Assert.assertEquals( + -1, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); + } + + /** A test to verfiy that we correctly handles AT+BIND event with error case from HF */ @Test public void testAtBindEventWithErrorEventWhenConnecting() { setUpConnectingState(); String atString = "err,A,123,,1"; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, mTestDevice)); ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( - intentArgument.capture(), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), - any()); - Assert.assertEquals(mTestDevice, intentArgument.getValue().getExtra( - BluetoothDevice.EXTRA_DEVICE, null)); - Assert.assertEquals(HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY, - intentArgument.getValue().getIntExtra( - BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); - Assert.assertEquals(-1, intentArgument.getValue().getIntExtra( - BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); - } - - /** - * A test to verify that we correctly set AG indicator mask when enter/exit silence mode - */ + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcast(intentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), any()); + Assert.assertEquals( + mTestDevice, + intentArgument.getValue().getExtra(BluetoothDevice.EXTRA_DEVICE, null)); + Assert.assertEquals( + HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); + Assert.assertEquals( + -1, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); + } + + /** A test to verify that we correctly set AG indicator mask when enter/exit silence mode */ @Test public void testSetSilenceDevice() { doNothing().when(mPhoneState).listenForPhoneState(any(BluetoothDevice.class), anyInt()); mHeadsetStateMachine.setSilenceDevice(true); mHeadsetStateMachine.setSilenceDevice(false); - verify(mPhoneState, times(2)).listenForPhoneState(mTestDevice, - PhoneStateListener.LISTEN_NONE); + verify(mPhoneState, times(2)) + .listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_NONE); } @Test public void testBroadcastVendorSpecificEventIntent() { - mHeadsetStateMachine.broadcastVendorSpecificEventIntent( - "command", 1, 1, null, mTestDevice); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); + mHeadsetStateMachine.broadcastVendorSpecificEventIntent("command", 1, 1, null, mTestDevice); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); } @Test @@ -1207,19 +1461,19 @@ public class HeadsetStateMachineTest { @Test public void testGetAtCommandType() { String atCommand = "start?"; - Assert.assertEquals(mHeadsetStateMachine.getAtCommandType(atCommand), - AtPhonebook.TYPE_READ); + Assert.assertEquals( + mHeadsetStateMachine.getAtCommandType(atCommand), AtPhonebook.TYPE_READ); atCommand = "start=?"; - Assert.assertEquals(mHeadsetStateMachine.getAtCommandType(atCommand), - AtPhonebook.TYPE_TEST); + Assert.assertEquals( + mHeadsetStateMachine.getAtCommandType(atCommand), AtPhonebook.TYPE_TEST); atCommand = "start=comm"; Assert.assertEquals(mHeadsetStateMachine.getAtCommandType(atCommand), AtPhonebook.TYPE_SET); atCommand = "start!"; - Assert.assertEquals(mHeadsetStateMachine.getAtCommandType(atCommand), - AtPhonebook.TYPE_UNKNOWN); + Assert.assertEquals( + mHeadsetStateMachine.getAtCommandType(atCommand), AtPhonebook.TYPE_UNKNOWN); } @Test @@ -1248,8 +1502,9 @@ public class HeadsetStateMachineTest { public void testHandleAccessPermissionResult_withNoChangeInAtCommandResult() { when(mIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).thenReturn(null); when(mIntent.getAction()).thenReturn(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); - when(mIntent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, - BluetoothDevice.CONNECTION_ACCESS_NO)) + when(mIntent.getIntExtra( + BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, + BluetoothDevice.CONNECTION_ACCESS_NO)) .thenReturn(BluetoothDevice.CONNECTION_ACCESS_NO); when(mIntent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)).thenReturn(true); mHeadsetStateMachine.mPhonebook.setCheckingAccessPermission(true); @@ -1263,8 +1518,8 @@ public class HeadsetStateMachineTest { public void testProcessAtBievCommand() { mHeadsetStateMachine.processAtBiev(1, 1, mTestDevice); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( - mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcast(mIntentArgument.capture(), eq(BLUETOOTH_CONNECT), any(Bundle.class)); } @Test @@ -1284,8 +1539,8 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processAtChld(chld, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - 0); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); } @Test @@ -1331,8 +1586,11 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processAtCpbr(atString, type, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.TEXT_HAS_INVALID_CHARS); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.TEXT_HAS_INVALID_CHARS); } @Test @@ -1342,8 +1600,11 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processAtCpbs(atString, type, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.OPERATION_NOT_ALLOWED); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.OPERATION_NOT_ALLOWED); } @Test @@ -1353,8 +1614,8 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processAtCscs(atString, type, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, - -1); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, -1); } @Test @@ -1370,8 +1631,8 @@ public class HeadsetStateMachineTest { @Test public void testProcessSendVendorSpecificResultCode() { - HeadsetVendorSpecificResultCode resultCode = new HeadsetVendorSpecificResultCode( - mTestDevice, "command", "arg"); + HeadsetVendorSpecificResultCode resultCode = + new HeadsetVendorSpecificResultCode(mTestDevice, "command", "arg"); mHeadsetStateMachine.processSendVendorSpecificResultCode(resultCode); @@ -1394,8 +1655,14 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processSubscriberNumberRequest(mTestDevice); - verify(mNativeInterface).atResponseString(mTestDevice, - "+CNUM: ,\"" + number + "\"," + PhoneNumberUtils.toaFromString(number) + ",,4"); + verify(mNativeInterface) + .atResponseString( + mTestDevice, + "+CNUM: ,\"" + + number + + "\"," + + PhoneNumberUtils.toaFromString(number) + + ",,4"); verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0); } @@ -1403,24 +1670,33 @@ public class HeadsetStateMachineTest { public void testProcessUnknownAt() { String atString = "+CSCS=invalid"; mHeadsetStateMachine.processUnknownAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.OPERATION_NOT_SUPPORTED); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.OPERATION_NOT_SUPPORTED); Mockito.clearInvocations(mNativeInterface); atString = "+CPBS="; mHeadsetStateMachine.processUnknownAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.OPERATION_NOT_SUPPORTED); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.OPERATION_NOT_SUPPORTED); atString = "+CPBR=ERR"; mHeadsetStateMachine.processUnknownAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - BluetoothCmeError.TEXT_HAS_INVALID_CHARS); + verify(mNativeInterface) + .atResponseCode( + mTestDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.TEXT_HAS_INVALID_CHARS); atString = "inval="; mHeadsetStateMachine.processUnknownAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - 0); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); } @Test @@ -1429,8 +1705,8 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - 0); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); } @Test @@ -1439,8 +1715,8 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - 0); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); } @Test @@ -1449,8 +1725,8 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice); - verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, - 0); + verify(mNativeInterface) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); } @Test @@ -1535,28 +1811,28 @@ public class HeadsetStateMachineTest { mHeadsetStateMachine.dump(sb); } - /** - * A test to validate received Android AT commands and processing - */ + /** A test to validate received Android AT commands and processing */ @Test public void testCheckAndProcessAndroidAt() { // Commands that will be handled int counter_ok = 0; int counter_error = 0; - Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID=?" , mTestDevice)); + Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=?", mTestDevice)); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_ok)) .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0); - Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID=SINKAUDIOPOLICY,1,1,1" , mTestDevice)); + Assert.assertTrue( + mHeadsetStateMachine.checkAndProcessAndroidAt( + "+ANDROID=SINKAUDIOPOLICY,1,1,1", mTestDevice)); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_ok)) .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0); - Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID=SINKAUDIOPOLICY,100,100,100" , mTestDevice)); + Assert.assertTrue( + mHeadsetStateMachine.checkAndProcessAndroidAt( + "+ANDROID=SINKAUDIOPOLICY,100,100,100", mTestDevice)); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_ok)) .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0); - Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID=SINKAUDIOPOLICY,1,2,3,4,5" , mTestDevice)); + Assert.assertTrue( + mHeadsetStateMachine.checkAndProcessAndroidAt( + "+ANDROID=SINKAUDIOPOLICY,1,2,3,4,5", mTestDevice)); verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_error)) .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=1", mTestDevice)); @@ -1577,18 +1853,20 @@ public class HeadsetStateMachineTest { .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); // Commands with correct format but will not be handled - Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID=" , mTestDevice)); - Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID: PROBE,1,\"`AB\"" , mTestDevice)); - Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID= PROBE,1,\"`AB\"" , mTestDevice)); - Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt( - "AT+ANDROID=PROBE,1,1,\"PQGHRSBCTU__\"" , mTestDevice)); + Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=", mTestDevice)); + Assert.assertFalse( + mHeadsetStateMachine.checkAndProcessAndroidAt( + "+ANDROID: PROBE,1,\"`AB\"", mTestDevice)); + Assert.assertFalse( + mHeadsetStateMachine.checkAndProcessAndroidAt( + "+ANDROID= PROBE,1,\"`AB\"", mTestDevice)); + Assert.assertFalse( + mHeadsetStateMachine.checkAndProcessAndroidAt( + "AT+ANDROID=PROBE,1,1,\"PQGHRSBCTU__\"", mTestDevice)); // Incorrect format AT command - Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt( - "RANDOM FORMAT" , mTestDevice)); + Assert.assertFalse( + mHeadsetStateMachine.checkAndProcessAndroidAt("RANDOM FORMAT", mTestDevice)); // Check no any AT result was sent for the failed ones verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(counter_ok)) @@ -1600,17 +1878,14 @@ public class HeadsetStateMachineTest { @Test public void testCheckAndProcessAndroidAt_replyAndroidAtFeatureRequest() { // Commands that will be handled - Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt( - "+ANDROID=?" , mTestDevice)); - verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).atResponseString( - mTestDevice, "+ANDROID: (SINKAUDIOPOLICY)"); - verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).atResponseCode( - mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0); + Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=?", mTestDevice)); + verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .atResponseString(mTestDevice, "+ANDROID: (SINKAUDIOPOLICY)"); + verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0); } - /** - * A end to end test to validate received Android AT commands and processing - */ + /** A end to end test to validate received Android AT commands and processing */ @Test public void testCehckAndProcessAndroidAtFromStateMachine() { // setAudioPolicyMetadata is invoked in HeadsetStateMachine.init() so start from 1 @@ -1621,24 +1896,28 @@ public class HeadsetStateMachineTest { setUpAudioPolicy(); // receive and set android policy - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, - "+ANDROID=SINKAUDIOPOLICY,1,1,1", mTestDevice)); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, + "+ANDROID=SINKAUDIOPOLICY,1,1,1", + mTestDevice)); expectCallTimes++; verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(expectCallTimes)) .setAudioPolicyMetadata(anyObject(), anyObject()); // receive and not set android policy - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, - "AT+ANDROID=PROBE,1,1,\"PQGHRSBCTU__\"", mTestDevice)); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, + "AT+ANDROID=PROBE,1,1,\"PQGHRSBCTU__\"", + mTestDevice)); verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(expectCallTimes)) .setAudioPolicyMetadata(anyObject(), anyObject()); } - /** - * A test to verify whether the sink audio policy command is valid - */ + /** A test to verify whether the sink audio policy command is valid */ @Test public void testProcessAndroidAtSinkAudioPolicy() { // expected format @@ -1772,6 +2051,7 @@ public class HeadsetStateMachineTest { /** * set sink audio policy + * * @param arg body of the AT command * @return the result from processAndroidAtSinkAudioPolicy */ @@ -1782,49 +2062,75 @@ public class HeadsetStateMachineTest { /** * Setup Connecting State + * * @return number of times mHeadsetService.sendBroadcastAsUser() has been invoked */ private int setUpConnectingState() { // Put test state machine in connecting state mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT, mTestDevice); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); return 1; } /** * Setup Connected State + * * @return number of times mHeadsetService.sendBroadcastAsUser() has been invoked */ private int setUpConnectedState() { // Put test state machine into connected state - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice)); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, - HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice)); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); return 2; } @@ -1834,14 +2140,19 @@ public class HeadsetStateMachineTest { // Send CONNECT_AUDIO numBroadcastsSent++; mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mTestDevice); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTING, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class)); return numBroadcastsSent; } @@ -1850,17 +2161,25 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpAudioConnectingState(); // Send StackEvent.AUDIO_DISCONNECTED message numBroadcastsSent++; - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, - HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, - BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + HeadsetHalConstants.AUDIO_STATE_CONNECTED, + mTestDevice)); + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyAudioStateBroadcast( + mTestDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTING, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); return numBroadcastsSent; } @@ -1869,11 +2188,14 @@ public class HeadsetStateMachineTest { int numBroadcastsSent = setUpAudioOnState(); mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice); // No new broadcast due to lack of AUDIO_DISCONNECTING intent variable - verify(mHeadsetService, - after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + verify(mHeadsetService, after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + any(Intent.class), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); return numBroadcastsSent; } @@ -1883,24 +2205,30 @@ public class HeadsetStateMachineTest { // Send DISCONNECT message numBroadcastsSent++; mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, mTestDevice); - verify(mHeadsetService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( - mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), - any(Bundle.class)); - HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, + verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)) + .sendBroadcastAsUser( + mIntentArgument.capture(), + eq(UserHandle.ALL), + eq(BLUETOOTH_CONNECT), + any(Bundle.class)); + HeadsetTestUtils.verifyConnectionStateBroadcast( + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, mIntentArgument.getValue()); - Assert.assertThat(mHeadsetStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); return numBroadcastsSent; } private void setUpAudioPolicy() { - mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, - "+ANDROID=?", mTestDevice)); - verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).atResponseString( - anyObject(), anyString()); + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, "+ANDROID=?", mTestDevice)); + verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .atResponseString(anyObject(), anyString()); } private void configureHeadsetServiceForAptxVoice(boolean enable) { diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java index 4279afb0d3e..b8439fa8557 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java @@ -25,9 +25,7 @@ import android.content.Intent; import org.junit.Assert; -/** - * Helper functions for HFP related tests - */ +/** Helper functions for HFP related tests */ public class HeadsetTestUtils { /** @@ -38,14 +36,14 @@ public class HeadsetTestUtils { * @param fromState value of {@link BluetoothProfile#EXTRA_PREVIOUS_STATE} * @param intent a {@link BluetoothHeadset#ACTION_AUDIO_STATE_CHANGED} intent */ - public static void verifyAudioStateBroadcast(BluetoothDevice device, int toState, int fromState, - Intent intent) { + public static void verifyAudioStateBroadcast( + BluetoothDevice device, int toState, int fromState, Intent intent) { Assert.assertNotNull(intent); Assert.assertEquals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED, intent.getAction()); Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); Assert.assertEquals(toState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(fromState, - intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); + Assert.assertEquals( + fromState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); } /** @@ -56,10 +54,10 @@ public class HeadsetTestUtils { * @param fromState value of {@link BluetoothProfile#EXTRA_PREVIOUS_STATE} * @param intent a {@link BluetoothHeadset#ACTION_CONNECTION_STATE_CHANGED} intent * @param checkFlag whether intent flag should be verified, normally this can only be done at - * the sender end + * the sender end */ - public static void verifyConnectionStateBroadcast(BluetoothDevice device, int toState, - int fromState, Intent intent, boolean checkFlag) { + public static void verifyConnectionStateBroadcast( + BluetoothDevice device, int toState, int fromState, Intent intent, boolean checkFlag) { Assert.assertNotNull(intent); Assert.assertEquals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED, intent.getAction()); if (checkFlag) { @@ -67,41 +65,43 @@ public class HeadsetTestUtils { } Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); Assert.assertEquals(toState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(fromState, - intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); + Assert.assertEquals( + fromState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); } /** - * Verify the content of a {@link BluetoothHeadset#ACTION_CONNECTION_STATE_CHANGED} intent - * and its flag, normally used at sender end + * Verify the content of a {@link BluetoothHeadset#ACTION_CONNECTION_STATE_CHANGED} intent and + * its flag, normally used at sender end * * @param device Bluetooth device * @param toState value of {@link BluetoothProfile#EXTRA_STATE} * @param fromState value of {@link BluetoothProfile#EXTRA_PREVIOUS_STATE} * @param intent a {@link BluetoothHeadset#ACTION_CONNECTION_STATE_CHANGED} intent */ - public static void verifyConnectionStateBroadcast(BluetoothDevice device, int toState, - int fromState, Intent intent) { + public static void verifyConnectionStateBroadcast( + BluetoothDevice device, int toState, int fromState, Intent intent) { verifyConnectionStateBroadcast(device, toState, fromState, intent, true); } /** - * Verify the content of a {@link BluetoothHeadset#ACTION_ACTIVE_DEVICE_CHANGED} intent - * and its flag, normally used at sender end + * Verify the content of a {@link BluetoothHeadset#ACTION_ACTIVE_DEVICE_CHANGED} intent and its + * flag, normally used at sender end * * @param device intended active Bluetooth device * @param intent a {@link BluetoothHeadset#ACTION_ACTIVE_DEVICE_CHANGED} intent * @param checkFlag whether intent flag should be verified, normally this can only be done at - * the sender end + * the sender end */ - public static void verifyActiveDeviceChangedBroadcast(BluetoothDevice device, Intent intent, - boolean checkFlag) { + public static void verifyActiveDeviceChangedBroadcast( + BluetoothDevice device, Intent intent, boolean checkFlag) { Assert.assertNotNull(intent); Assert.assertEquals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED, intent.getAction()); Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); if (checkFlag) { - Assert.assertEquals(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, intent.getFlags()); + Assert.assertEquals( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, + intent.getFlags()); } } @@ -113,13 +113,13 @@ public class HeadsetTestUtils { * @param headsetCallState intended headset call state * @param timeoutMs timeout for this check in asynchronous test conditions */ - public static void verifyPhoneStateChangeSetters(HeadsetPhoneState headsetPhoneState, - HeadsetCallState headsetCallState, int timeoutMs) { - verify(headsetPhoneState, timeout(timeoutMs).times(1)).setNumActiveCall( - headsetCallState.mNumActive); - verify(headsetPhoneState, timeout(timeoutMs).times(1)).setNumHeldCall( - headsetCallState.mNumHeld); - verify(headsetPhoneState, timeout(timeoutMs).times(1)).setCallState( - headsetCallState.mCallState); + public static void verifyPhoneStateChangeSetters( + HeadsetPhoneState headsetPhoneState, HeadsetCallState headsetCallState, int timeoutMs) { + verify(headsetPhoneState, timeout(timeoutMs).times(1)) + .setNumActiveCall(headsetCallState.mNumActive); + verify(headsetPhoneState, timeout(timeoutMs).times(1)) + .setNumHeldCall(headsetCallState.mNumHeld); + verify(headsetPhoneState, timeout(timeoutMs).times(1)) + .setCallState(headsetCallState.mCallState); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java index 8d669e15456..3e5dc1d3ea1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java @@ -45,8 +45,8 @@ public class HeadsetVendorSpecificResultCodeTest { @Test public void constructor() { - HeadsetVendorSpecificResultCode code = new HeadsetVendorSpecificResultCode(mTestDevice, - TEST_COMMAND, TEST_ARG); + HeadsetVendorSpecificResultCode code = + new HeadsetVendorSpecificResultCode(mTestDevice, TEST_COMMAND, TEST_ARG); assertThat(code.mDevice).isEqualTo(mTestDevice); assertThat(code.mCommand).isEqualTo(TEST_COMMAND); @@ -55,15 +55,21 @@ public class HeadsetVendorSpecificResultCodeTest { @Test public void buildString() { - HeadsetVendorSpecificResultCode code = new HeadsetVendorSpecificResultCode(mTestDevice, - TEST_COMMAND, TEST_ARG); + HeadsetVendorSpecificResultCode code = + new HeadsetVendorSpecificResultCode(mTestDevice, TEST_COMMAND, TEST_ARG); StringBuilder builder = new StringBuilder(); code.buildString(builder); String expectedString = - code.getClass().getSimpleName() + "[device=" + mTestDevice + ", command=" - + TEST_COMMAND + ", arg=" + TEST_ARG + "]"; + code.getClass().getSimpleName() + + "[device=" + + mTestDevice + + ", command=" + + TEST_COMMAND + + ", arg=" + + TEST_ARG + + "]"; assertThat(builder.toString()).isEqualTo(expectedString); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java index 57b7f9087c3..cb0121653b5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java @@ -40,8 +40,7 @@ public class HeadsetClientServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private HeadsetClientService mService; + @Mock private HeadsetClientService mService; BluetoothDevice mRemoteDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java index 65ef6b3985d..d059770d9e8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java @@ -120,10 +120,7 @@ public class HeadsetClientServiceTest { // Expect send BIEV to state machine verify(mStateMachine, timeout(STANDARD_WAIT_MILLIS).times(1)) - .sendMessage( - eq(HeadsetClientStateMachine.SEND_BIEV), - eq(2), - anyInt()); + .sendMessage(eq(HeadsetClientStateMachine.SEND_BIEV), eq(2), anyInt()); } @Test @@ -141,10 +138,7 @@ public class HeadsetClientServiceTest { // Expect send BIEV to state machine verify(mStateMachine, timeout(STANDARD_WAIT_MILLIS).times(1)) - .sendMessage( - eq(HeadsetClientStateMachine.SEND_BIEV), - eq(2), - anyInt()); + .sendMessage(eq(HeadsetClientStateMachine.SEND_BIEV), eq(2), anyInt()); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java index ea38d2ea859..339a5bc6871 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java @@ -88,9 +88,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -/** - * Test cases for {@link HeadsetClientStateMachine}. - */ +/** Test cases for {@link HeadsetClientStateMachine}. */ @LargeTest @RunWith(AndroidJUnit4.class) public class HeadsetClientStateMachineTest { @@ -115,8 +113,8 @@ public class HeadsetClientStateMachineTest { private static final int STANDARD_WAIT_MILLIS = 1000; private static final int QUERY_CURRENT_CALLS_WAIT_MILLIS = 2000; - private static final int QUERY_CURRENT_CALLS_TEST_WAIT_MILLIS = QUERY_CURRENT_CALLS_WAIT_MILLIS - * 3 / 2; + private static final int QUERY_CURRENT_CALLS_TEST_WAIT_MILLIS = + QUERY_CURRENT_CALLS_WAIT_MILLIS * 3 / 2; private static final int TIMEOUT_MS = 1000; @Before @@ -127,8 +125,7 @@ public class HeadsetClientStateMachineTest { when(mAudioManager.getStreamVolume(anyInt())).thenReturn(2); when(mAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10); when(mAudioManager.getStreamMinVolume(anyInt())).thenReturn(1); - when(mHeadsetClientService.getAudioManager()).thenReturn( - mAudioManager); + when(mHeadsetClientService.getAudioManager()).thenReturn(mAudioManager); when(mHeadsetClientService.getResources()).thenReturn(mMockHfpResources); when(mHeadsetClientService.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.hasSystemFeature(FEATURE_WATCH)).thenReturn(false); @@ -149,8 +146,12 @@ public class HeadsetClientStateMachineTest { mHandlerThread = new HandlerThread("HeadsetClientStateMachineTestHandlerThread"); mHandlerThread.start(); // Manage looper execution in main test thread explicitly to guarantee timing consistency - mHeadsetClientStateMachine = new TestHeadsetClientStateMachine(mHeadsetClientService, - mHeadsetService, mHandlerThread.getLooper(), mNativeInterface); + mHeadsetClientStateMachine = + new TestHeadsetClientStateMachine( + mHeadsetClientService, + mHeadsetService, + mHandlerThread.getLooper(), + mNativeInterface); mHeadsetClientStateMachine.start(); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); } @@ -255,25 +256,22 @@ public class HeadsetClientStateMachineTest { } } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @SmallTest @Test public void testDefaultDisconnectedState() { - Assert.assertEquals(mHeadsetClientStateMachine.getConnectionState(null), + Assert.assertEquals( + mHeadsetClientStateMachine.getConnectionState(null), BluetoothProfile.STATE_DISCONNECTED); } - /** - * Test that an incoming connection with low priority is rejected - */ + /** Test that an incoming connection with low priority is rejected */ @MediumTest @Test public void testIncomingPriorityReject() { // Return false for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Inject an event for when incoming connection is requested StackEvent connStCh = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); @@ -283,29 +281,33 @@ public class HeadsetClientStateMachineTest { // Verify that only DISCONNECTED -> DISCONNECTED broadcast is fired verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS)) - .sendBroadcastMultiplePermissions(MockitoHamcrest.argThat( - AllOf.allOf(IntentMatchers.hasAction( - BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED), - IntentMatchers.hasExtra(BluetoothProfile.EXTRA_STATE, - BluetoothProfile.STATE_DISCONNECTED), - IntentMatchers.hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - BluetoothProfile.STATE_DISCONNECTED))), - any(String[].class), - any(BroadcastOptions.class)); + .sendBroadcastMultiplePermissions( + MockitoHamcrest.argThat( + AllOf.allOf( + IntentMatchers.hasAction( + BluetoothHeadsetClient + .ACTION_CONNECTION_STATE_CHANGED), + IntentMatchers.hasExtra( + BluetoothProfile.EXTRA_STATE, + BluetoothProfile.STATE_DISCONNECTED), + IntentMatchers.hasExtra( + BluetoothProfile.EXTRA_PREVIOUS_STATE, + BluetoothProfile.STATE_DISCONNECTED))), + any(String[].class), + any(BroadcastOptions.class)); // Check we are in disconnected state still. - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Disconnected.class)); } - /** - * Test that an incoming connection with high priority is accepted - */ + /** Test that an incoming connection with high priority is accepted */ @MediumTest @Test public void testIncomingPriorityAccept() { // Return true for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Inject an event for when incoming connection is requested StackEvent connStCh = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); @@ -316,13 +318,17 @@ public class HeadsetClientStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS)) - .sendBroadcastMultiplePermissions(intentArgument1.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + .sendBroadcastMultiplePermissions( + intentArgument1.capture(), + any(String[].class), + any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check we are in connecting state now. - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class)); // Send a message to trigger SLC connection @@ -338,25 +344,27 @@ public class HeadsetClientStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(2)) - .sendBroadcastMultiplePermissions(intentArgument2.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, + .sendBroadcastMultiplePermissions( + intentArgument2.capture(), + any(String[].class), + any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check we are in connecting state now. - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(true)); } - /** - * Test that an incoming connection that times out - */ + /** Test that an incoming connection that times out */ @MediumTest @Test public void testIncomingTimeout() { // Return true for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Inject an event for when incoming connection is requested StackEvent connStCh = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); @@ -367,26 +375,35 @@ public class HeadsetClientStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS)) - .sendBroadcastMultiplePermissions(intentArgument1.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + .sendBroadcastMultiplePermissions( + intentArgument1.capture(), + any(String[].class), + any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check we are in connecting state now. - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class)); // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class); - verify(mHeadsetClientService, - timeout(HeadsetClientStateMachine.CONNECTING_TIMEOUT_MS * 2).times(2)) - .sendBroadcastMultiplePermissions(intentArgument2.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + verify( + mHeadsetClientService, + timeout(HeadsetClientStateMachine.CONNECTING_TIMEOUT_MS * 2).times(2)) + .sendBroadcastMultiplePermissions( + intentArgument2.capture(), + any(String[].class), + any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Check we are in connecting state now. - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Disconnected.class)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(false)); } @@ -396,31 +413,39 @@ public class HeadsetClientStateMachineTest { initToConnectedState(); // True on correct AT command and BluetothDevice - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: (SINKAUDIOPOLICY)", mTestDevice)); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: ()", mTestDevice)); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: (,,,)", mTestDevice)); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: (SINKAUDIOPOLICY),(OTHERFEATURE)", mTestDevice)); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: (SINKAUDIOPOLICY),(OTHERFEATURE,1,2,3),(1,2,3)", mTestDevice)); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: 123", mTestDevice)); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: ", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID: (SINKAUDIOPOLICY)", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand("+ANDROID: ()", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID: (,,,)", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID: (SINKAUDIOPOLICY),(OTHERFEATURE)", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID: (SINKAUDIOPOLICY),(OTHERFEATURE,1,2,3),(1,2,3)", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand("+ANDROID: 123", mTestDevice)); + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand("+ANDROID: ", mTestDevice)); // False on incorrect AT command format - Assert.assertFalse(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID= (SINKAUDIOPOLICY)", mTestDevice)); - Assert.assertFalse(mHeadsetClientStateMachine.processAndroidSlcCommand( - "RANDOM ^%$# STRING", mTestDevice)); + Assert.assertFalse( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID= (SINKAUDIOPOLICY)", mTestDevice)); + Assert.assertFalse( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "RANDOM ^%$# STRING", mTestDevice)); Assert.assertFalse(mHeadsetClientStateMachine.processAndroidSlcCommand("", mTestDevice)); // False on incorrect BluetoothDevice - Assert.assertFalse(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: (SINKAUDIOPOLICY)", mAdapter.getRemoteDevice("05:04:01:02:03:00"))); + Assert.assertFalse( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID: (SINKAUDIOPOLICY)", + mAdapter.getRemoteDevice("05:04:01:02:03:00"))); } @Test @@ -428,34 +453,38 @@ public class HeadsetClientStateMachineTest { initToConnectedState(); mHeadsetClientStateMachine.setAudioPolicyRemoteSupported(false); - Assert.assertFalse(mHeadsetClientStateMachine.processAndroidSlcCommand( - "RANDOM ^%$# STRING", mTestDevice)); - Assert.assertEquals(BluetoothStatusCodes.FEATURE_NOT_SUPPORTED, + Assert.assertFalse( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "RANDOM ^%$# STRING", mTestDevice)); + Assert.assertEquals( + BluetoothStatusCodes.FEATURE_NOT_SUPPORTED, mHeadsetClientStateMachine.getAudioPolicyRemoteSupported()); mHeadsetClientStateMachine.setAudioPolicyRemoteSupported(false); - Assert.assertFalse(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID= (SINKAUDIOPOLICY)", mTestDevice)); - Assert.assertEquals(BluetoothStatusCodes.FEATURE_NOT_SUPPORTED, + Assert.assertFalse( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID= (SINKAUDIOPOLICY)", mTestDevice)); + Assert.assertEquals( + BluetoothStatusCodes.FEATURE_NOT_SUPPORTED, mHeadsetClientStateMachine.getAudioPolicyRemoteSupported()); mHeadsetClientStateMachine.setAudioPolicyRemoteSupported(false); - Assert.assertTrue(mHeadsetClientStateMachine.processAndroidSlcCommand( - "+ANDROID: (SINKAUDIOPOLICY)", mTestDevice)); - Assert.assertEquals(BluetoothStatusCodes.FEATURE_SUPPORTED, + Assert.assertTrue( + mHeadsetClientStateMachine.processAndroidSlcCommand( + "+ANDROID: (SINKAUDIOPOLICY)", mTestDevice)); + Assert.assertEquals( + BluetoothStatusCodes.FEATURE_SUPPORTED, mHeadsetClientStateMachine.getAudioPolicyRemoteSupported()); } - /** - * Test that In Band Ringtone information is relayed from phone. - */ + /** Test that In Band Ringtone information is relayed from phone. */ @LargeTest @Test @FlakyTest public void testInBandRingtone() { // Return true for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); Assert.assertEquals(false, mHeadsetClientStateMachine.getInBandRing()); @@ -470,11 +499,14 @@ public class HeadsetClientStateMachineTest { // Verify that one connection state broadcast is executed ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); - verify(mHeadsetClientService, - timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastMultiplePermissionsIndex++)) - .sendBroadcastMultiplePermissions(intentArgument.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + verify( + mHeadsetClientService, + timeout(STANDARD_WAIT_MILLIS) + .times(expectedBroadcastMultiplePermissionsIndex++)) + .sendBroadcastMultiplePermissions( + intentArgument.capture(), any(String[].class), any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); // Send a message to trigger SLC connection @@ -487,12 +519,15 @@ public class HeadsetClientStateMachineTest { setUpAndroidAt(false); - verify(mHeadsetClientService, - timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastMultiplePermissionsIndex++)) - .sendBroadcastMultiplePermissions(intentArgument.capture(), - any(String[].class), any(BroadcastOptions.class)); + verify( + mHeadsetClientService, + timeout(STANDARD_WAIT_MILLIS) + .times(expectedBroadcastMultiplePermissionsIndex++)) + .sendBroadcastMultiplePermissions( + intentArgument.capture(), any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, intentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(true)); @@ -507,12 +542,12 @@ public class HeadsetClientStateMachineTest { eventInBandRing.device = mTestDevice; mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, eventInBandRing); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex++)) - .sendBroadcast( - intentArgument.capture(), - anyString(), any(Bundle.class)); - Assert.assertEquals(1, - intentArgument.getValue().getIntExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, - -1)); + .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + 1, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, -1)); Assert.assertEquals(true, mHeadsetClientStateMachine.getInBandRing()); // Simulate a new incoming phone call @@ -520,54 +555,55 @@ public class HeadsetClientStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, eventCallStatusUpdated); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - verify(mHeadsetClientService, - timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex - 1)) - .sendBroadcast( - intentArgument.capture(), - anyString(),any(Bundle.class)); + verify( + mHeadsetClientService, + timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex - 1)) + .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); // Provide information about the new call StackEvent eventIncomingCall = new StackEvent(StackEvent.EVENT_TYPE_CURRENT_CALLS); - eventIncomingCall.valueInt = 1; //index - eventIncomingCall.valueInt2 = 1; //direction - eventIncomingCall.valueInt3 = 4; //state - eventIncomingCall.valueInt4 = 0; //multi party - eventIncomingCall.valueString = "5551212"; //phone number + eventIncomingCall.valueInt = 1; // index + eventIncomingCall.valueInt2 = 1; // direction + eventIncomingCall.valueInt3 = 4; // state + eventIncomingCall.valueInt4 = 0; // multi party + eventIncomingCall.valueString = "5551212"; // phone number eventIncomingCall.device = mTestDevice; mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, eventIncomingCall); - verify(mHeadsetClientService, - timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex - 1)) - .sendBroadcast( - intentArgument.capture(), - anyString(), any(Bundle.class)); - + verify( + mHeadsetClientService, + timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex - 1)) + .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); // Signal that the complete list of calls was received. StackEvent eventCommandStatus = new StackEvent(StackEvent.EVENT_TYPE_CMD_RESULT); eventCommandStatus.valueInt = AT_OK; mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, eventCommandStatus); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - verify(mHeadsetClientService, - timeout(QUERY_CURRENT_CALLS_TEST_WAIT_MILLIS).times(expectedBroadcastIndex++)) - .sendBroadcast( - intentArgument.capture(), - anyString(), any(Bundle.class)); + verify( + mHeadsetClientService, + timeout(QUERY_CURRENT_CALLS_TEST_WAIT_MILLIS) + .times(expectedBroadcastIndex++)) + .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); // Verify that the new call is being registered with the inBandRing flag set. - Assert.assertEquals(true, - ((HfpClientCall) intentArgument.getValue().getParcelableExtra( - BluetoothHeadsetClient.EXTRA_CALL)).isInBandRing()); + Assert.assertEquals( + true, + ((HfpClientCall) + intentArgument + .getValue() + .getParcelableExtra(BluetoothHeadsetClient.EXTRA_CALL)) + .isInBandRing()); // Disable In Band Ring and verify state gets propagated. eventInBandRing.valueInt = 0; mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, eventInBandRing); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex++)) - .sendBroadcast( - intentArgument.capture(), - anyString(), any(Bundle.class)); - Assert.assertEquals(0, - intentArgument.getValue().getIntExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, - -1)); + .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); + Assert.assertEquals( + 0, + intentArgument + .getValue() + .getIntExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, -1)); Assert.assertEquals(false, mHeadsetClientStateMachine.getInBandRing()); } @@ -637,9 +673,10 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, connStCh); ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(startBroadcastIndex)) - .sendBroadcastMultiplePermissions(intentArgument.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + .sendBroadcastMultiplePermissions( + intentArgument.capture(), any(String[].class), any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, intentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); startBroadcastIndex++; return startBroadcastIndex; @@ -664,11 +701,13 @@ public class HeadsetClientStateMachineTest { ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(startBroadcastIndex)) - .sendBroadcastMultiplePermissions(intentArgument.capture(), - any(String[].class), any(BroadcastOptions.class)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, + .sendBroadcastMultiplePermissions( + intentArgument.capture(), any(String[].class), any(BroadcastOptions.class)); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, intentArgument.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(true)); @@ -677,8 +716,8 @@ public class HeadsetClientStateMachineTest { } /** - * Set up and verify AT Android related commands and events. - * Make sure this method is invoked after SLC is setup. + * Set up and verify AT Android related commands and events. Make sure this method is invoked + * after SLC is setup. */ private void setUpAndroidAt(boolean androidAtSupported) { verify(mNativeInterface).sendAndroidAt(mTestDevice, "+ANDROID=?"); @@ -697,7 +736,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, cmdResEvt); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertEquals(BluetoothStatusCodes.FEATURE_SUPPORTED, + Assert.assertEquals( + BluetoothStatusCodes.FEATURE_SUPPORTED, mHeadsetClientStateMachine.getAudioPolicyRemoteSupported()); } else { // receive CMD_RESULT CME_ERROR due to remote not supporting Android AT @@ -707,7 +747,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, cmdResEvt); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertEquals(BluetoothStatusCodes.FEATURE_NOT_SUPPORTED, + Assert.assertEquals( + BluetoothStatusCodes.FEATURE_NOT_SUPPORTED, mHeadsetClientStateMachine.getAudioPolicyRemoteSupported()); } } @@ -715,27 +756,29 @@ public class HeadsetClientStateMachineTest { /* Utility function: supported AT command should lead to native call */ private void runSupportedVendorAtCommand(String atCommand, int vendorId) { // Return true for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); expectedBroadcastIndex = setUpServiceLevelConnection(expectedBroadcastIndex); - Message msg = mHeadsetClientStateMachine.obtainMessage( - HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); + Message msg = + mHeadsetClientStateMachine.obtainMessage( + HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); mHeadsetClientStateMachine.sendMessage(msg); - verify(mNativeInterface, timeout(STANDARD_WAIT_MILLIS).times(1)).sendATCmd( - mTestDevice, - HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, - 0, 0, atCommand); + verify(mNativeInterface, timeout(STANDARD_WAIT_MILLIS).times(1)) + .sendATCmd( + mTestDevice, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, + 0, + 0, + atCommand); } - /** - * Test: supported vendor specific command: set operation - */ + /** Test: supported vendor specific command: set operation */ @LargeTest @Test public void testSupportedVendorAtCommandSet() { @@ -744,9 +787,7 @@ public class HeadsetClientStateMachineTest { runSupportedVendorAtCommand(atCommand, vendorId); } - /** - * Test: supported vendor specific command: read operation - */ + /** Test: supported vendor specific command: read operation */ @LargeTest @Test public void testSupportedVendorAtCommandRead() { @@ -758,25 +799,24 @@ public class HeadsetClientStateMachineTest { /* utility function: unsupported vendor specific command shall be filtered. */ public void runUnsupportedVendorAtCommand(String atCommand, int vendorId) { // Return true for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); expectedBroadcastIndex = setUpServiceLevelConnection(expectedBroadcastIndex); - Message msg = mHeadsetClientStateMachine.obtainMessage( - HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); + Message msg = + mHeadsetClientStateMachine.obtainMessage( + HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); mHeadsetClientStateMachine.sendMessage(msg); verify(mNativeInterface, timeout(STANDARD_WAIT_MILLIS).times(0)) .sendATCmd(any(), anyInt(), anyInt(), anyInt(), any()); } - /** - * Test: unsupported vendor specific command shall be filtered: bad command code - */ + /** Test: unsupported vendor specific command shall be filtered: bad command code */ @LargeTest @Test public void testUnsupportedVendorAtCommandBadCode() { @@ -785,10 +825,7 @@ public class HeadsetClientStateMachineTest { runUnsupportedVendorAtCommand(atCommand, vendorId); } - /** - * Test: unsupported vendor specific command shall be filtered: - * no back to back command - */ + /** Test: unsupported vendor specific command shall be filtered: no back to back command */ @LargeTest @Test public void testUnsupportedVendorAtCommandBackToBack() { @@ -800,17 +837,17 @@ public class HeadsetClientStateMachineTest { /* Utility test function: supported vendor specific event * shall lead to broadcast intent */ - private void runSupportedVendorEvent(int vendorId, String vendorEventCode, - String vendorEventArgument) { + private void runSupportedVendorEvent( + int vendorId, String vendorEventCode, String vendorEventArgument) { // Setup connection state machine to be in connected state - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; int expectedBroadcastMultiplePermissionsIndex = 1; expectedBroadcastMultiplePermissionsIndex = - setUpHfpClientConnection(expectedBroadcastMultiplePermissionsIndex); + setUpHfpClientConnection(expectedBroadcastMultiplePermissionsIndex); expectedBroadcastMultiplePermissionsIndex = - setUpServiceLevelConnection(expectedBroadcastMultiplePermissionsIndex); + setUpServiceLevelConnection(expectedBroadcastMultiplePermissionsIndex); // Simulate a known event arrive String vendorEvent = vendorEventCode + vendorEventArgument; @@ -823,21 +860,25 @@ public class HeadsetClientStateMachineTest { ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex)) .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothHeadsetClient.ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT, + Assert.assertEquals( + BluetoothHeadsetClient.ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT, intentArgument.getValue().getAction()); - Assert.assertEquals(vendorId, + Assert.assertEquals( + vendorId, intentArgument.getValue().getIntExtra(BluetoothHeadsetClient.EXTRA_VENDOR_ID, -1)); - Assert.assertEquals(vendorEventCode, - intentArgument.getValue().getStringExtra( - BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_CODE)); - Assert.assertEquals(vendorEvent, - intentArgument.getValue().getStringExtra( - BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_FULL_ARGS)); + Assert.assertEquals( + vendorEventCode, + intentArgument + .getValue() + .getStringExtra(BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_CODE)); + Assert.assertEquals( + vendorEvent, + intentArgument + .getValue() + .getStringExtra(BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_FULL_ARGS)); } - /** - * Test: supported vendor specific response: response to read command - */ + /** Test: supported vendor specific response: response to read command */ @LargeTest @Test public void testSupportedVendorEventReadResponse() { @@ -847,9 +888,7 @@ public class HeadsetClientStateMachineTest { runSupportedVendorEvent(vendorId, vendorResponseCode, vendorResponseArgument); } - /** - * Test: supported vendor specific response: response to test command - */ + /** Test: supported vendor specific response: response to test command */ @LargeTest @Test public void testSupportedVendorEventTestResponse() { @@ -860,11 +899,11 @@ public class HeadsetClientStateMachineTest { } /* Utility test function: unsupported vendor specific response shall be filtered out*/ - public void runUnsupportedVendorEvent(int vendorId, String vendorEventCode, - String vendorEventArgument) { + public void runUnsupportedVendorEvent( + int vendorId, String vendorEventCode, String vendorEventArgument) { // Setup connection state machine to be in connected state - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); expectedBroadcastIndex = setUpServiceLevelConnection(expectedBroadcastIndex); @@ -881,9 +920,7 @@ public class HeadsetClientStateMachineTest { .sendBroadcast(any(), anyString(), any(Bundle.class)); } - /** - * Test unsupported vendor response: bad read response - */ + /** Test unsupported vendor response: bad read response */ @LargeTest @Test public void testUnsupportedVendorEventBadReadResponse() { @@ -893,9 +930,7 @@ public class HeadsetClientStateMachineTest { runUnsupportedVendorEvent(vendorId, vendorResponseCode, vendorResponseArgument); } - /** - * Test unsupported vendor response: bad test response - */ + /** Test unsupported vendor response: bad test response */ @LargeTest @Test public void testUnsupportedVendorEventBadTestResponse() { @@ -905,24 +940,22 @@ public class HeadsetClientStateMachineTest { runUnsupportedVendorEvent(vendorId, vendorResponseCode, vendorResponseArgument); } - /** - * Test voice recognition state change broadcast. - */ + /** Test voice recognition state change broadcast. */ @MediumTest @Test public void testVoiceRecognitionStateChange() { // Setup connection state machine to be in connected state - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).startVoiceRecognition(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).stopVoiceRecognition(any(BluetoothDevice.class)); int expectedBroadcastIndex = 1; int expectedBroadcastMultiplePermissionsIndex = 1; expectedBroadcastMultiplePermissionsIndex = - setUpHfpClientConnection(expectedBroadcastMultiplePermissionsIndex); + setUpHfpClientConnection(expectedBroadcastMultiplePermissionsIndex); expectedBroadcastMultiplePermissionsIndex = - setUpServiceLevelConnection(expectedBroadcastMultiplePermissionsIndex); + setUpServiceLevelConnection(expectedBroadcastMultiplePermissionsIndex); // Simulate a voice recognition start mHeadsetClientStateMachine.sendMessage(VOICE_RECOGNITION_START); @@ -933,8 +966,9 @@ public class HeadsetClientStateMachineTest { event.valueInt = AT_OK; mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, event); - expectedBroadcastIndex = verifyVoiceRecognitionBroadcast(expectedBroadcastIndex, - HeadsetClientHalConstants.VR_STATE_STARTED); + expectedBroadcastIndex = + verifyVoiceRecognitionBroadcast( + expectedBroadcastIndex, HeadsetClientHalConstants.VR_STATE_STARTED); // Simulate a voice recognition stop mHeadsetClientStateMachine.sendMessage(VOICE_RECOGNITION_STOP); @@ -945,8 +979,8 @@ public class HeadsetClientStateMachineTest { event.valueInt = AT_OK; mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, event); - verifyVoiceRecognitionBroadcast(expectedBroadcastIndex, - HeadsetClientHalConstants.VR_STATE_STOPPED); + verifyVoiceRecognitionBroadcast( + expectedBroadcastIndex, HeadsetClientHalConstants.VR_STATE_STOPPED); } private int verifyVoiceRecognitionBroadcast(int expectedBroadcastIndex, int expectedState) { @@ -954,23 +988,23 @@ public class HeadsetClientStateMachineTest { ArgumentCaptor intentArgument = ArgumentCaptor.forClass(Intent.class); verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(expectedBroadcastIndex)) .sendBroadcast(intentArgument.capture(), anyString(), any(Bundle.class)); - Assert.assertEquals(BluetoothHeadsetClient.ACTION_AG_EVENT, - intentArgument.getValue().getAction()); - int state = intentArgument.getValue().getIntExtra( - BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, -1); + Assert.assertEquals( + BluetoothHeadsetClient.ACTION_AG_EVENT, intentArgument.getValue().getAction()); + int state = + intentArgument + .getValue() + .getIntExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, -1); Assert.assertEquals(expectedState, state); return expectedBroadcastIndex + 1; } - /** - * Test send BIEV command - */ + /** Test send BIEV command */ @MediumTest @Test public void testSendBIEVCommand() { // Setup connection state machine to be in connected state - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); expectedBroadcastIndex = setUpServiceLevelConnection(expectedBroadcastIndex); @@ -994,27 +1028,26 @@ public class HeadsetClientStateMachineTest { } /** - * Test state machine shall try to send AT+BIEV command to AG - * to update an init battery level. + * Test state machine shall try to send AT+BIEV command to AG to update an init battery level. */ @MediumTest @Test public void testSendBatteryUpdateIndicatorWhenConnect() { // Setup connection state machine to be in connected state - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); expectedBroadcastIndex = setUpServiceLevelConnection(expectedBroadcastIndex); - verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(1)) - .updateBatteryLevel(); + verify(mHeadsetClientService, timeout(STANDARD_WAIT_MILLIS).times(1)).updateBatteryLevel(); } @Test public void testBroadcastAudioState() { - mHeadsetClientStateMachine.broadcastAudioState(mTestDevice, + mHeadsetClientStateMachine.broadcastAudioState( + mTestDevice, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED, BluetoothHeadsetClient.STATE_AUDIO_CONNECTING); @@ -1023,8 +1056,9 @@ public class HeadsetClientStateMachineTest { @Test public void testCallsInState() { - HfpClientCall call = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_WAITING, - "1", false, false, false); + HfpClientCall call = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_WAITING, "1", false, false, false); mHeadsetClientStateMachine.mCalls.put(0, call); Assert.assertEquals( @@ -1033,11 +1067,13 @@ public class HeadsetClientStateMachineTest { @Test public void testEnterPrivateMode() { - HfpClientCall call = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, - "1", true, false, false); + HfpClientCall call = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, "1", true, false, false); mHeadsetClientStateMachine.mCalls.put(0, call); - doReturn(true).when(mNativeInterface).handleCallAction(null, - HeadsetClientHalConstants.CALL_ACTION_CHLD_2X, 0); + doReturn(true) + .when(mNativeInterface) + .handleCallAction(null, HeadsetClientHalConstants.CALL_ACTION_CHLD_2X, 0); mHeadsetClientStateMachine.enterPrivateMode(0); @@ -1047,14 +1083,17 @@ public class HeadsetClientStateMachineTest { @Test public void testExplicitCallTransfer() { - HfpClientCall callOne = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, - "1", true, false, false); - HfpClientCall callTwo = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, - "1", true, false, false); + HfpClientCall callOne = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, "1", true, false, false); + HfpClientCall callTwo = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, "1", true, false, false); mHeadsetClientStateMachine.mCalls.put(0, callOne); mHeadsetClientStateMachine.mCalls.put(1, callTwo); - doReturn(true).when(mNativeInterface).handleCallAction(null, - HeadsetClientHalConstants.CALL_ACTION_CHLD_4, -1); + doReturn(true) + .when(mNativeInterface) + .handleCallAction(null, HeadsetClientHalConstants.CALL_ACTION_CHLD_4, -1); mHeadsetClientStateMachine.explicitCallTransfer(); @@ -1072,8 +1111,8 @@ public class HeadsetClientStateMachineTest { // Expect: Should not send +ANDROID to remote mHeadsetClientStateMachine.mCurrentDevice = mTestDevice; mHeadsetClientStateMachine.setAudioPolicyRemoteSupported(false); - verify(mNativeInterface, never()).sendAndroidAt(mTestDevice, - "+ANDROID=SINKAUDIOPOLICY,1,0,0"); + verify(mNativeInterface, never()) + .sendAndroidAt(mTestDevice, "+ANDROID=SINKAUDIOPOLICY,1,0,0"); // Case 2: if remote is supported and mForceSetAudioPolicyProperty is false // Expect: Should send +ANDROID=SINKAUDIOPOLICY,1,0,0 to remote @@ -1096,7 +1135,8 @@ public class HeadsetClientStateMachineTest { public void testGetAudioState_withCurrentDeviceNull() { Assert.assertNull(mHeadsetClientStateMachine.mCurrentDevice); - Assert.assertEquals(mHeadsetClientStateMachine.getAudioState(mTestDevice), + Assert.assertEquals( + mHeadsetClientStateMachine.getAudioState(mTestDevice), BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED); } @@ -1111,8 +1151,9 @@ public class HeadsetClientStateMachineTest { @Test public void testGetCall_withMatchingState() { - HfpClientCall call = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, - "1", true, false, false); + HfpClientCall call = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, "1", true, false, false); mHeadsetClientStateMachine.mCalls.put(0, call); int[] states = new int[1]; states[0] = HfpClientCall.CALL_STATE_ACTIVE; @@ -1122,8 +1163,9 @@ public class HeadsetClientStateMachineTest { @Test public void testGetCall_withNoMatchingState() { - HfpClientCall call = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_WAITING, - "1", true, false, false); + HfpClientCall call = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_WAITING, "1", true, false, false); mHeadsetClientStateMachine.mCalls.put(0, call); int[] states = new int[1]; states[0] = HfpClientCall.CALL_STATE_ACTIVE; @@ -1133,7 +1175,8 @@ public class HeadsetClientStateMachineTest { @Test public void testGetConnectionState_withNullDevice() { - Assert.assertEquals(mHeadsetClientStateMachine.getConnectionState(null), + Assert.assertEquals( + mHeadsetClientStateMachine.getConnectionState(null), BluetoothProfile.STATE_DISCONNECTED); } @@ -1141,17 +1184,23 @@ public class HeadsetClientStateMachineTest { public void testGetConnectionState_withNonNullDevice() { mHeadsetClientStateMachine.mCurrentDevice = mTestDevice; - Assert.assertEquals(mHeadsetClientStateMachine.getConnectionState(mTestDevice), + Assert.assertEquals( + mHeadsetClientStateMachine.getConnectionState(mTestDevice), BluetoothProfile.STATE_DISCONNECTED); } @Test public void testGetConnectionStateFromAudioState() { - Assert.assertEquals(HeadsetClientStateMachine.getConnectionStateFromAudioState( - BluetoothHeadsetClient.STATE_AUDIO_CONNECTED), BluetoothAdapter.STATE_CONNECTED); - Assert.assertEquals(HeadsetClientStateMachine.getConnectionStateFromAudioState( - BluetoothHeadsetClient.STATE_AUDIO_CONNECTING), BluetoothAdapter.STATE_CONNECTING); - Assert.assertEquals(HeadsetClientStateMachine.getConnectionStateFromAudioState( + Assert.assertEquals( + HeadsetClientStateMachine.getConnectionStateFromAudioState( + BluetoothHeadsetClient.STATE_AUDIO_CONNECTED), + BluetoothAdapter.STATE_CONNECTED); + Assert.assertEquals( + HeadsetClientStateMachine.getConnectionStateFromAudioState( + BluetoothHeadsetClient.STATE_AUDIO_CONNECTING), + BluetoothAdapter.STATE_CONNECTING); + Assert.assertEquals( + HeadsetClientStateMachine.getConnectionStateFromAudioState( BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED), BluetoothAdapter.STATE_DISCONNECTED); int invalidAudioState = 3; @@ -1164,7 +1213,8 @@ public class HeadsetClientStateMachineTest { public void testGetCurrentAgEvents() { Bundle bundle = mHeadsetClientStateMachine.getCurrentAgEvents(); - Assert.assertEquals(bundle.getString(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO), + Assert.assertEquals( + bundle.getString(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO), mHeadsetClientStateMachine.mSubscriberInfo); } @@ -1205,16 +1255,18 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.mChldFeatures = HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC; Bundle bundle = mHeadsetClientStateMachine.getCurrentAgFeaturesBundle(); Assert.assertTrue(bundle.getBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_3WAY_CALLING)); - Assert.assertTrue(bundle.getBoolean( - BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL)); + Assert.assertTrue( + bundle.getBoolean( + BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL)); mHeadsetClientStateMachine.mPeerFeatures = HeadsetClientHalConstants.PEER_FEAT_VREC; mHeadsetClientStateMachine.mChldFeatures = HeadsetClientHalConstants.CHLD_FEAT_REL; bundle = mHeadsetClientStateMachine.getCurrentAgFeaturesBundle(); Assert.assertTrue( bundle.getBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_VOICE_RECOGNITION)); - Assert.assertTrue(bundle.getBoolean( - BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL)); + Assert.assertTrue( + bundle.getBoolean( + BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL)); mHeadsetClientStateMachine.mPeerFeatures = HeadsetClientHalConstants.PEER_FEAT_REJECT; mHeadsetClientStateMachine.mChldFeatures = HeadsetClientHalConstants.CHLD_FEAT_REL_ACC; @@ -1237,8 +1289,9 @@ public class HeadsetClientStateMachineTest { @Test public void testGetCurrentCalls() { - HfpClientCall call = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_WAITING, - "1", true, false, false); + HfpClientCall call = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_WAITING, "1", true, false, false); mHeadsetClientStateMachine.mCalls.put(0, call); List currentCalls = mHeadsetClientStateMachine.getCurrentCalls(); @@ -1248,8 +1301,8 @@ public class HeadsetClientStateMachineTest { @Test public void testGetMessageName() { - Assert.assertEquals(HeadsetClientStateMachine.getMessageName(StackEvent.STACK_EVENT), - "STACK_EVENT"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName(StackEvent.STACK_EVENT), "STACK_EVENT"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.CONNECT), "CONNECT"); @@ -1259,17 +1312,23 @@ public class HeadsetClientStateMachineTest { Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.CONNECT_AUDIO), "CONNECT_AUDIO"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName( - HeadsetClientStateMachine.DISCONNECT_AUDIO), "DISCONNECT_AUDIO"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName(VOICE_RECOGNITION_START), + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName( + HeadsetClientStateMachine.DISCONNECT_AUDIO), + "DISCONNECT_AUDIO"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName(VOICE_RECOGNITION_START), "VOICE_RECOGNITION_START"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName(VOICE_RECOGNITION_STOP), + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName(VOICE_RECOGNITION_STOP), "VOICE_RECOGNITION_STOP"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.SET_MIC_VOLUME), "SET_MIC_VOLUME"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName( - HeadsetClientStateMachine.SET_SPEAKER_VOLUME), "SET_SPEAKER_VOLUME"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName( + HeadsetClientStateMachine.SET_SPEAKER_VOLUME), + "SET_SPEAKER_VOLUME"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.DIAL_NUMBER), "DIAL_NUMBER"); @@ -1285,43 +1344,54 @@ public class HeadsetClientStateMachineTest { Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.TERMINATE_CALL), "TERMINATE_CALL"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName(ENTER_PRIVATE_MODE), - "ENTER_PRIVATE_MODE"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName(ENTER_PRIVATE_MODE), "ENTER_PRIVATE_MODE"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.SEND_DTMF), "SEND_DTMF"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName(EXPLICIT_CALL_TRANSFER), + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName(EXPLICIT_CALL_TRANSFER), "EXPLICIT_CALL_TRANSFER"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.DISABLE_NREC), "DISABLE_NREC"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName( - HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND), "SEND_VENDOR_AT_COMMAND"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName( + HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND), + "SEND_VENDOR_AT_COMMAND"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.SEND_BIEV), "SEND_BIEV"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName( - HeadsetClientStateMachine.QUERY_CURRENT_CALLS), "QUERY_CURRENT_CALLS"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName( - HeadsetClientStateMachine.QUERY_OPERATOR_NAME), "QUERY_OPERATOR_NAME"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName( + HeadsetClientStateMachine.QUERY_CURRENT_CALLS), + "QUERY_CURRENT_CALLS"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName( + HeadsetClientStateMachine.QUERY_OPERATOR_NAME), + "QUERY_OPERATOR_NAME"); Assert.assertEquals( HeadsetClientStateMachine.getMessageName(HeadsetClientStateMachine.SUBSCRIBER_INFO), "SUBSCRIBER_INFO"); - Assert.assertEquals(HeadsetClientStateMachine.getMessageName( - HeadsetClientStateMachine.CONNECTING_TIMEOUT), "CONNECTING_TIMEOUT"); + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName( + HeadsetClientStateMachine.CONNECTING_TIMEOUT), + "CONNECTING_TIMEOUT"); int unknownMessageInt = 54; - Assert.assertEquals(HeadsetClientStateMachine.getMessageName(unknownMessageInt), + Assert.assertEquals( + HeadsetClientStateMachine.getMessageName(unknownMessageInt), "UNKNOWN(" + unknownMessageInt + ")"); } + /** - * Tests and verify behavior of the case where remote device doesn't support - * At Android but tries to send audio policy. + * Tests and verify behavior of the case where remote device doesn't support At Android but + * tries to send audio policy. */ @Test public void testAndroidAtRemoteNotSupported_StateTransition_setAudioPolicy() { // Setup connection state machine to be in connected state - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); @@ -1329,33 +1399,35 @@ public class HeadsetClientStateMachineTest { BluetoothSinkAudioPolicy dummyAudioPolicy = new BluetoothSinkAudioPolicy.Builder().build(); mHeadsetClientStateMachine.setAudioPolicy(dummyAudioPolicy); - verify(mNativeInterface, never()).sendAndroidAt(mTestDevice, - "+ANDROID=SINKAUDIOPOLICY,0,0,0"); + verify(mNativeInterface, never()) + .sendAndroidAt(mTestDevice, "+ANDROID=SINKAUDIOPOLICY,0,0,0"); } @SmallTest @Test public void testSetGetCallAudioPolicy() { // Return true for priority. - when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mHeadsetClientService.getConnectionPolicy(any(BluetoothDevice.class))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); int expectedBroadcastIndex = 1; expectedBroadcastIndex = setUpHfpClientConnection(expectedBroadcastIndex); expectedBroadcastIndex = setUpServiceLevelConnection(expectedBroadcastIndex, true); - BluetoothSinkAudioPolicy dummyAudioPolicy = new BluetoothSinkAudioPolicy.Builder() - .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .setActiveDevicePolicyAfterConnection(BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) - .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) - .build(); + BluetoothSinkAudioPolicy dummyAudioPolicy = + new BluetoothSinkAudioPolicy.Builder() + .setCallEstablishPolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .setActiveDevicePolicyAfterConnection( + BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) + .setInBandRingtonePolicy(BluetoothSinkAudioPolicy.POLICY_ALLOWED) + .build(); // Test if not support audio policy feature mHeadsetClientStateMachine.setAudioPolicyRemoteSupported(false); mHeadsetClientStateMachine.setAudioPolicy(dummyAudioPolicy); - verify(mNativeInterface, never()).sendAndroidAt(mTestDevice, - "+ANDROID=SINKAUDIOPOLICY,1,2,1"); + verify(mNativeInterface, never()) + .sendAndroidAt(mTestDevice, "+ANDROID=SINKAUDIOPOLICY,1,2,1"); Assert.assertEquals(0, mHeadsetClientStateMachine.mQueuedActions.size()); // Test setAudioPolicy @@ -1419,16 +1491,16 @@ public class HeadsetClientStateMachineTest { public void testProcessDisconnectMessage_onDisconnectedState() { mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.DISCONNECT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertEquals(STATE_DISCONNECTED, - mHeadsetClientStateMachine.getConnectionState(mTestDevice)); + Assert.assertEquals( + STATE_DISCONNECTED, mHeadsetClientStateMachine.getConnectionState(mTestDevice)); } @Test public void testProcessConnectMessage_onDisconnectedState() { doReturn(true).when(mNativeInterface).connect(any(BluetoothDevice.class)); sendMessageAndVerifyTransition( - mHeadsetClientStateMachine - .obtainMessage(HeadsetClientStateMachine.CONNECT, mTestDevice), + mHeadsetClientStateMachine.obtainMessage( + HeadsetClientStateMachine.CONNECT, mTestDevice), HeadsetClientStateMachine.Connecting.class); } @@ -1457,12 +1529,15 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessConnectMessage_onConnectingState() { initToConnectingState(); - assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - HeadsetClientStateMachine.CONNECT)).isFalse(); + assertThat( + mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( + HeadsetClientStateMachine.CONNECT)) + .isFalse(); mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertTrue(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - HeadsetClientStateMachine.CONNECT)); + Assert.assertTrue( + mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( + HeadsetClientStateMachine.CONNECT)); } @Test @@ -1485,7 +1560,8 @@ public class HeadsetClientStateMachineTest { event.device = mTestDevice; mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class)); } @@ -1497,7 +1573,8 @@ public class HeadsetClientStateMachineTest { event.device = mTestDevice; mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class)); } @@ -1507,13 +1584,13 @@ public class HeadsetClientStateMachineTest { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CALL); event.valueInt = StackEvent.EVENT_TYPE_CALL; event.device = mTestDevice; - assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - StackEvent.STACK_EVENT)).isFalse(); + assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages(StackEvent.STACK_EVENT)) + .isFalse(); mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertTrue(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - StackEvent.STACK_EVENT)); + Assert.assertTrue( + mHeadsetClientStateMachine.doesSuperHaveDeferredMessages(StackEvent.STACK_EVENT)); } @Test @@ -1524,7 +1601,8 @@ public class HeadsetClientStateMachineTest { event.device = mTestDevice; mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class)); } @@ -1539,7 +1617,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(true)); } @@ -1547,8 +1626,9 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessConnectTimeoutMessage_onConnectingState() { initToConnectingState(); - Message msg = mHeadsetClientStateMachine - .obtainMessage(HeadsetClientStateMachine.CONNECTING_TIMEOUT); + Message msg = + mHeadsetClientStateMachine.obtainMessage( + HeadsetClientStateMachine.CONNECTING_TIMEOUT); sendMessageAndVerifyTransition(msg, HeadsetClientStateMachine.Disconnected.class); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(false)); } @@ -1559,13 +1639,13 @@ public class HeadsetClientStateMachineTest { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_IN_BAND_RINGTONE); event.valueInt = StackEvent.EVENT_TYPE_IN_BAND_RINGTONE; event.device = mTestDevice; - assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - StackEvent.STACK_EVENT)).isFalse(); + assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages(StackEvent.STACK_EVENT)) + .isFalse(); mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - StackEvent.STACK_EVENT)).isTrue(); + assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages(StackEvent.STACK_EVENT)) + .isTrue(); } @Test @@ -1573,7 +1653,8 @@ public class HeadsetClientStateMachineTest { initToConnectedState(); mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class)); } @@ -1612,19 +1693,22 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessDisconnectMessage_onAudioOnState() { initToAudioOnState(); - assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - HeadsetClientStateMachine.DISCONNECT)).isFalse(); + assertThat( + mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( + HeadsetClientStateMachine.DISCONNECT)) + .isFalse(); mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.DISCONNECT, mTestDevice); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertTrue(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( - HeadsetClientStateMachine.DISCONNECT)); + Assert.assertTrue( + mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( + HeadsetClientStateMachine.DISCONNECT)); } @Test public void testProcessDisconnectAudioMessage_onAudioOnState() { initToAudioOnState(); - mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.DISCONNECT_AUDIO, - mTestDevice); + mHeadsetClientStateMachine.sendMessage( + HeadsetClientStateMachine.DISCONNECT_AUDIO, mTestDevice); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mNativeInterface).disconnectAudio(any(BluetoothDevice.class)); } @@ -1632,13 +1716,13 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessHoldCall_onAudioOnState() { initToAudioOnState(); - HfpClientCall call = new HfpClientCall(mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, - "1", true, false, false); + HfpClientCall call = + new HfpClientCall( + mTestDevice, 0, HfpClientCall.CALL_STATE_ACTIVE, "1", true, false, false); mHeadsetClientStateMachine.mCalls.put(0, call); int[] states = new int[1]; states[0] = HfpClientCall.CALL_STATE_ACTIVE; - mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.HOLD_CALL, - mTestDevice); + mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.HOLD_CALL, mTestDevice); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); verify(mNativeInterface).handleCallAction(any(BluetoothDevice.class), anyInt(), eq(0)); } @@ -1646,7 +1730,8 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessStackEvent_ConnectionStateChanged_onAudioOnState() { initToAudioOnState(); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.AudioOn.class)); StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED; @@ -1654,7 +1739,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Disconnected.class)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(false)); } @@ -1662,7 +1748,8 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessStackEvent_AudioStateChanged_onAudioOnState() { initToAudioOnState(); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.AudioOn.class)); StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED); event.valueInt = HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED; @@ -1670,7 +1757,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class)); } @@ -1718,8 +1806,8 @@ public class HeadsetClientStateMachineTest { private void initToConnectingState() { doReturn(true).when(mNativeInterface).connect(any(BluetoothDevice.class)); sendMessageAndVerifyTransition( - mHeadsetClientStateMachine - .obtainMessage(HeadsetClientStateMachine.CONNECT, mTestDevice), + mHeadsetClientStateMachine.obtainMessage( + HeadsetClientStateMachine.CONNECT, mTestDevice), HeadsetClientStateMachine.Connecting.class); } @@ -1732,7 +1820,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class)); verify(mHeadsetService).updateInbandRinging(eq(mTestDevice), eq(true)); } @@ -1746,7 +1835,8 @@ public class HeadsetClientStateMachineTest { mHeadsetClientStateMachine.sendMessage( mHeadsetClientStateMachine.obtainMessage(StackEvent.STACK_EVENT, event)); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(HeadsetClientStateMachine.AudioOn.class)); } @@ -1754,11 +1844,11 @@ public class HeadsetClientStateMachineTest { Mockito.clearInvocations(mHeadsetClientService); mHeadsetClientStateMachine.sendMessage(msg); // Verify that one connection state broadcast is executed - verify(mHeadsetClientService, timeout(TIMEOUT_MS)).sendBroadcastMultiplePermissions( - any(Intent.class), any(String[].class), any(BroadcastOptions.class) - ); - Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(), - IsInstanceOf.instanceOf(type)); + verify(mHeadsetClientService, timeout(TIMEOUT_MS)) + .sendBroadcastMultiplePermissions( + any(Intent.class), any(String[].class), any(BroadcastOptions.class)); + Assert.assertThat( + mHeadsetClientStateMachine.getCurrentState(), IsInstanceOf.instanceOf(type)); } public static class TestHeadsetClientStateMachine extends HeadsetClientStateMachine { @@ -1766,8 +1856,11 @@ public class HeadsetClientStateMachineTest { Boolean allowConnect = null; boolean mForceSetAudioPolicyProperty = false; - TestHeadsetClientStateMachine(HeadsetClientService context, HeadsetService headsetService, - Looper looper, NativeInterface nativeInterface) { + TestHeadsetClientStateMachine( + HeadsetClientService context, + HeadsetService headsetService, + Looper looper, + NativeInterface nativeInterface) { super(context, headsetService, looper, nativeInterface); } @@ -1790,7 +1883,7 @@ public class HeadsetClientStateMachineTest { return 1; } - void setForceSetAudioPolicyProperty(boolean flag){ + void setForceSetAudioPolicyProperty(boolean flag) { mForceSetAudioPolicyProperty = flag; } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java index 5dc40be3144..f2e887db88f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java @@ -36,13 +36,11 @@ import org.mockito.junit.MockitoRule; public class HfpNativeInterfaceTest { private static final byte[] TEST_DEVICE_ADDRESS = - new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - HeadsetClientService mService; - @Mock - AdapterService mAdapterService; + @Mock HeadsetClientService mService; + @Mock AdapterService mAdapterService; private NativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java index 8c82602f344..7aaba84f594 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java @@ -35,10 +35,23 @@ public class StackEventTest { int type = StackEvent.EVENT_TYPE_RING_INDICATION; StackEvent event = new StackEvent(type); - String expectedString = "StackEvent {type:" + StackEvent.eventTypeToString(type) - + ", value1:" + event.valueInt + ", value2:" + event.valueInt2 + ", value3:" - + event.valueInt3 + ", value4:" + event.valueInt4 + ", string: \"" - + event.valueString + "\"" + ", device:" + event.device + "}"; + String expectedString = + "StackEvent {type:" + + StackEvent.eventTypeToString(type) + + ", value1:" + + event.valueInt + + ", value2:" + + event.valueInt2 + + ", value3:" + + event.valueInt3 + + ", value4:" + + event.valueInt4 + + ", string: \"" + + event.valueString + + "\"" + + ", device:" + + event.device + + "}"; assertThat(event.toString()).isEqualTo(expectedString); } @@ -54,8 +67,8 @@ public class StackEventTest { if (t == int.class) { int stackEventType = field.getInt(null); if (fieldName.equals("EVENT_TYPE_UNKNOWN_EVENT")) { - assertThat(StackEvent.eventTypeToString(stackEventType)).isEqualTo( - "EVENT_TYPE_UNKNOWN:" + stackEventType); + assertThat(StackEvent.eventTypeToString(stackEventType)) + .isEqualTo("EVENT_TYPE_UNKNOWN:" + stackEventType); } else { String eventTypeToString = StackEvent.eventTypeToString(stackEventType); assertThat(eventTypeToString).isEqualTo(fieldName); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java index 48428b70447..aa39028d3dc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java @@ -51,10 +51,8 @@ public class VendorCommandResponseProcessorTest { @Mock private NativeInterface mNativeInterface; private VendorCommandResponseProcessor mProcessor; - @Mock - private AdapterService mAdapterService; - @Mock - private HeadsetClientService mHeadsetClientService; + @Mock private AdapterService mAdapterService; + @Mock private HeadsetClientService mHeadsetClientService; @Before public void setUp() throws Exception { @@ -94,9 +92,14 @@ public class VendorCommandResponseProcessorTest { @Test public void sendCommand_withEqualSign() { String atCommand = "+XAPL="; - doReturn(true).when(mNativeInterface).sendATCmd(mTestDevice, - HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, 0, 0, - atCommand); + doReturn(true) + .when(mNativeInterface) + .sendATCmd( + mTestDevice, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, + 0, + 0, + atCommand); assertThat(mProcessor.sendCommand(TEST_VENDOR_ID, atCommand, mTestDevice)).isTrue(); } @@ -104,9 +107,14 @@ public class VendorCommandResponseProcessorTest { @Test public void sendCommand_withQuestionMarkSign() { String atCommand = "+APLSIRI?"; - doReturn(true).when(mNativeInterface).sendATCmd(mTestDevice, - HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, 0, 0, - atCommand); + doReturn(true) + .when(mNativeInterface) + .sendATCmd( + mTestDevice, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, + 0, + 0, + atCommand); assertThat(mProcessor.sendCommand(TEST_VENDOR_ID, atCommand, mTestDevice)).isTrue(); } @@ -114,9 +122,14 @@ public class VendorCommandResponseProcessorTest { @Test public void sendCommand_failingToSendATCommand() { String atCommand = "+APLSIRI?"; - doReturn(false).when(mNativeInterface).sendATCmd(mTestDevice, - HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, 0, 0, - atCommand); + doReturn(false) + .when(mNativeInterface) + .sendATCmd( + mTestDevice, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, + 0, + 0, + atCommand); assertThat(mProcessor.sendCommand(TEST_VENDOR_ID, atCommand, mTestDevice)).isFalse(); } @@ -148,4 +161,4 @@ public class VendorCommandResponseProcessorTest { assertThat(mProcessor.processEvent(atString, mTestDevice)).isTrue(); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java index 68918e5965e..d7af650d943 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java @@ -45,17 +45,26 @@ import java.util.Set; public class HeadsetClientServiceInterfaceTest { private static final String TEST_DEVICE_ADDRESS = "00:11:22:33:44:55"; private static final BluetoothDevice TEST_DEVICE = - ((BluetoothManager) InstrumentationRegistry.getTargetContext() - .getSystemService(Context.BLUETOOTH_SERVICE)) - .getAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS); + ((BluetoothManager) + InstrumentationRegistry.getTargetContext() + .getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter() + .getRemoteDevice(TEST_DEVICE_ADDRESS); private static final String TEST_NUMBER = "000-111-2222"; private static final byte TEST_CODE = 0; private static final int TEST_CALL_INDEX = 0; - private static final HfpClientCall TEST_CALL = new HfpClientCall(TEST_DEVICE, /* id= */ 0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */false, /* inBandRing= */true); + private static final HfpClientCall TEST_CALL = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true); private static final int TEST_FLAGS = 0; private static final Bundle TEST_BUNDLE = new Bundle(); + static { TEST_BUNDLE.putInt("test_int", 0); } @@ -80,7 +89,7 @@ public class HeadsetClientServiceInterfaceTest { private void makeHeadsetClientServiceAvailable() { when(mMockHeadsetClientService.isAvailable()).thenReturn(true); assertThat(HeadsetClientService.getHeadsetClientService()) - .isEqualTo(mMockHeadsetClientService); + .isEqualTo(mMockHeadsetClientService); } @Test @@ -97,11 +106,13 @@ public class HeadsetClientServiceInterfaceTest { assertThat(mServiceInterface.enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX)).isFalse(); makeHeadsetClientServiceAvailable(); - doReturn(false).when(mMockHeadsetClientService) - .enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX); + doReturn(false) + .when(mMockHeadsetClientService) + .enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX); assertThat(mServiceInterface.enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX)).isFalse(); - doReturn(true).when(mMockHeadsetClientService) - .enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX); + doReturn(true) + .when(mMockHeadsetClientService) + .enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX); assertThat(mServiceInterface.enterPrivateMode(TEST_DEVICE, TEST_CALL_INDEX)).isTrue(); } @@ -121,10 +132,12 @@ public class HeadsetClientServiceInterfaceTest { assertThat(mServiceInterface.terminateCall(TEST_DEVICE, TEST_CALL)).isFalse(); makeHeadsetClientServiceAvailable(); - doReturn(true).when(mMockHeadsetClientService) + doReturn(true) + .when(mMockHeadsetClientService) .terminateCall(TEST_DEVICE, TEST_CALL.getUUID()); assertThat(mServiceInterface.terminateCall(TEST_DEVICE, TEST_CALL)).isTrue(); - doReturn(false).when(mMockHeadsetClientService) + doReturn(false) + .when(mMockHeadsetClientService) .terminateCall(TEST_DEVICE, TEST_CALL.getUUID()); assertThat(mServiceInterface.terminateCall(TEST_DEVICE, TEST_CALL)).isFalse(); } @@ -237,4 +250,3 @@ public class HeadsetClientServiceInterfaceTest { assertThat(mServiceInterface.hasHfpClientEcc(TEST_DEVICE)).isTrue(); } } - diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientCallTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientCallTest.java index 8278a40e8f4..4e73a36b7fb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientCallTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientCallTest.java @@ -33,15 +33,24 @@ import org.junit.runner.RunWith; public class HfpClientCallTest { private static final String TEST_DEVICE_ADDRESS = "00:11:22:33:44:55"; private static final BluetoothDevice TEST_DEVICE = - ((BluetoothManager) InstrumentationRegistry.getTargetContext() - .getSystemService(Context.BLUETOOTH_SERVICE)) - .getAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS); + ((BluetoothManager) + InstrumentationRegistry.getTargetContext() + .getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter() + .getRemoteDevice(TEST_DEVICE_ADDRESS); private static final int TEST_ID = 0; private static final String TEST_NUMBER = "000-111-2222"; private static final String TEST_NUMBER_2 = "111-222-3333"; - private void assertCall(BluetoothDevice device, int id, int state, String number, - boolean isMultiParty, boolean isOutgoing, boolean isInBandRing, HfpClientCall call) { + private void assertCall( + BluetoothDevice device, + int id, + int state, + String number, + boolean isMultiParty, + boolean isOutgoing, + boolean isInBandRing, + HfpClientCall call) { assertThat(call).isNotNull(); assertThat(call.getDevice()).isEqualTo(device); assertThat(call.getId()).isEqualTo(id); @@ -58,189 +67,306 @@ public class HfpClientCallTest { @Test public void testCreateActiveCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + false, + true, + false, + call); } @Test public void testCreateHeldCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_HELD, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_HELD, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_HELD, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_HELD, + TEST_NUMBER, + false, + true, + false, + call); } @Test public void testCreateDialingCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_DIALING, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_DIALING, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_DIALING, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_DIALING, + TEST_NUMBER, + false, + true, + false, + call); } @Test public void testCreateAlertingCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_ALERTING, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ALERTING, TEST_NUMBER, false, - true, false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_ALERTING, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ALERTING, + TEST_NUMBER, + false, + true, + false, + call); } @Test public void testCreateIncomingCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_INCOMING, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ false, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_INCOMING, TEST_NUMBER, false, - false, false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_INCOMING, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_INCOMING, + TEST_NUMBER, + false, + false, + false, + call); } @Test public void testCreateWaitingCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_WAITING, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ false, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_WAITING, TEST_NUMBER, false, - false, false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_WAITING, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_WAITING, + TEST_NUMBER, + false, + false, + false, + call); } @Test public void testCreateHeldByResponseAndHoldCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ false, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, - TEST_NUMBER, false, false, false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, + TEST_NUMBER, + false, + false, + false, + call); } @Test public void testCreateTerminatedCall() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_TERMINATED, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ false, - /* inBandRing= */ false); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_TERMINATED, TEST_NUMBER, false, - false, false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_TERMINATED, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ false); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_TERMINATED, + TEST_NUMBER, + false, + false, + false, + call); } @Test public void testSetState() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + false, + true, + false, + call); call.setState(HfpClientCall.CALL_STATE_HELD); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_HELD, TEST_NUMBER, false, true, - false, call); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_HELD, + TEST_NUMBER, + false, + true, + false, + call); } @Test public void testSetNumber() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + false, + true, + false, + call); call.setNumber(TEST_NUMBER_2); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER_2, false, - true, false, call); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER_2, + false, + true, + false, + call); } @Test public void testSetMultiParty() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + false, + true, + false, + call); call.setMultiParty(true); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, true, true, - false, call); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + true, + true, + false, + call); } @Test public void testParcelable() { - HfpClientCall call = new HfpClientCall( - /* device= */ TEST_DEVICE, - /* call id= */ TEST_ID, - /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, - /* phone number= */ TEST_NUMBER, - /* multiParty= */ false, - /* outgoing= */ true, - /* inBandRing= */ false); - - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, false, true, - false, call); + HfpClientCall call = + new HfpClientCall( + /* device= */ TEST_DEVICE, + /* call id= */ TEST_ID, + /* call state= */ HfpClientCall.CALL_STATE_ACTIVE, + /* phone number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ false); + + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + false, + true, + false, + call); Parcel parcel = Parcel.obtain(); call.writeToParcel(parcel, 0 /* flags */); @@ -248,8 +374,15 @@ public class HfpClientCallTest { HfpClientCall callOut = HfpClientCall.CREATOR.createFromParcel(parcel); parcel.recycle(); - assertCall(TEST_DEVICE, TEST_ID, HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, false, true, - false, callOut); + assertCall( + TEST_DEVICE, + TEST_ID, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + false, + true, + false, + callOut); assertThat(HfpClientCall.CREATOR.newArray(5).length).isEqualTo(5); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java index a4258951d67..c3ebab4c974 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java @@ -64,9 +64,11 @@ import java.util.List; public class HfpClientConnectionServiceTest { private static final String TEST_DEVICE_ADDRESS = "00:11:22:33:44:55"; private static final BluetoothDevice TEST_DEVICE = - ((BluetoothManager) InstrumentationRegistry.getTargetContext() - .getSystemService(Context.BLUETOOTH_SERVICE)) - .getAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS); + ((BluetoothManager) + InstrumentationRegistry.getTargetContext() + .getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter() + .getRemoteDevice(TEST_DEVICE_ADDRESS); private static final String TEST_NUMBER = "000-111-2222"; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -100,24 +102,31 @@ public class HfpClientConnectionServiceTest { // attachBaseContext, but until we need a full context this is simpler. mHfpClientConnectionService = spy(new HfpClientConnectionService()); - doReturn("com.android.bluetooth.hfpclient").when(mHfpClientConnectionService) + doReturn("com.android.bluetooth.hfpclient") + .when(mHfpClientConnectionService) .getPackageName(); - doReturn(mHfpClientConnectionService).when(mHfpClientConnectionService) + doReturn(mHfpClientConnectionService) + .when(mHfpClientConnectionService) .getApplicationContext(); doReturn(mMockResources).when(mHfpClientConnectionService).getResources(); - doReturn(true).when(mMockResources) + doReturn(true) + .when(mMockResources) .getBoolean(R.bool.hfp_client_connection_service_support_emergency_call); - doReturn(Context.TELECOM_SERVICE).when(mHfpClientConnectionService) + doReturn(Context.TELECOM_SERVICE) + .when(mHfpClientConnectionService) .getSystemServiceName(TelecomManager.class); - doReturn(mMockTelecomManager).when(mHfpClientConnectionService) + doReturn(mMockTelecomManager) + .when(mHfpClientConnectionService) .getSystemService(Context.TELECOM_SERVICE); doReturn(getPhoneAccount(TEST_DEVICE)).when(mMockTelecomManager).getPhoneAccount(any()); - doReturn(Context.BLUETOOTH_SERVICE).when(mHfpClientConnectionService) + doReturn(Context.BLUETOOTH_SERVICE) + .when(mHfpClientConnectionService) .getSystemServiceName(BluetoothManager.class); doReturn(targetContext.getSystemService(BluetoothManager.class)) - .when(mHfpClientConnectionService).getSystemService(Context.BLUETOOTH_SERVICE); + .when(mHfpClientConnectionService) + .getSystemService(Context.BLUETOOTH_SERVICE); } @After @@ -130,8 +139,9 @@ public class HfpClientConnectionServiceTest { } private PhoneAccountHandle getPhoneAccountHandle(BluetoothDevice device) { - return new PhoneAccountHandle(new ComponentName(mHfpClientConnectionService, - HfpClientConnectionService.class), device.getAddress()); + return new PhoneAccountHandle( + new ComponentName(mHfpClientConnectionService, HfpClientConnectionService.class), + device.getAddress()); } private PhoneAccount getPhoneAccount(BluetoothDevice device) { @@ -145,8 +155,8 @@ public class HfpClientConnectionServiceTest { } private void setupDeviceConnection(BluetoothDevice device) throws Exception { - mHfpClientConnectionService.onConnectionStateChanged(device, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + mHfpClientConnectionService.onConnectionStateChanged( + device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); HfpClientDeviceBlock block = mHfpClientConnectionService.findBlockForDevice(TEST_DEVICE); assertThat(block).isNotNull(); assertThat(block.getDevice()).isEqualTo(TEST_DEVICE); @@ -171,8 +181,8 @@ public class HfpClientConnectionServiceTest { public void disconnectDevice_blockIsRemoved() throws Exception { createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientConnectionService.onConnectionStateChanged(TEST_DEVICE, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); + HfpClientConnectionService.onConnectionStateChanged( + TEST_DEVICE, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); assertThat(mHfpClientConnectionService.findBlockForDevice(TEST_DEVICE)).isNull(); } @@ -180,9 +190,15 @@ public class HfpClientConnectionServiceTest { public void callChanged_callAdded() throws Exception { createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */false, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true); HfpClientConnectionService.onCallChanged(TEST_DEVICE, call); HfpClientDeviceBlock block = mHfpClientConnectionService.findBlockForDevice(TEST_DEVICE); assertThat(block).isNotNull(); @@ -194,7 +210,8 @@ public class HfpClientConnectionServiceTest { public void audioStateChanged_scoStateChanged() throws Exception { createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientConnectionService.onAudioStateChanged(TEST_DEVICE, + HfpClientConnectionService.onAudioStateChanged( + TEST_DEVICE, HeadsetClientHalConstants.AUDIO_STATE_CONNECTED, HeadsetClientHalConstants.AUDIO_STATE_CONNECTING); HfpClientDeviceBlock block = mHfpClientConnectionService.findBlockForDevice(TEST_DEVICE); @@ -209,21 +226,27 @@ public class HfpClientConnectionServiceTest { createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */false, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true); Bundle extras = new Bundle(); - extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); - ConnectionRequest connectionRequest = new ConnectionRequest.Builder().setExtras( - extras).build(); + extras.putParcelable( + TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); + ConnectionRequest connectionRequest = + new ConnectionRequest.Builder().setExtras(extras).build(); HfpClientConnectionService.onCallChanged(TEST_DEVICE, call); - Connection connection = mHfpClientConnectionService.onCreateIncomingConnection( - getPhoneAccountHandle(TEST_DEVICE), - connectionRequest); + Connection connection = + mHfpClientConnectionService.onCreateIncomingConnection( + getPhoneAccountHandle(TEST_DEVICE), connectionRequest); assertThat(connection).isNotNull(); assertThat(((HfpClientConnection) connection).getDevice()).isEqualTo(TEST_DEVICE); @@ -235,22 +258,30 @@ public class HfpClientConnectionServiceTest { createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */true, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ true); doReturn(call).when(mMockHeadsetClientService).dial(TEST_DEVICE, TEST_NUMBER); Bundle extras = new Bundle(); - extras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); - ConnectionRequest connectionRequest = new ConnectionRequest.Builder().setExtras( - extras).setAddress(Uri.fromParts( - PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)).build(); - - Connection connection = mHfpClientConnectionService.onCreateOutgoingConnection( - getPhoneAccountHandle(TEST_DEVICE), - connectionRequest); + extras.putParcelable( + TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); + ConnectionRequest connectionRequest = + new ConnectionRequest.Builder() + .setExtras(extras) + .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)) + .build(); + + Connection connection = + mHfpClientConnectionService.onCreateOutgoingConnection( + getPhoneAccountHandle(TEST_DEVICE), connectionRequest); assertThat(connection).isNotNull(); assertThat(((HfpClientConnection) connection).getDevice()).isEqualTo(TEST_DEVICE); @@ -262,22 +293,30 @@ public class HfpClientConnectionServiceTest { createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */true, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ true); Bundle extras = new Bundle(); - extras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); - ConnectionRequest connectionRequest = new ConnectionRequest.Builder().setExtras( - extras).setAddress(Uri.fromParts( - PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)).build(); + extras.putParcelable( + TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); + ConnectionRequest connectionRequest = + new ConnectionRequest.Builder() + .setExtras(extras) + .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)) + .build(); HfpClientConnectionService.onCallChanged(TEST_DEVICE, call); - Connection connection = mHfpClientConnectionService.onCreateUnknownConnection( - getPhoneAccountHandle(TEST_DEVICE), - connectionRequest); + Connection connection = + mHfpClientConnectionService.onCreateUnknownConnection( + getPhoneAccountHandle(TEST_DEVICE), connectionRequest); assertThat(connection).isNotNull(); assertThat(((HfpClientConnection) connection).getDevice()).isEqualTo(TEST_DEVICE); @@ -285,82 +324,101 @@ public class HfpClientConnectionServiceTest { } @Test - public void onCreateIncomingConnection_phoneAccountIsNull_returnsNull() throws Exception{ + public void onCreateIncomingConnection_phoneAccountIsNull_returnsNull() throws Exception { doReturn(null).when(mMockTelecomManager).getPhoneAccount(any()); createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */false, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true); Bundle extras = new Bundle(); - extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); - ConnectionRequest connectionRequest = new ConnectionRequest.Builder().setExtras( - extras).build(); + extras.putParcelable( + TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); + ConnectionRequest connectionRequest = + new ConnectionRequest.Builder().setExtras(extras).build(); HfpClientConnectionService.onCallChanged(TEST_DEVICE, call); - Connection connection = mHfpClientConnectionService.onCreateIncomingConnection( - getPhoneAccountHandle(TEST_DEVICE), - connectionRequest); + Connection connection = + mHfpClientConnectionService.onCreateIncomingConnection( + getPhoneAccountHandle(TEST_DEVICE), connectionRequest); assertThat(connection).isNull(); } - @Test - public void onCreateOutgoingConnection_phoneAccountIsNull_returnsNull() throws Exception{ + public void onCreateOutgoingConnection_phoneAccountIsNull_returnsNull() throws Exception { doReturn(null).when(mMockTelecomManager).getPhoneAccount(any()); createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */true, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ true); doReturn(call).when(mMockHeadsetClientService).dial(TEST_DEVICE, TEST_NUMBER); Bundle extras = new Bundle(); - extras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); - ConnectionRequest connectionRequest = new ConnectionRequest.Builder().setExtras( - extras).setAddress(Uri.fromParts( - PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)).build(); - - Connection connection = mHfpClientConnectionService.onCreateOutgoingConnection( - getPhoneAccountHandle(TEST_DEVICE), - connectionRequest); + extras.putParcelable( + TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); + ConnectionRequest connectionRequest = + new ConnectionRequest.Builder() + .setExtras(extras) + .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)) + .build(); + + Connection connection = + mHfpClientConnectionService.onCreateOutgoingConnection( + getPhoneAccountHandle(TEST_DEVICE), connectionRequest); assertThat(connection).isNull(); } - @Test - public void onCreateUnknownConnection_phoneAccountIsNull_returnsNull() throws Exception{ + public void onCreateUnknownConnection_phoneAccountIsNull_returnsNull() throws Exception { doReturn(null).when(mMockTelecomManager).getPhoneAccount(any()); createService(); setupDeviceConnection(TEST_DEVICE); - HfpClientCall call = new HfpClientCall(TEST_DEVICE, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, /* number= */ TEST_NUMBER, - /* multiParty= */ false, /* outgoing= */true, /* inBandRing= */true); + HfpClientCall call = + new HfpClientCall( + TEST_DEVICE, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + /* number= */ TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ true, + /* inBandRing= */ true); Bundle extras = new Bundle(); - extras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); - ConnectionRequest connectionRequest = new ConnectionRequest.Builder().setExtras( - extras).setAddress(Uri.fromParts( - PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)).build(); + extras.putParcelable( + TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); + ConnectionRequest connectionRequest = + new ConnectionRequest.Builder() + .setExtras(extras) + .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, null)) + .build(); HfpClientConnectionService.onCallChanged(TEST_DEVICE, call); - Connection connection = mHfpClientConnectionService.onCreateUnknownConnection( - getPhoneAccountHandle(TEST_DEVICE), - connectionRequest); + Connection connection = + mHfpClientConnectionService.onCreateUnknownConnection( + getPhoneAccountHandle(TEST_DEVICE), connectionRequest); assertThat(connection).isNull(); } - } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java index 76d3552ca6e..e7e0f415e30 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java @@ -49,8 +49,7 @@ import java.util.Set; @MediumTest @RunWith(MockitoJUnitRunner.class) public class HfpClientConnectionTest { - @Rule - public MockitoRule rule = MockitoJUnit.rule(); + @Rule public MockitoRule rule = MockitoJUnit.rule(); private static final String EVENT_SCO_CONNECT = "com.android.bluetooth.hfpclient.SCO_CONNECT"; private static final String EVENT_SCO_DISCONNECT = @@ -63,20 +62,23 @@ public class HfpClientConnectionTest { private BluetoothDevice mBluetoothDevice; private HfpClientCall mCall; - @Mock - private HeadsetClientServiceInterface mMockServiceInterface; - @Mock - private Context mContext; - @Mock - private HfpClientConnectionService mHfpClientConnectionService; + @Mock private HeadsetClientServiceInterface mMockServiceInterface; + @Mock private Context mContext; + @Mock private HfpClientConnectionService mHfpClientConnectionService; @Before public void setUp() { - mBluetoothDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice( - TEST_DEVICE_ADDRESS); - mCall = new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, /* multiParty= */ - false, /* outgoing= */false, /* inBandRing= */true); + mBluetoothDevice = + BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS); + mCall = + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true); } @Test @@ -88,15 +90,18 @@ public class HfpClientConnectionTest { assertThat(mHfpClientConnection.getUUID()).isEqualTo(mCall.getUUID()); assertThat(mHfpClientConnection.getState()).isEqualTo(Connection.STATE_ACTIVE); assertThat(mHfpClientConnection.getAudioModeIsVoip()).isFalse(); - assertThat(mHfpClientConnection.getAddress()).isEqualTo( - Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, /* fragment= */ null)); - assertThat(mHfpClientConnection.getAddressPresentation()).isEqualTo( - TelecomManager.PRESENTATION_ALLOWED); - assertThat(mHfpClientConnection.getConnectionCapabilities()).isEqualTo( - Connection.CAPABILITY_SUPPORT_HOLD | Connection.CAPABILITY_MUTE - | Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE - | Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE - | Connection.CAPABILITY_HOLD); + assertThat(mHfpClientConnection.getAddress()) + .isEqualTo( + Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, /* fragment= */ null)); + assertThat(mHfpClientConnection.getAddressPresentation()) + .isEqualTo(TelecomManager.PRESENTATION_ALLOWED); + assertThat(mHfpClientConnection.getConnectionCapabilities()) + .isEqualTo( + Connection.CAPABILITY_SUPPORT_HOLD + | Connection.CAPABILITY_MUTE + | Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE + | Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE + | Connection.CAPABILITY_HOLD); } @Test @@ -111,15 +116,17 @@ public class HfpClientConnectionTest { assertThat(mHfpClientConnection.getExtras()).isNull(); assertThat(mHfpClientConnection.getState()).isEqualTo(Connection.STATE_DIALING); assertThat(mHfpClientConnection.getAudioModeIsVoip()).isFalse(); - assertThat(mHfpClientConnection.getAddress()).isEqualTo( - Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, /* fragment= */ null)); - assertThat(mHfpClientConnection.getAddressPresentation()).isEqualTo( - TelecomManager.PRESENTATION_ALLOWED); - assertThat(mHfpClientConnection.getConnectionCapabilities()).isEqualTo( - Connection.CAPABILITY_SUPPORT_HOLD | Connection.CAPABILITY_MUTE - | Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE - | Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE); - + assertThat(mHfpClientConnection.getAddress()) + .isEqualTo( + Uri.fromParts(PhoneAccount.SCHEME_TEL, TEST_NUMBER, /* fragment= */ null)); + assertThat(mHfpClientConnection.getAddressPresentation()) + .isEqualTo(TelecomManager.PRESENTATION_ALLOWED); + assertThat(mHfpClientConnection.getConnectionCapabilities()) + .isEqualTo( + Connection.CAPABILITY_SUPPORT_HOLD + | Connection.CAPABILITY_MUTE + | Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE + | Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE); } @Test @@ -136,11 +143,18 @@ public class HfpClientConnectionTest { @Test public void multiPartyCallOnAddedNotDisconnected_isInConference() { - mHfpClientConnection = createHfpClientConnectionWithExistingCall() - .setCall(new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, - "444-555-6666", /* multiParty= */true, /* outgoing= */ - false, /* inBandRing= */true)).build(); + mHfpClientConnection = + createHfpClientConnectionWithExistingCall() + .setCall( + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + "444-555-6666", + /* multiParty= */ true, + /* outgoing= */ false, + /* inBandRing= */ true)) + .build(); mHfpClientConnection.onAdded(); assertThat(mHfpClientConnection.inConference()).isTrue(); @@ -156,22 +170,36 @@ public class HfpClientConnectionTest { @Test public void multiPartyCallNotAddedNotDisconnected_notInConference() { - mHfpClientConnection = createHfpClientConnectionWithExistingCall() - .setCall(new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, - "444-555-6666", /* multiParty= */true, /* outgoing= */ - false, /* inBandRing= */true)).build(); + mHfpClientConnection = + createHfpClientConnectionWithExistingCall() + .setCall( + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + "444-555-6666", + /* multiParty= */ true, + /* outgoing= */ false, + /* inBandRing= */ true)) + .build(); assertThat(mHfpClientConnection.inConference()).isFalse(); } @Test public void multiPartyCallOnAddedDisconnected_notInConference() { - mHfpClientConnection = createHfpClientConnectionWithExistingCall() - .setCall(new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, - "444-555-6666", /* multiParty= */true, /* outgoing= */ - false, /* inBandRing= */true)).build(); + mHfpClientConnection = + createHfpClientConnectionWithExistingCall() + .setCall( + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + "444-555-6666", + /* multiParty= */ true, + /* outgoing= */ false, + /* inBandRing= */ true)) + .build(); mHfpClientConnection.onAdded(); mHfpClientConnection.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL)); @@ -193,10 +221,14 @@ public class HfpClientConnectionTest { assertThat(mHfpClientConnection.getCall()).isEqualTo(mCall); HfpClientCall newCall = - new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, - TEST_NUMBER_2, /* multiParty= */false, /* outgoing= */ - false, /* inBandRing= */true); + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER_2, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true); mHfpClientConnection.updateCall(newCall); assertThat(mHfpClientConnection.getCall()).isEqualTo(newCall); @@ -226,8 +258,7 @@ public class HfpClientConnectionTest { @Test public void handleCallChanged_heldByResponseAndHold() { mHfpClientConnection = createHfpClientConnectionWithExistingCall().build(); - mHfpClientConnection.getCall() - .setState(HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); + mHfpClientConnection.getCall().setState(HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); mHfpClientConnection.handleCallChanged(); assertThat(mHfpClientConnection.getState()).isEqualTo(Connection.STATE_HOLDING); @@ -239,8 +270,7 @@ public class HfpClientConnectionTest { mHfpClientConnection = createHfpClientConnectionWithExistingCall().build(); HfpClientConference mockConference = mock(HfpClientConference.class); mHfpClientConnection.setConference(mockConference); - mHfpClientConnection.getCall() - .setState(HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); + mHfpClientConnection.getCall().setState(HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); mHfpClientConnection.handleCallChanged(); verify(mockConference).setOnHold(); @@ -397,31 +427,38 @@ public class HfpClientConnectionTest { @Ignore("b/191783947") public void onUnhold_connectionServiceHasOneConnection_acceptsHeldCall() { mHfpClientConnection = createHfpClientConnectionWithExistingCall().build(); - when(mHfpClientConnectionService.getAllConnections()).thenReturn( - Set.of(mHfpClientConnection)); + when(mHfpClientConnectionService.getAllConnections()) + .thenReturn(Set.of(mHfpClientConnection)); mHfpClientConnection.onUnhold(); - verify(mMockServiceInterface).acceptCall(mBluetoothDevice, - HeadsetClientServiceInterface.CALL_ACCEPT_HOLD); + verify(mMockServiceInterface) + .acceptCall(mBluetoothDevice, HeadsetClientServiceInterface.CALL_ACCEPT_HOLD); } @Test @Ignore("b/191783947") public void onUnhold_connectionServiceHasMultipleConnections_doesNotAcceptHeldCall() { mHfpClientConnection = createHfpClientConnectionWithExistingCall().build(); - HfpClientConnection secondConnection = createHfpClientConnectionWithExistingCall() - .setCall(new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, - "444-555-6666", /* multiParty= */false, /* outgoing= */ - false, /* inBandRing= */true)).build(); - when(mHfpClientConnectionService.getAllConnections()).thenReturn( - Set.of(mHfpClientConnection, secondConnection)); + HfpClientConnection secondConnection = + createHfpClientConnectionWithExistingCall() + .setCall( + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + "444-555-6666", + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true)) + .build(); + when(mHfpClientConnectionService.getAllConnections()) + .thenReturn(Set.of(mHfpClientConnection, secondConnection)); mHfpClientConnection.onUnhold(); - verify(mMockServiceInterface, never()).acceptCall(mBluetoothDevice, - HeadsetClientServiceInterface.CALL_ACCEPT_HOLD); + verify(mMockServiceInterface, never()) + .acceptCall(mBluetoothDevice, HeadsetClientServiceInterface.CALL_ACCEPT_HOLD); } @Test @@ -430,8 +467,8 @@ public class HfpClientConnectionTest { mHfpClientConnection.onAnswer(); - verify(mMockServiceInterface).acceptCall(mBluetoothDevice, - HeadsetClientServiceInterface.CALL_ACCEPT_NONE); + verify(mMockServiceInterface) + .acceptCall(mBluetoothDevice, HeadsetClientServiceInterface.CALL_ACCEPT_NONE); } @Test @@ -501,8 +538,8 @@ public class HfpClientConnectionTest { @Override public HfpClientConnection build() { - return new HfpClientConnection(mBluetoothDevice, mCall, mHfpClientConnectionService, - mMockServiceInterface); + return new HfpClientConnection( + mBluetoothDevice, mCall, mHfpClientConnectionService, mMockServiceInterface); } } @@ -516,8 +553,11 @@ public class HfpClientConnectionTest { @Override public HfpClientConnection build() { - return new HfpClientConnection(mBluetoothDevice, Uri.parse(mNumber), - mHfpClientConnectionService, mMockServiceInterface); + return new HfpClientConnection( + mBluetoothDevice, + Uri.parse(mNumber), + mHfpClientConnectionService, + mMockServiceInterface); } } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java index c30e2b86a34..e92dd5dc593 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java @@ -51,18 +51,12 @@ public class HfpClientDeviceBlockTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private HeadsetClientService mHeadsetClientService; - @Mock - private HfpClientConnectionService mConnServ; - @Mock - private HeadsetClientServiceInterface mMockServiceInterface; - @Mock - private Context mApplicationContext; - @Mock - private Resources mResources; - @Mock - private TelecomManager mTelecomManager; + @Mock private HeadsetClientService mHeadsetClientService; + @Mock private HfpClientConnectionService mConnServ; + @Mock private HeadsetClientServiceInterface mMockServiceInterface; + @Mock private Context mApplicationContext; + @Mock private Resources mResources; + @Mock private TelecomManager mTelecomManager; private HfpClientDeviceBlock mHfpClientDeviceBlock; private BluetoothDevice mBluetoothDevice; @@ -73,8 +67,10 @@ public class HfpClientDeviceBlockTest { // HfpClientConnectionService.createAccount is static and can't be mocked, so the // application context and resources must be mocked to avoid NPE when creating an // HfpClientDeviceBlock for testing. - when(mResources.getBoolean(com.android.bluetooth.R.bool - .hfp_client_connection_service_support_emergency_call)).thenReturn(true); + when(mResources.getBoolean( + com.android.bluetooth.R.bool + .hfp_client_connection_service_support_emergency_call)) + .thenReturn(true); when(mApplicationContext.getResources()).thenReturn(mResources); when(mConnServ.getApplicationContext()).thenReturn(mApplicationContext); when(mConnServ.getPackageName()).thenReturn(TEST_PACKAGE); @@ -83,8 +79,8 @@ public class HfpClientDeviceBlockTest { when(mConnServ.getSystemServiceName(TelecomManager.class)) .thenReturn(Context.TELECOM_SERVICE); - mBluetoothDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice( - TEST_DEVICE_ADDRESS); + mBluetoothDevice = + BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS); when(mHeadsetClientService.isAvailable()).thenReturn(true); HeadsetClientService.setHeadsetClientService(mHeadsetClientService); @@ -92,11 +88,18 @@ public class HfpClientDeviceBlockTest { @Test public void testCreateOutgoingConnection_scoStateIsSet() { - setUpCall(new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, - /* multiParty= */false, /* outgoing= */false, /* inBandRing= */true)); - HfpClientConnection connection = createOutgoingConnectionWithScoState( - HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); + setUpCall( + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true)); + HfpClientConnection connection = + createOutgoingConnectionWithScoState( + HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); assertThat(connection.getExtras().getInt(KEY_SCO_STATE)) .isEqualTo(HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); @@ -104,15 +107,23 @@ public class HfpClientDeviceBlockTest { @Test public void testOnAudioStateChanged() { - setUpCall(new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, - /* multiParty= */false, /* outgoing= */false, /* inBandRing= */true)); - HfpClientConnection connection = createOutgoingConnectionWithScoState( - HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); + setUpCall( + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + /* multiParty= */ false, + /* outgoing= */ false, + /* inBandRing= */ true)); + HfpClientConnection connection = + createOutgoingConnectionWithScoState( + HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); assertThat(connection.getExtras().getInt(KEY_SCO_STATE)) .isEqualTo(HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); - mHfpClientDeviceBlock.onAudioStateChange(HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED, + mHfpClientDeviceBlock.onAudioStateChange( + HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED, HeadsetClientHalConstants.AUDIO_STATE_CONNECTED); assertThat(connection.getExtras().getInt(KEY_SCO_STATE)) @@ -123,9 +134,14 @@ public class HfpClientDeviceBlockTest { @Ignore("b/191783947") public void testHandleMultiPartyCall_scoStateIsSetOnConference() { HfpClientCall call = - new HfpClientCall(mBluetoothDevice, /* id= */0, - HfpClientCall.CALL_STATE_ACTIVE, TEST_NUMBER, /* multiParty= */ - true, /* outgoing= */false, /* inBandRing= */true); + new HfpClientCall( + mBluetoothDevice, + /* id= */ 0, + HfpClientCall.CALL_STATE_ACTIVE, + TEST_NUMBER, + /* multiParty= */ true, + /* outgoing= */ false, + /* inBandRing= */ true); setUpCall(call); createOutgoingConnectionWithScoState(HeadsetClientHalConstants.AUDIO_STATE_CONNECTING); @@ -147,9 +163,7 @@ public class HfpClientDeviceBlockTest { private HfpClientConnection createOutgoingConnectionWithScoState(int scoState) { when(mHeadsetClientService.getAudioState(mBluetoothDevice)).thenReturn(scoState); - doCallRealMethod() - .when(mConnServ) - .createAccount(any()); + doCallRealMethod().when(mConnServ).createAccount(any()); mHfpClientDeviceBlock = new HfpClientDeviceBlock(mBluetoothDevice, mConnServ, mMockServiceInterface); return mHfpClientDeviceBlock.onCreateOutgoingConnection( diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java index 86396c0f120..fac59958d8d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java @@ -44,8 +44,7 @@ public class BluetoothHidDeviceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private HidDeviceService mService; + @Mock private HidDeviceService mService; private AttributionSource mAttributionSource; private BluetoothDevice mTestDevice; private HidDeviceService.BluetoothHidDeviceBinder mBinder; @@ -71,20 +70,31 @@ public class BluetoothHidDeviceBinderTest { String provider = "test-provider"; byte subclass = 1; byte[] descriptors = new byte[] {10}; - BluetoothHidDeviceAppSdpSettings sdp = new BluetoothHidDeviceAppSdpSettings( - name, description, provider, subclass, descriptors); + BluetoothHidDeviceAppSdpSettings sdp = + new BluetoothHidDeviceAppSdpSettings( + name, description, provider, subclass, descriptors); int tokenRate = 800; int tokenBucketSize = 9; int peakBandwidth = 10; int latency = 11250; int delayVariation = BluetoothHidDeviceAppQosSettings.MAX; - BluetoothHidDeviceAppQosSettings inQos = new BluetoothHidDeviceAppQosSettings( - BluetoothHidDeviceAppQosSettings.SERVICE_BEST_EFFORT, tokenRate, - tokenBucketSize, peakBandwidth, latency, delayVariation); - BluetoothHidDeviceAppQosSettings outQos = new BluetoothHidDeviceAppQosSettings( - BluetoothHidDeviceAppQosSettings.SERVICE_BEST_EFFORT, tokenRate, - tokenBucketSize, peakBandwidth, latency, delayVariation); + BluetoothHidDeviceAppQosSettings inQos = + new BluetoothHidDeviceAppQosSettings( + BluetoothHidDeviceAppQosSettings.SERVICE_BEST_EFFORT, + tokenRate, + tokenBucketSize, + peakBandwidth, + latency, + delayVariation); + BluetoothHidDeviceAppQosSettings outQos = + new BluetoothHidDeviceAppQosSettings( + BluetoothHidDeviceAppQosSettings.SERVICE_BEST_EFFORT, + tokenRate, + tokenBucketSize, + peakBandwidth, + latency, + delayVariation); IBluetoothHidDeviceCallback cb = mock(IBluetoothHidDeviceCallback.class); mBinder.registerApp(sdp, inQos, outQos, cb, mAttributionSource); @@ -100,7 +110,7 @@ public class BluetoothHidDeviceBinderTest { @Test public void sendReport() { int id = 100; - byte[] data = new byte[] { 0x00, 0x01 }; + byte[] data = new byte[] {0x00, 0x01}; mBinder.sendReport(mTestDevice, id, data, mAttributionSource); verify(mService).sendReport(mTestDevice, id, data); } @@ -109,7 +119,7 @@ public class BluetoothHidDeviceBinderTest { public void replyReport() { byte type = 0; byte id = 100; - byte[] data = new byte[] { 0x00, 0x01 }; + byte[] data = new byte[] {0x00, 0x01}; mBinder.replyReport(mTestDevice, type, id, data, mAttributionSource); verify(mService).replyReport(mTestDevice, type, id, data); } @@ -160,7 +170,7 @@ public class BluetoothHidDeviceBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] { BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource); verify(mService).getDevicesMatchingConnectionStates(states); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java index 41b4006ee80..27bd6d6c1e9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java @@ -37,13 +37,11 @@ import org.mockito.junit.MockitoRule; public class HidDeviceNativeInterfaceTest { private static final byte[] TEST_DEVICE_ADDRESS = - new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - HidDeviceService mService; - @Mock - AdapterService mAdapterService; + @Mock HidDeviceService mService; + @Mock AdapterService mAdapterService; private HidDeviceNativeInterface mNativeInterface; @@ -69,8 +67,8 @@ public class HidDeviceNativeInterfaceTest { @Test public void onConnectStateChanged() { - mNativeInterface.onConnectStateChanged(TEST_DEVICE_ADDRESS, - BluetoothHidDevice.STATE_DISCONNECTED); + mNativeInterface.onConnectStateChanged( + TEST_DEVICE_ADDRESS, BluetoothHidDevice.STATE_DISCONNECTED); verify(mService).onConnectStateChangedFromNative(any(), anyInt()); } @@ -87,7 +85,7 @@ public class HidDeviceNativeInterfaceTest { public void onSetReport() { byte reportType = 1; byte reportId = 2; - byte[] data = new byte[] { 0x00, 0x00 }; + byte[] data = new byte[] {0x00, 0x00}; mNativeInterface.onSetReport(reportType, reportId, data); verify(mService).onSetReportFromNative(reportType, reportId, data); } @@ -102,7 +100,7 @@ public class HidDeviceNativeInterfaceTest { @Test public void onInterruptData() { byte reportId = 3; - byte[] data = new byte[] { 0x00, 0x00 }; + byte[] data = new byte[] {0x00, 0x00}; mNativeInterface.onInterruptData(reportId, data); verify(mService).onInterruptDataFromNative(reportId, data); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java index 4b6672ec6c2..a509da0730f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java @@ -57,8 +57,8 @@ import java.util.concurrent.TimeUnit; @MediumTest @RunWith(AndroidJUnit4.class) public class HidDeviceTest { - private static final int TIMEOUT_MS = 1000; // 1s - private static final byte[] SAMPLE_HID_REPORT = new byte[]{0x01, 0x00, 0x02}; + private static final int TIMEOUT_MS = 1000; // 1s + private static final byte[] SAMPLE_HID_REPORT = new byte[] {0x01, 0x00, 0x02}; private static final byte SAMPLE_REPORT_ID = 0x00; private static final byte SAMPLE_REPORT_TYPE = 0x00; private static final byte SAMPLE_REPORT_ERROR = 0x02; @@ -87,11 +87,11 @@ public class HidDeviceTest { private final BlockingQueue mConnectionStateChangedQueue = new LinkedBlockingQueue<>(); private final BlockingQueue mCallbackQueue = new LinkedBlockingQueue<>(); - private static void setHidDeviceNativeInterfaceInstance(HidDeviceNativeInterface instance) throws Exception { - Method method = HidDeviceNativeInterface.class.getDeclaredMethod("setInstance", - HidDeviceNativeInterface.class); + Method method = + HidDeviceNativeInterface.class.getDeclaredMethod( + "setInstance", HidDeviceNativeInterface.class); method.setAccessible(true); method.invoke(null, instance); } @@ -126,8 +126,13 @@ public class HidDeviceTest { Assert.assertEquals(nativeInterface, mHidDeviceNativeInterface); // Dummy SDP settings - mSettings = new BluetoothHidDeviceAppSdpSettings("Unit test", "test", "Android", - BluetoothHidDevice.SUBCLASS1_COMBO, new byte[]{}); + mSettings = + new BluetoothHidDeviceAppSdpSettings( + "Unit test", + "test", + "Android", + BluetoothHidDevice.SUBCLASS1_COMBO, + new byte[] {}); // Set up the Connection State Changed receiver IntentFilter filter = new IntentFilter(); @@ -174,15 +179,15 @@ public class HidDeviceTest { } } - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, int newState, - int prevState) { + private void verifyConnectionStateIntent( + int timeoutMs, BluetoothDevice device, int newState, int prevState) { Intent intent = waitForIntent(timeoutMs, mConnectionStateChangedQueue); Assert.assertNotNull(intent); Assert.assertEquals(BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED, intent.getAction()); Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(prevState, - intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); + Assert.assertEquals( + prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)); } private void verifyCallback(int timeoutMs, int callbackType, BlockingQueue queue) { @@ -209,9 +214,7 @@ public class HidDeviceTest { } } - public void onConnectionStateChanged(BluetoothDevice device, int state) { - - } + public void onConnectionStateChanged(BluetoothDevice device, int state) {} public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) { try { @@ -242,7 +245,6 @@ public class HidDeviceTest { mCallbackQueue.put(CALLBACK_ON_INTR_DATA); } catch (InterruptedException e) { throw new AssertionError("Cannot add Intent to the queue", e); - } } @@ -255,9 +257,7 @@ public class HidDeviceTest { } } - /** - * Test getting HidDeviceService: getHidDeviceService(). - */ + /** Test getting HidDeviceService: getHidDeviceService(). */ @Test public void testGetHidDeviceService() { Assert.assertEquals(mHidDeviceService, HidDeviceService.getHidDeviceService()); @@ -269,19 +269,40 @@ public class HidDeviceTest { */ @Test public void testRegistration() throws Exception { - doReturn(true).when(mHidDeviceNativeInterface) - .registerApp(anyString(), anyString(), anyString(), anyByte(), any(byte[].class), - isNull(), isNull()); - - verify(mHidDeviceNativeInterface, never()).registerApp(anyString(), anyString(), - anyString(), anyByte(), any(byte[].class), isNull(), isNull()); + doReturn(true) + .when(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); + + verify(mHidDeviceNativeInterface, never()) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); // Register app BluetoothHidDeviceCallbackTestHelper helper = new BluetoothHidDeviceCallbackTestHelper(); Assert.assertTrue(mHidDeviceService.registerApp(mSettings, null, null, helper)); - verify(mHidDeviceNativeInterface).registerApp(anyString(), anyString(), anyString(), - anyByte(), any(byte[].class), isNull(), isNull()); + verify(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); // App registered mHidDeviceService.onApplicationStateChangedFromNative(mTestDevice, true); @@ -295,23 +316,28 @@ public class HidDeviceTest { mHidDeviceService.onApplicationStateChangedFromNative(mTestDevice, false); verifyCallback(TIMEOUT_MS, CALLBACK_APP_UNREGISTERED, mCallbackQueue); - } - /** - * Test the logic in sendReport(). This should fail when the app is not registered. - */ + /** Test the logic in sendReport(). This should fail when the app is not registered. */ @Test public void testSendReport() throws Exception { doReturn(true).when(mHidDeviceNativeInterface).sendReport(anyInt(), any(byte[].class)); // sendReport() should fail without app registered - Assert.assertEquals(false, + Assert.assertEquals( + false, mHidDeviceService.sendReport(mTestDevice, SAMPLE_REPORT_ID, SAMPLE_HID_REPORT)); // Register app - doReturn(true).when(mHidDeviceNativeInterface) - .registerApp(anyString(), anyString(), anyString(), anyByte(), any(byte[].class), - isNull(), isNull()); + doReturn(true) + .when(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); BluetoothHidDeviceCallbackTestHelper helper = new BluetoothHidDeviceCallbackTestHelper(); Assert.assertTrue(mHidDeviceService.registerApp(mSettings, null, null, helper)); @@ -322,33 +348,41 @@ public class HidDeviceTest { verifyCallback(TIMEOUT_MS, CALLBACK_APP_REGISTERED, mCallbackQueue); // sendReport() should work when app is registered - Assert.assertEquals(true, + Assert.assertEquals( + true, mHidDeviceService.sendReport(mTestDevice, SAMPLE_REPORT_ID, SAMPLE_HID_REPORT)); - verify(mHidDeviceNativeInterface).sendReport(eq((int) SAMPLE_REPORT_ID), - eq(SAMPLE_HID_REPORT)); + verify(mHidDeviceNativeInterface) + .sendReport(eq((int) SAMPLE_REPORT_ID), eq(SAMPLE_HID_REPORT)); // Unregister app doReturn(true).when(mHidDeviceNativeInterface).unregisterApp(); Assert.assertEquals(true, mHidDeviceService.unregisterApp()); } - /** - * Test the logic in replyReport(). This should fail when the app is not registered. - */ + /** Test the logic in replyReport(). This should fail when the app is not registered. */ @Test public void testReplyReport() throws Exception { - doReturn(true).when(mHidDeviceNativeInterface) + doReturn(true) + .when(mHidDeviceNativeInterface) .replyReport(anyByte(), anyByte(), any(byte[].class)); // replyReport() should fail without app registered - Assert.assertEquals(false, - mHidDeviceService.replyReport(mTestDevice, SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, - SAMPLE_HID_REPORT)); + Assert.assertEquals( + false, + mHidDeviceService.replyReport( + mTestDevice, SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, SAMPLE_HID_REPORT)); // Register app - doReturn(true).when(mHidDeviceNativeInterface) - .registerApp(anyString(), anyString(), anyString(), anyByte(), any(byte[].class), - isNull(), isNull()); + doReturn(true) + .when(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); BluetoothHidDeviceCallbackTestHelper helper = new BluetoothHidDeviceCallbackTestHelper(); Assert.assertTrue(mHidDeviceService.registerApp(mSettings, null, null, helper)); @@ -359,21 +393,20 @@ public class HidDeviceTest { verifyCallback(TIMEOUT_MS, CALLBACK_APP_REGISTERED, mCallbackQueue); // replyReport() should work when app is registered - Assert.assertEquals(true, - mHidDeviceService.replyReport(mTestDevice, SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, - SAMPLE_HID_REPORT)); + Assert.assertEquals( + true, + mHidDeviceService.replyReport( + mTestDevice, SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, SAMPLE_HID_REPORT)); - verify(mHidDeviceNativeInterface).replyReport(eq(SAMPLE_REPORT_TYPE), eq(SAMPLE_REPORT_ID), - eq(SAMPLE_HID_REPORT)); + verify(mHidDeviceNativeInterface) + .replyReport(eq(SAMPLE_REPORT_TYPE), eq(SAMPLE_REPORT_ID), eq(SAMPLE_HID_REPORT)); // Unregister app doReturn(true).when(mHidDeviceNativeInterface).unregisterApp(); Assert.assertEquals(true, mHidDeviceService.unregisterApp()); } - /** - * Test the logic in reportError(). This should fail when the app is not registered. - */ + /** Test the logic in reportError(). This should fail when the app is not registered. */ @Test public void testReportError() throws Exception { doReturn(true).when(mHidDeviceNativeInterface).reportError(anyByte()); @@ -381,9 +414,16 @@ public class HidDeviceTest { Assert.assertEquals(false, mHidDeviceService.reportError(mTestDevice, SAMPLE_REPORT_ERROR)); // Register app - doReturn(true).when(mHidDeviceNativeInterface) - .registerApp(anyString(), anyString(), anyString(), anyByte(), any(byte[].class), - isNull(), isNull()); + doReturn(true) + .when(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); BluetoothHidDeviceCallbackTestHelper helper = new BluetoothHidDeviceCallbackTestHelper(); Assert.assertTrue(mHidDeviceService.registerApp(mSettings, null, null, helper)); @@ -403,18 +443,23 @@ public class HidDeviceTest { Assert.assertEquals(true, mHidDeviceService.unregisterApp()); } - /** - * Test that an outgoing connection/disconnection succeeds - */ + /** Test that an outgoing connection/disconnection succeeds */ @Test public void testOutgoingConnectDisconnectSuccess() { doReturn(true).when(mHidDeviceNativeInterface).connect(any(BluetoothDevice.class)); doReturn(true).when(mHidDeviceNativeInterface).disconnect(); // Register app - doReturn(true).when(mHidDeviceNativeInterface) - .registerApp(anyString(), anyString(), anyString(), anyByte(), any(byte[].class), - isNull(), isNull()); + doReturn(true) + .when(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); mHidDeviceService.registerApp(mSettings, null, null, null); // App registered @@ -423,48 +468,70 @@ public class HidDeviceTest { // Send a connect request Assert.assertTrue("Connect failed", mHidDeviceService.connect(mTestDevice)); - mHidDeviceService.onConnectStateChangedFromNative(mTestDevice, - HidDeviceService.HAL_CONN_STATE_CONNECTING); + mHidDeviceService.onConnectStateChangedFromNative( + mTestDevice, HidDeviceService.HAL_CONN_STATE_CONNECTING); // Verify the connection state broadcast - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mTestDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mHidDeviceService.getConnectionState(mTestDevice)); - mHidDeviceService.onConnectStateChangedFromNative(mTestDevice, - HidDeviceService.HAL_CONN_STATE_CONNECTED); + mHidDeviceService.onConnectStateChangedFromNative( + mTestDevice, HidDeviceService.HAL_CONN_STATE_CONNECTED); // Verify the connection state broadcast - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_CONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mTestDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mHidDeviceService.getConnectionState(mTestDevice)); // Verify the list of connected devices - Assert.assertTrue(mHidDeviceService.getDevicesMatchingConnectionStates( - new int[]{BluetoothProfile.STATE_CONNECTED}).contains(mTestDevice)); + Assert.assertTrue( + mHidDeviceService + .getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED}) + .contains(mTestDevice)); // Send a disconnect request Assert.assertTrue("Disconnect failed", mHidDeviceService.disconnect(mTestDevice)); - mHidDeviceService.onConnectStateChangedFromNative(mTestDevice, - HidDeviceService.HAL_CONN_STATE_DISCONNECTING); + mHidDeviceService.onConnectStateChangedFromNative( + mTestDevice, HidDeviceService.HAL_CONN_STATE_DISCONNECTING); // Verify the connection state broadcast - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mTestDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTING, mHidDeviceService.getConnectionState(mTestDevice)); - mHidDeviceService.onConnectStateChangedFromNative(mTestDevice, - HidDeviceService.HAL_CONN_STATE_DISCONNECTED); + mHidDeviceService.onConnectStateChangedFromNative( + mTestDevice, HidDeviceService.HAL_CONN_STATE_DISCONNECTED); // Verify the connection state broadcast - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mTestDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mHidDeviceService.getConnectionState(mTestDevice)); // Verify the list of connected devices - Assert.assertFalse(mHidDeviceService.getDevicesMatchingConnectionStates( - new int[]{BluetoothProfile.STATE_CONNECTED}).contains(mTestDevice)); + Assert.assertFalse( + mHidDeviceService + .getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED}) + .contains(mTestDevice)); // Unregister app doReturn(true).when(mHidDeviceNativeInterface).unregisterApp(); @@ -478,32 +545,53 @@ public class HidDeviceTest { */ @Test public void testCallbacks() { - doReturn(true).when(mHidDeviceNativeInterface) - .registerApp(anyString(), anyString(), anyString(), anyByte(), any(byte[].class), - isNull(), isNull()); - - verify(mHidDeviceNativeInterface, never()).registerApp(anyString(), anyString(), - anyString(), anyByte(), any(byte[].class), isNull(), isNull()); + doReturn(true) + .when(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); + + verify(mHidDeviceNativeInterface, never()) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); // Register app BluetoothHidDeviceCallbackTestHelper helper = new BluetoothHidDeviceCallbackTestHelper(); Assert.assertTrue(mHidDeviceService.registerApp(mSettings, null, null, helper)); - verify(mHidDeviceNativeInterface).registerApp(anyString(), anyString(), anyString(), - anyByte(), any(byte[].class), isNull(), isNull()); + verify(mHidDeviceNativeInterface) + .registerApp( + anyString(), + anyString(), + anyString(), + anyByte(), + any(byte[].class), + isNull(), + isNull()); // App registered mHidDeviceService.onApplicationStateChangedFromNative(mTestDevice, true); verifyCallback(TIMEOUT_MS, CALLBACK_APP_REGISTERED, mCallbackQueue); // Received callback: onGetReport - mHidDeviceService.onGetReportFromNative(SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, - SAMPLE_BUFFER_SIZE); + mHidDeviceService.onGetReportFromNative( + SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, SAMPLE_BUFFER_SIZE); verifyCallback(TIMEOUT_MS, CALLBACK_ON_GET_REPORT, mCallbackQueue); // Received callback: onSetReport - mHidDeviceService.onSetReportFromNative(SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, - SAMPLE_HID_REPORT); + mHidDeviceService.onSetReportFromNative( + SAMPLE_REPORT_TYPE, SAMPLE_REPORT_ID, SAMPLE_HID_REPORT); verifyCallback(TIMEOUT_MS, CALLBACK_ON_SET_REPORT, mCallbackQueue); // Received callback: onSetProtocol diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java index 8e1870c2ce5..39de9c8e0f2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java @@ -44,8 +44,7 @@ public class HidHostServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private HidHostService mService; + @Mock private HidHostService mService; BluetoothDevice mRemoteDevice; @@ -75,8 +74,8 @@ public class HidHostServiceBinderTest { public void getConnectedDevices_callsServiceMethod() { mBinder.getConnectedDevices(null); - verify(mService).getDevicesMatchingConnectionStates( - new int[] { BluetoothProfile.STATE_CONNECTED }); + verify(mService) + .getDevicesMatchingConnectionStates(new int[] {BluetoothProfile.STATE_CONNECTED}); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java index ee746db3c50..6bac16e14ff 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java @@ -84,45 +84,66 @@ public class HidHostServiceTest { Assert.assertNotNull(HidHostService.getHidHostService()); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testOkToConnect() { int badPriorityValue = 1024; int badBondState = 42; - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, badPriorityValue, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, badPriorityValue, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, badPriorityValue, false); - testOkToConnectCase(mTestDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mTestDevice, - badBondState, badPriorityValue, false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_NONE, badPriorityValue, false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDING, badPriorityValue, false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testOkToConnectCase(mTestDevice, BluetoothDevice.BOND_BONDED, badPriorityValue, false); + testOkToConnectCase( + mTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testOkToConnectCase( + mTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); + testOkToConnectCase( + mTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase(mTestDevice, badBondState, badPriorityValue, false); } @Test @@ -138,8 +159,8 @@ public class HidHostServiceTest { * @param priority value, could be invalid, could be invalid * @param expected expected result from okToConnect() */ - private void testOkToConnectCase(BluetoothDevice device, int bondState, int priority, - boolean expected) { + private void testOkToConnectCase( + BluetoothDevice device, int bondState, int priority, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HID_HOST)) .thenReturn(priority); diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java index 6a3443387d9..572eb95e51a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java @@ -45,10 +45,8 @@ import java.util.UUID; public class ContentControlIdKeeperTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - ServiceFactory mServiceFactoryMock; - @Mock - LeAudioService mLeAudioServiceMock; + @Mock ServiceFactory mServiceFactoryMock; + @Mock LeAudioService mLeAudioServiceMock; @Before public void setUp() throws Exception { @@ -64,33 +62,29 @@ public class ContentControlIdKeeperTest { public int testCcidAcquire(ParcelUuid uuid, int context, int expectedListSize) { int ccid = ContentControlIdKeeper.acquireCcid(uuid, context); - Assert.assertNotEquals( - ccid, - ContentControlIdKeeper.CCID_INVALID); + Assert.assertNotEquals(ccid, ContentControlIdKeeper.CCID_INVALID); - verify(mLeAudioServiceMock).setCcidInformation(eq(uuid), - eq(ccid), eq(context)); + verify(mLeAudioServiceMock).setCcidInformation(eq(uuid), eq(ccid), eq(context)); Map> uuidToCcidContextPair = ContentControlIdKeeper.getUuidToCcidContextPairMap(); Assert.assertEquals(expectedListSize, uuidToCcidContextPair.size()); Assert.assertTrue(uuidToCcidContextPair.containsKey(uuid)); - Assert.assertEquals(ccid, (long)uuidToCcidContextPair.get(uuid).first); - Assert.assertEquals(context, (long)uuidToCcidContextPair.get(uuid).second); + Assert.assertEquals(ccid, (long) uuidToCcidContextPair.get(uuid).first); + Assert.assertEquals(context, (long) uuidToCcidContextPair.get(uuid).second); return ccid; } public void testCcidRelease(ParcelUuid uuid, int ccid, int expectedListSize) { Map> uuidToCcidContextPair = - ContentControlIdKeeper.getUuidToCcidContextPairMap(); + ContentControlIdKeeper.getUuidToCcidContextPairMap(); Assert.assertTrue(uuidToCcidContextPair.containsKey(uuid)); ContentControlIdKeeper.releaseCcid(ccid); uuidToCcidContextPair = ContentControlIdKeeper.getUuidToCcidContextPairMap(); Assert.assertFalse(uuidToCcidContextPair.containsKey(uuid)); - verify(mLeAudioServiceMock).setCcidInformation(eq(uuid), - eq(ccid), eq(0)); + verify(mLeAudioServiceMock).setCcidInformation(eq(uuid), eq(ccid), eq(0)); Assert.assertEquals(expectedListSize, uuidToCcidContextPair.size()); } @@ -111,8 +105,12 @@ public class ContentControlIdKeeperTest { @Test public void testAcquireReleaseCcidForCompoundContext() { ParcelUuid uuid = new ParcelUuid(UUID.randomUUID()); - int ccid = testCcidAcquire(uuid, - BluetoothLeAudio.CONTEXT_TYPE_MEDIA | BluetoothLeAudio.CONTEXT_TYPE_RINGTONE, 1); + int ccid = + testCcidAcquire( + uuid, + BluetoothLeAudio.CONTEXT_TYPE_MEDIA + | BluetoothLeAudio.CONTEXT_TYPE_RINGTONE, + 1); testCcidRelease(uuid, ccid, 0); } @@ -123,8 +121,8 @@ public class ContentControlIdKeeperTest { int ccid = ContentControlIdKeeper.acquireCcid(uuid, 0); Assert.assertEquals(ccid, ContentControlIdKeeper.CCID_INVALID); - verify(mLeAudioServiceMock, - times(0)).setCcidInformation(any(ParcelUuid.class), any(int.class), any(int.class)); + verify(mLeAudioServiceMock, times(0)) + .setCcidInformation(any(ParcelUuid.class), any(int.class), any(int.class)); Map> uuidToCcidContextPair = ContentControlIdKeeper.getUuidToCcidContextPairMap(); Assert.assertEquals(0, uuidToCcidContextPair.size()); @@ -140,5 +138,4 @@ public class ContentControlIdKeeperTest { // This is implementation specific but verifies that the previous CCID was recycled Assert.assertEquals(ccid_one, ccid_two); } - } diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java index 9cf208aaa02..c8a85c0ec38 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java @@ -76,8 +76,7 @@ public class LeAudioBinderTest { private BluetoothAdapter mAdapter; private static final String TEST_BROADCAST_NAME = "TEST"; - private static final int TEST_QUALITY = - BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD; + private static final int TEST_QUALITY = BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD; @Before public void setUp() throws Exception { @@ -145,7 +144,7 @@ public class LeAudioBinderTest { @Test public void getDevicesMatchingConnectionStates() { - int[] states = new int[] {BluetoothProfile.STATE_DISCONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_DISCONNECTED}; AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.getDevicesMatchingConnectionStates(states, source); @@ -410,8 +409,7 @@ public class LeAudioBinderTest { @Test public void setCodecConfigPreference() { int groupId = 1; - BluetoothLeAudioCodecConfig inputConfig = - new BluetoothLeAudioCodecConfig.Builder().build(); + BluetoothLeAudioCodecConfig inputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); BluetoothLeAudioCodecConfig outputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); AttributionSource source = new AttributionSource.Builder(0).build(); @@ -429,10 +427,11 @@ public class LeAudioBinderTest { BluetoothLeBroadcastSubgroupSettings.Builder subgroupBuilder = new BluetoothLeBroadcastSubgroupSettings.Builder() - .setPreferredQuality(TEST_QUALITY) - .setContentMetadata(metadata); + .setPreferredQuality(TEST_QUALITY) + .setContentMetadata(metadata); - BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() + BluetoothLeBroadcastSettings.Builder builder = + new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(false) .setBroadcastName(TEST_BROADCAST_NAME) .setBroadcastCode(null) diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java index 34936960f81..7510fe2ce62 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java @@ -81,12 +81,9 @@ public class LeAudioBroadcastServiceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private ActiveDeviceManager mActiveDeviceManager; - @Mock - private AdapterService mAdapterService; - @Mock - private DatabaseManager mDatabaseManager; - @Mock - private AudioManager mAudioManager; + @Mock private AdapterService mAdapterService; + @Mock private DatabaseManager mDatabaseManager; + @Mock private AudioManager mAudioManager; @Mock private LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface; @Mock private LeAudioNativeInterface mLeAudioNativeInterface; @Mock private LeAudioTmapGattServer mTmapGattServer; @@ -199,7 +196,6 @@ public class LeAudioBroadcastServiceTest { public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); - // Use spied objects factory doNothing().when(mTmapGattServer).start(anyInt()); doNothing().when(mTmapGattServer).stop(); @@ -213,8 +209,11 @@ public class LeAudioBroadcastServiceTest { TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); doReturn(true).when(mAdapterService).isLeAudioBroadcastSourceSupported(); - doReturn((long)(1 << BluetoothProfile.LE_AUDIO_BROADCAST) | (1 << BluetoothProfile.LE_AUDIO)) - .when(mAdapterService).getSupportedProfilesBitMask(); + doReturn( + (long) (1 << BluetoothProfile.LE_AUDIO_BROADCAST) + | (1 << BluetoothProfile.LE_AUDIO)) + .when(mAdapterService) + .getSupportedProfilesBitMask(); doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -270,9 +269,7 @@ public class LeAudioBroadcastServiceTest { Assert.assertNull(mService); } - /** - * Test getting LeAudio Service - */ + /** Test getting LeAudio Service */ @Test public void testGetLeAudioService() { Assert.assertEquals(mService, LeAudioService.getLeAudioService()); @@ -289,12 +286,10 @@ public class LeAudioBroadcastServiceTest { void verifyBroadcastStarted(int broadcastId, BluetoothLeBroadcastSettings settings) { mService.createBroadcast(settings); - List settingsList = - settings.getSubgroupSettings(); + List settingsList = settings.getSubgroupSettings(); int[] expectedQualityArray = - settingsList.stream() - .mapToInt(setting -> setting.getPreferredQuality()).toArray(); + settingsList.stream().mapToInt(setting -> setting.getPreferredQuality()).toArray(); byte[][] expectedDataArray = settingsList.stream() .map(setting -> setting.getContentMetadata().getRawMetadata()) @@ -411,10 +406,10 @@ public class LeAudioBroadcastServiceTest { mService.createBroadcast(settings); // Test data with only one subgroup - int[] expectedQualityArray = - {settings.getSubgroupSettings().get(0).getPreferredQuality()}; - byte[][] expectedDataArray = - {settings.getSubgroupSettings().get(0).getContentMetadata().getRawMetadata()}; + int[] expectedQualityArray = {settings.getSubgroupSettings().get(0).getPreferredQuality()}; + byte[][] expectedDataArray = { + settings.getSubgroupSettings().get(0).getContentMetadata().getRawMetadata() + }; verify(mLeAudioBroadcasterNativeInterface, times(1)) .createBroadcast( @@ -565,11 +560,11 @@ public class LeAudioBroadcastServiceTest { // Update metadata for non-existing broadcast BluetoothLeAudioContentMetadata.Builder meta_builder = - new BluetoothLeAudioContentMetadata.Builder(); + new BluetoothLeAudioContentMetadata.Builder(); meta_builder.setLanguage("eng"); meta_builder.setProgramInfo("Public broadcast info"); - mService.updateBroadcast(broadcastId, - buildBroadcastSettingsFromMetadata(meta_builder.build(), null, 1)); + mService.updateBroadcast( + broadcastId, buildBroadcastSettingsFromMetadata(meta_builder.build(), null, 1)); TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper()); @@ -580,35 +575,41 @@ public class LeAudioBroadcastServiceTest { private BluetoothLeBroadcastSubgroup createBroadcastSubgroup() { BluetoothLeAudioCodecConfigMetadata codecMetadata = new BluetoothLeAudioCodecConfigMetadata.Builder() - .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_LEFT).build(); + .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_LEFT) + .build(); BluetoothLeAudioContentMetadata contentMetadata = new BluetoothLeAudioContentMetadata.Builder() - .setProgramInfo(TEST_PROGRAM_INFO).setLanguage(TEST_LANGUAGE).build(); - BluetoothLeBroadcastSubgroup.Builder builder = new BluetoothLeBroadcastSubgroup.Builder() - .setCodecId(TEST_CODEC_ID) - .setCodecSpecificConfig(codecMetadata) - .setContentMetadata(contentMetadata); + .setProgramInfo(TEST_PROGRAM_INFO) + .setLanguage(TEST_LANGUAGE) + .build(); + BluetoothLeBroadcastSubgroup.Builder builder = + new BluetoothLeBroadcastSubgroup.Builder() + .setCodecId(TEST_CODEC_ID) + .setCodecSpecificConfig(codecMetadata) + .setContentMetadata(contentMetadata); BluetoothLeAudioCodecConfigMetadata channelCodecMetadata = new BluetoothLeAudioCodecConfigMetadata.Builder() - .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_RIGHT).build(); + .setAudioLocation(TEST_AUDIO_LOCATION_FRONT_RIGHT) + .build(); // builder expect at least one channel BluetoothLeBroadcastChannel channel = - new BluetoothLeBroadcastChannel.Builder() - .setSelected(true) - .setChannelIndex(TEST_CHANNEL_INDEX) - .setCodecMetadata(channelCodecMetadata) - .build(); + new BluetoothLeBroadcastChannel.Builder() + .setSelected(true) + .setChannelIndex(TEST_CHANNEL_INDEX) + .setCodecMetadata(channelCodecMetadata) + .build(); builder.addChannel(channel); return builder.build(); } private BluetoothLeBroadcastMetadata createBroadcastMetadata() { BluetoothDevice testDevice = - mAdapter.getRemoteLeDevice(TEST_MAC_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM); + mAdapter.getRemoteLeDevice(TEST_MAC_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM); - BluetoothLeBroadcastMetadata.Builder builder = new BluetoothLeBroadcastMetadata.Builder() + BluetoothLeBroadcastMetadata.Builder builder = + new BluetoothLeBroadcastMetadata.Builder() .setEncrypted(false) .setSourceDevice(testDevice, BluetoothDevice.ADDRESS_TYPE_RANDOM) .setSourceAdvertisingSid(TEST_ADVERTISER_SID) @@ -731,7 +732,7 @@ public class LeAudioBroadcastServiceTest { /* Initialize native */ LeAudioStackEvent stackEvent = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_NATIVE_INITIALIZED); + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_NATIVE_INITIALIZED); mService.messageFromNative(stackEvent); Assert.assertTrue(mService.mLeAudioNativeIsInitialized); @@ -1150,7 +1151,8 @@ public class LeAudioBroadcastServiceTest { Assert.assertEquals(activeGroup, groupId); /* Imitate group change request by Bluetooth Sink HAL suspend request */ - create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS); + create_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS); create_event.valueInt1 = LeAudioStackEvent.DIRECTION_SINK; create_event.valueInt2 = LeAudioStackEvent.STATUS_LOCAL_STREAM_SUSPENDED; mService.messageFromNative(create_event); @@ -1199,7 +1201,8 @@ public class LeAudioBroadcastServiceTest { .setContentMetadata(contentMetadata) .setPreferredQuality(BluetoothLeBroadcastSubgroupSettings.QUALITY_HIGH); - BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() + BluetoothLeBroadcastSettings.Builder builder = + new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(true) .setBroadcastName(TEST_BROADCAST_NAME) .setBroadcastCode(broadcastCode) diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java index 045b5a26673..889a8cdcbf2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java @@ -39,8 +39,7 @@ import org.mockito.junit.MockitoRule; public class LeAudioBroadcasterNativeInterfaceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private LeAudioService mMockService; + @Mock private LeAudioService mMockService; private LeAudioBroadcasterNativeInterface mNativeInterface; @@ -63,11 +62,9 @@ public class LeAudioBroadcasterNativeInterfaceTest { mNativeInterface.onBroadcastCreated(broadcastId, success); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED); + assertThat(event.getValue().type).isEqualTo(LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED); } @Test @@ -76,11 +73,10 @@ public class LeAudioBroadcasterNativeInterfaceTest { mNativeInterface.onBroadcastDestroyed(broadcastId); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_BROADCAST_DESTROYED); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_BROADCAST_DESTROYED); } @Test @@ -90,11 +86,9 @@ public class LeAudioBroadcasterNativeInterfaceTest { mNativeInterface.onBroadcastStateChanged(broadcastId, state); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE); + assertThat(event.getValue().type).isEqualTo(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE); } @Test @@ -104,10 +98,9 @@ public class LeAudioBroadcasterNativeInterfaceTest { mNativeInterface.onBroadcastMetadataChanged(broadcastId, metadata); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_BROADCAST_METADATA_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_BROADCAST_METADATA_CHANGED); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java index cf88ce49259..c6e8cf33381 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java @@ -40,8 +40,7 @@ import org.mockito.junit.MockitoRule; public class LeAudioNativeInterfaceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private LeAudioService mMockService; + @Mock private LeAudioService mMockService; private LeAudioNativeInterface mNativeInterface; @@ -60,30 +59,28 @@ public class LeAudioNativeInterfaceTest { @Test public void onConnectionStateChanged() { int state = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; - byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; mNativeInterface.onConnectionStateChanged(state, address); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); } @Test public void onGroupNodeStatus() { - byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; int groupId = 1; int nodeStatus = LeAudioStackEvent.GROUP_NODE_ADDED; mNativeInterface.onGroupNodeStatus(address, groupId, nodeStatus); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); } @Test @@ -97,44 +94,40 @@ public class LeAudioNativeInterfaceTest { mNativeInterface.onAudioConf( direction, groupId, sinkAudioLocation, sourceAudioLocation, availableContexts); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); } @Test public void onSinkAudioLocationAvailable() { - byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; int sinkAudioLocation = BluetoothLeAudio.AUDIO_LOCATION_INVALID; mNativeInterface.onSinkAudioLocationAvailable(address, sinkAudioLocation); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE); } @Test public void onAudioLocalCodecCapabilities() { - BluetoothLeAudioCodecConfig emptyConfig = - new BluetoothLeAudioCodecConfig.Builder().build(); + BluetoothLeAudioCodecConfig emptyConfig = new BluetoothLeAudioCodecConfig.Builder().build(); BluetoothLeAudioCodecConfig[] localInputCodecCapabilities = - new BluetoothLeAudioCodecConfig[] { emptyConfig }; + new BluetoothLeAudioCodecConfig[] {emptyConfig}; BluetoothLeAudioCodecConfig[] localOutputCodecCapabilities = - new BluetoothLeAudioCodecConfig[] { emptyConfig }; + new BluetoothLeAudioCodecConfig[] {emptyConfig}; mNativeInterface.onAudioLocalCodecCapabilities( localInputCodecCapabilities, localOutputCodecCapabilities); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); - assertThat(event.getValue().type).isEqualTo( - LeAudioStackEvent.EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED); + assertThat(event.getValue().type) + .isEqualTo(LeAudioStackEvent.EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED); } @Test @@ -155,20 +148,18 @@ public class LeAudioNativeInterfaceTest { @Test public void onAudioGroupSelectableCodecConf() { int groupId = 1; - BluetoothLeAudioCodecConfig inputConfig = - new BluetoothLeAudioCodecConfig.Builder().build(); + BluetoothLeAudioCodecConfig inputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); BluetoothLeAudioCodecConfig outputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); BluetoothLeAudioCodecConfig[] inputSelectableCodecConfig = - new BluetoothLeAudioCodecConfig[] { inputConfig }; + new BluetoothLeAudioCodecConfig[] {inputConfig}; BluetoothLeAudioCodecConfig[] outputSelectableCodecConfig = - new BluetoothLeAudioCodecConfig[] { outputConfig }; + new BluetoothLeAudioCodecConfig[] {outputConfig}; mNativeInterface.onAudioGroupSelectableCodecConf( groupId, inputSelectableCodecConfig, outputSelectableCodecConfig); - ArgumentCaptor event = - ArgumentCaptor.forClass(LeAudioStackEvent.class); + ArgumentCaptor event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); assertThat(event.getValue().type) .isEqualTo( diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java index ee3c5cfd3c2..20651241105 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java @@ -145,42 +145,42 @@ public class LeAudioServiceTest { private static final BluetoothLeAudioCodecConfig LC3_16KHZ_CONFIG = new BluetoothLeAudioCodecConfig.Builder() - .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) - .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000) - .build(); + .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) + .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000) + .build(); private static final BluetoothLeAudioCodecConfig LC3_48KHZ_CONFIG = new BluetoothLeAudioCodecConfig.Builder() - .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) - .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000) - .build(); + .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) + .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000) + .build(); private static final BluetoothLeAudioCodecConfig LC3_48KHZ_16KHZ_CONFIG = - new BluetoothLeAudioCodecConfig.Builder() - .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) - .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000 - | BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000) - .build(); + new BluetoothLeAudioCodecConfig.Builder() + .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) + .setSampleRate( + BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000 + | BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000) + .build(); - private static final List INPUT_CAPABILITIES_CONFIG = List.of( - LC3_48KHZ_16KHZ_CONFIG); + private static final List INPUT_CAPABILITIES_CONFIG = + List.of(LC3_48KHZ_16KHZ_CONFIG); - private static final List OUTPUT_CAPABILITIES_CONFIG = List.of( - LC3_48KHZ_16KHZ_CONFIG); + private static final List OUTPUT_CAPABILITIES_CONFIG = + List.of(LC3_48KHZ_16KHZ_CONFIG); - private static final List INPUT_SELECTABLE_CONFIG = List.of( - LC3_16KHZ_CONFIG); + private static final List INPUT_SELECTABLE_CONFIG = + List.of(LC3_16KHZ_CONFIG); private static final List INPUT_EMPTY_CONFIG = List.of(EMPTY_CONFIG); - private static final List OUTPUT_SELECTABLE_CONFIG = List.of( - LC3_48KHZ_16KHZ_CONFIG); + private static final List OUTPUT_SELECTABLE_CONFIG = + List.of(LC3_48KHZ_16KHZ_CONFIG); @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); - // Use spied objects factory doNothing().when(mTmapGattServer).start(anyInt()); doNothing().when(mTmapGattServer).stop(); @@ -194,7 +194,8 @@ public class LeAudioServiceTest { TestUtils.setAdapterService(mAdapterService); doReturn(MAX_LE_AUDIO_CONNECTIONS).when(mAdapterService).getMaxConnectedAudioDevices(); - doReturn(new ParcelUuid[]{BluetoothUuid.LE_AUDIO}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); @@ -203,8 +204,9 @@ public class LeAudioServiceTest { assertThat(manager).isNotNull(); mAdapter = manager.getAdapter(); // Mock methods in AdapterService - doAnswer(invocation -> mBondedDevices.toArray(new BluetoothDevice[]{})).when( - mAdapterService).getBondedDevices(); + doAnswer(invocation -> mBondedDevices.toArray(new BluetoothDevice[] {})) + .when(mAdapterService) + .getBondedDevices(); LeAudioNativeInterface.setInstance(mNativeInterface); startService(); @@ -221,12 +223,12 @@ public class LeAudioServiceTest { when(mServiceFactory.getBassClientService()).thenReturn(mBassClientService); LeAudioStackEvent stackEvent = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_NATIVE_INITIALIZED); + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_NATIVE_INITIALIZED); mService.messageFromNative(stackEvent); assertThat(mService.mLeAudioNativeIsInitialized).isTrue(); // Override the timeout value to speed up the test - LeAudioStateMachine.sConnectTimeoutMs = TIMEOUT_MS; // 1s + LeAudioStateMachine.sConnectTimeoutMs = TIMEOUT_MS; // 1s mGroupIntentQueue = new LinkedBlockingQueue<>(); @@ -238,8 +240,9 @@ public class LeAudioServiceTest { mLeAudioIntentReceiver = new LeAudioIntentReceiver(); mTargetContext.registerReceiver(mLeAudioIntentReceiver, filter); - doAnswer(invocation -> mBondedDevices.toArray(new BluetoothDevice[]{})).when( - mAdapterService).getBondedDevices(); + doAnswer(invocation -> mBondedDevices.toArray(new BluetoothDevice[] {})) + .when(mAdapterService) + .getBondedDevices(); // Get a device for testing mLeftDevice = TestUtils.getTestDevice(mAdapter, 0); @@ -251,9 +254,11 @@ public class LeAudioServiceTest { mDeviceQueueMap.put(mRightDevice, new LinkedBlockingQueue<>()); mDeviceQueueMap.put(mSingleDevice, new LinkedBlockingQueue<>()); mDeviceQueueMap.put(mSingleDevice_2, new LinkedBlockingQueue<>()); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); - doReturn(new ParcelUuid[]{BluetoothUuid.LE_AUDIO}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); verify(mNativeInterface, timeout(3000).times(1)).init(any()); @@ -305,46 +310,52 @@ public class LeAudioServiceTest { return; } - if (BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED - .equals(intent.getAction())) { + if (BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED.equals( + intent.getAction())) { try { - BluetoothDevice device = intent.getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); assertThat(device).isNotNull(); LinkedBlockingQueue queue = mDeviceQueueMap.get(device); assertThat(queue).isNotNull(); queue.put(intent); } catch (InterruptedException e) { - assertWithMessage("Cannot add Intent to the Connection State queue: " - + e.getMessage()).fail(); + assertWithMessage( + "Cannot add Intent to the Connection State queue: " + + e.getMessage()) + .fail(); } } else if (BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED.equals( intent.getAction())) { try { - BluetoothDevice device = intent.getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device != null) { LinkedBlockingQueue queue = mDeviceQueueMap.get(device); assertThat(queue).isNotNull(); queue.put(intent); } } catch (InterruptedException e) { - assertWithMessage("Cannot add Le Audio Intent to the Connection State queue: " - + e.getMessage()).fail(); + assertWithMessage( + "Cannot add Le Audio Intent to the Connection State queue: " + + e.getMessage()) + .fail(); } } } } - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, - int newState, int prevState) { + private void verifyConnectionStateIntent( + int timeoutMs, BluetoothDevice device, int newState, int prevState) { Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device)); assertThat(intent).isNotNull(); assertThat(intent.getAction()) .isEqualTo(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); - assertThat((BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).isEqualTo(device); + assertThat((BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)) + .isEqualTo(device); assertThat(intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)).isEqualTo(newState); - assertThat(intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)).isEqualTo(prevState); + assertThat(intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)) + .isEqualTo(prevState); if (newState == BluetoothProfile.STATE_CONNECTED) { // ActiveDeviceManager calls deviceConnected when connected. @@ -355,17 +366,13 @@ public class LeAudioServiceTest { } } - /** - * Test getting LeAudio Service: getLeAudioService() - */ + /** Test getting LeAudio Service: getLeAudioService() */ @Test public void testGetLeAudioService() { assertThat(mService).isEqualTo(LeAudioService.getLeAudioService()); } - /** - * Test stop LeAudio Service - */ + /** Test stop LeAudio Service */ @Test public void testStopLeAudioService() { // Prepare: connect @@ -374,9 +381,7 @@ public class LeAudioServiceTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); } - /** - * Test if stop during init is ok. - */ + /** Test if stop during init is ok. */ @Test public void testStopStartStopService() throws Exception { InstrumentationRegistry.getInstrumentation() @@ -412,118 +417,128 @@ public class LeAudioServiceTest { } /** - * Helper function to test okToConnect() method + * Helper function to test okToConnect() method * - * @param device test device - * @param bondState bond state value, could be invalid - * @param priority value, could be invalid, could be invalid - * @param expected expected result from okToConnect() + * @param device test device + * @param bondState bond state value, could be invalid + * @param priority value, could be invalid, could be invalid + * @param expected expected result from okToConnect() */ - private void testOkToConnectCase(BluetoothDevice device, int bondState, int priority, - boolean expected) { + private void testOkToConnectCase( + BluetoothDevice device, int bondState, int priority, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO)) .thenReturn(priority); assertThat(expected).isEqualTo(mService.okToConnect(device)); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testOkToConnect() { int badPriorityValue = 1024; int badBondState = 42; - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, badPriorityValue, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, badPriorityValue, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, badPriorityValue, false); - testOkToConnectCase(mSingleDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mSingleDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mSingleDevice, - badBondState, badPriorityValue, false); - } - - /** - * Test that an outgoing connection to device that does not have Le Audio UUID is rejected - */ + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mSingleDevice, BluetoothDevice.BOND_NONE, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mSingleDevice, BluetoothDevice.BOND_BONDING, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testOkToConnectCase(mSingleDevice, BluetoothDevice.BOND_BONDED, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testOkToConnectCase( + mSingleDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); + testOkToConnectCase( + mSingleDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase(mSingleDevice, badBondState, badPriorityValue, false); + } + + /** Test that an outgoing connection to device that does not have Le Audio UUID is rejected */ @Test public void testOutgoingConnectMissingLeAudioUuid() { // Update the device priority so okToConnect() returns true when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); // Return No UUID - doReturn(new ParcelUuid[]{}).when(mAdapterService) + doReturn(new ParcelUuid[] {}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request assertWithMessage("Connect expected to fail").that(mService.connect(mLeftDevice)).isFalse(); } - /** - * Test that an outgoing connection to device with PRIORITY_OFF is rejected - */ + /** Test that an outgoing connection to device with PRIORITY_OFF is rejected */ @Test public void testOutgoingConnectPriorityOff() { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); // Set the device priority to PRIORITY_OFF so connect() should fail - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Send a connect request assertWithMessage("Connect expected to fail").that(mService.connect(mLeftDevice)).isFalse(); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); @@ -532,14 +547,19 @@ public class LeAudioServiceTest { assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(LeAudioStateMachine.sConnectTimeoutMs * 2, - mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + LeAudioStateMachine.sConnectTimeoutMs * 2, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); @@ -576,36 +596,35 @@ public class LeAudioServiceTest { } private void injectNoVerifyDeviceConnected(BluetoothDevice device) { - generateUnexpectedConnectionMessageFromNative(device, + generateUnexpectedConnectionMessageFromNative( + device, LeAudioStackEvent.CONNECTION_STATE_CONNECTED, LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED); } private void injectAndVerifyDeviceDisconnected(BluetoothDevice device) { - generateConnectionMessageFromNative(device, + generateConnectionMessageFromNative( + device, LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED, LeAudioStackEvent.CONNECTION_STATE_CONNECTED); } private void injectNoVerifyDeviceDisconnected(BluetoothDevice device) { - generateUnexpectedConnectionMessageFromNative(device, + generateUnexpectedConnectionMessageFromNative( + device, LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED, LeAudioStackEvent.CONNECTION_STATE_CONNECTED); } - /** - * Test that the outgoing connect/disconnect and audio switch is successful. - */ + + /** Test that the outgoing connect/disconnect and audio switch is successful. */ @Test public void testAudioManagerConnectDisconnect() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); @@ -615,38 +634,50 @@ public class LeAudioServiceTest { assertWithMessage("Connect failed").that(mService.connect(mRightDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mRightDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getConnectionState(mRightDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); LeAudioStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Send a message to trigger connection completed for right side - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state for right side - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mRightDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(mService.getConnectionState(mRightDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTED); @@ -660,37 +691,49 @@ public class LeAudioServiceTest { assertWithMessage("Disconnect failed").that(mService.disconnect(mRightDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Disconnecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); assertThat(BluetoothProfile.STATE_DISCONNECTING) .isEqualTo(mService.getConnectionState(mLeftDevice)); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mRightDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); assertThat(BluetoothProfile.STATE_DISCONNECTING) .isEqualTo(mService.getConnectionState(mRightDevice)); // Send a message to trigger disconnection completed - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mLeftDevice)); // Send a message to trigger disconnection completed to the right device - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mRightDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mRightDevice)); @@ -707,14 +750,11 @@ public class LeAudioServiceTest { @Test public void testCreateStateMachineStackEvents() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); @@ -723,14 +763,18 @@ public class LeAudioServiceTest { assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); // Le Audio stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_CONNECTING) .isEqualTo(mService.getConnectionState(mLeftDevice)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // LeAudio stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mLeftDevice)); @@ -740,20 +784,22 @@ public class LeAudioServiceTest { // Remove bond will remove also device descriptor. Device has to be connected again assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); - verifyConnectionStateIntent(LeAudioStateMachine.sConnectTimeoutMs * 2, - mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + LeAudioStateMachine.sConnectTimeoutMs * 2, + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); // stack event: CONNECTION_STATE_CONNECTED - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(BluetoothProfile.STATE_CONNECTED) .isEqualTo(mService.getConnectionState(mLeftDevice)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mLeftDevice)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); @@ -761,7 +807,8 @@ public class LeAudioServiceTest { assertThat(mService.getDevices().contains(mLeftDevice)).isFalse(); // stack event: CONNECTION_STATE_DISCONNECTING - state machine should not be created - generateUnexpectedConnectionMessageFromNative(mLeftDevice, + generateUnexpectedConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_DISCONNECTED) @@ -769,7 +816,8 @@ public class LeAudioServiceTest { assertThat(mService.getDevices().contains(mLeftDevice)).isFalse(); // stack event: CONNECTION_STATE_DISCONNECTED - state machine should not be created - generateUnexpectedConnectionMessageFromNative(mLeftDevice, + generateUnexpectedConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_DISCONNECTED) @@ -783,14 +831,11 @@ public class LeAudioServiceTest { @Test public void testDeleteStateMachineUnbondEvents() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); @@ -799,7 +844,9 @@ public class LeAudioServiceTest { assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); // LeAudio stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTING); @@ -807,20 +854,26 @@ public class LeAudioServiceTest { // Device unbond - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); // LeAudio stack event: CONNECTION_STATE_CONNECTED - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTED); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_CONNECTED); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // Device unbond - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_DISCONNECTING); @@ -836,7 +889,9 @@ public class LeAudioServiceTest { // LeAudio stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); assertThat(mService.getConnectionState(mLeftDevice)) .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); @@ -984,21 +1039,19 @@ public class LeAudioServiceTest { testAuthorizationInfoRemovedFromTbsMcsOnUnbondEvents(); } + /** - * Test that a CONNECTION_STATE_DISCONNECTED Le Audio stack event will remove the state - * machine only if the device is unbond. + * Test that a CONNECTION_STATE_DISCONNECTED Le Audio stack event will remove the state machine + * only if the device is unbond. */ @Test public void testDeleteStateMachineDisconnectEvents() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); @@ -1007,33 +1060,42 @@ public class LeAudioServiceTest { assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); // LeAudio stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_CONNECTING) .isEqualTo(mService.getConnectionState(mLeftDevice)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // LeAudio stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mLeftDevice)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // LeAudio stack event: CONNECTION_STATE_CONNECTING - state machine remains - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_CONNECTING) .isEqualTo(mService.getConnectionState(mLeftDevice)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // Device bond state marked as unbond - state machine is not removed - doReturn(BluetoothDevice.BOND_NONE).when(mAdapterService) + doReturn(BluetoothDevice.BOND_NONE) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); // LeAudio stack event: CONNECTION_STATE_DISCONNECTED - state machine is removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mLeftDevice)); @@ -1054,23 +1116,28 @@ public class LeAudioServiceTest { assertWithMessage("Connect failed").that(mService.connect(device)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + device, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_CONNECTING) .isEqualTo(mService.getConnectionState(device)); // Send a message to trigger connection completed - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = device; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + device, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); - assertThat(BluetoothProfile.STATE_CONNECTED) - .isEqualTo(mService.getConnectionState(device)); + assertThat(BluetoothProfile.STATE_CONNECTED).isEqualTo(mService.getConnectionState(device)); // Verify that the device is in the list of connected devices assertThat(mService.getConnectedDevices().contains(device)).isTrue(); @@ -1080,8 +1147,8 @@ public class LeAudioServiceTest { } } - private void generateConnectionMessageFromNative(BluetoothDevice device, int newConnectionState, - int oldConnectionState) { + private void generateConnectionMessageFromNative( + BluetoothDevice device, int newConnectionState, int oldConnectionState) { LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); stackEvent.device = device; @@ -1091,8 +1158,8 @@ public class LeAudioServiceTest { verifyConnectionStateIntent(TIMEOUT_MS, device, newConnectionState, oldConnectionState); } - private void generateUnexpectedConnectionMessageFromNative(BluetoothDevice device, - int newConnectionState, int oldConnectionState) { + private void generateUnexpectedConnectionMessageFromNative( + BluetoothDevice device, int newConnectionState, int oldConnectionState) { LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); stackEvent.device = device; @@ -1104,7 +1171,7 @@ public class LeAudioServiceTest { private void generateGroupNodeAdded(BluetoothDevice device, int groupId) { LeAudioStackEvent nodeGroupAdded = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); nodeGroupAdded.device = device; nodeGroupAdded.valueInt1 = groupId; nodeGroupAdded.valueInt2 = LeAudioStackEvent.GROUP_NODE_ADDED; @@ -1113,7 +1180,7 @@ public class LeAudioServiceTest { private void generateGroupNodeRemoved(BluetoothDevice device, int groupId) { LeAudioStackEvent nodeGroupRemoved = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); nodeGroupRemoved.device = device; nodeGroupRemoved.valueInt1 = groupId; nodeGroupRemoved.valueInt2 = LeAudioStackEvent.GROUP_NODE_REMOVED; @@ -1125,88 +1192,103 @@ public class LeAudioServiceTest { assertThat(intent).isNull(); } - /** - * Test setting connection policy - */ + /** Test setting connection policy */ @Test public void testSetConnectionPolicy() { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); - doReturn(true).when(mDatabaseManager).setProfileConnectionPolicy(any(BluetoothDevice.class), - anyInt(), anyInt()); + doReturn(true) + .when(mDatabaseManager) + .setProfileConnectionPolicy(any(BluetoothDevice.class), anyInt(), anyInt()); when(mVolumeControlService.setConnectionPolicy(any(), anyInt())).thenReturn(true); when(mCsipSetCoordinatorService.setConnectionPolicy(any(), anyInt())).thenReturn(true); when(mHapClientService.setConnectionPolicy(any(), anyInt())).thenReturn(true); when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - assertThat(mService.setConnectionPolicy(mSingleDevice, - BluetoothProfile.CONNECTION_POLICY_ALLOWED)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED)) + .isTrue(); // Verify connection policy for CSIP and VCP are also set - verify(mVolumeControlService, times(1)).setConnectionPolicy( - mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); - verify(mCsipSetCoordinatorService, times(1)).setConnectionPolicy( - mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); - verify(mHapClientService, times(1)).setConnectionPolicy( - mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + verify(mVolumeControlService, times(1)) + .setConnectionPolicy(mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + verify(mCsipSetCoordinatorService, times(1)) + .setConnectionPolicy(mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + verify(mHapClientService, times(1)) + .setConnectionPolicy(mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mSingleDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mSingleDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_CONNECTING) .isEqualTo(mService.getConnectionState(mSingleDevice)); LeAudioStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mSingleDevice; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mSingleDevice, BluetoothProfile.STATE_CONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mSingleDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); assertThat(BluetoothProfile.STATE_CONNECTED) .isEqualTo(mService.getConnectionState(mSingleDevice)); // Set connection policy to forbidden - assertThat(mService.setConnectionPolicy(mSingleDevice, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)) + .isTrue(); // Verify connection policy for CSIP and VCP are also set - verify(mVolumeControlService, times(1)).setConnectionPolicy( - mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - verify(mCsipSetCoordinatorService, times(1)).setConnectionPolicy( - mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - verify(mHapClientService, times(1)).setConnectionPolicy( - mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mVolumeControlService, times(1)) + .setConnectionPolicy(mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mCsipSetCoordinatorService, times(1)) + .setConnectionPolicy(mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + verify(mHapClientService, times(1)) + .setConnectionPolicy(mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mSingleDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + TIMEOUT_MS, + mSingleDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); assertThat(BluetoothProfile.STATE_DISCONNECTING) .isEqualTo(mService.getConnectionState(mSingleDevice)); // Send a message to trigger disconnection completed - connCompletedEvent = new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mSingleDevice; connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(TIMEOUT_MS, mSingleDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + mSingleDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); assertThat(BluetoothProfile.STATE_DISCONNECTED) .isEqualTo(mService.getConnectionState(mSingleDevice)); } /** - * Helper function to connect Test device + * Helper function to connect Test device * - * @param device test device + * @param device test device */ private void connectTestDevice(BluetoothDevice device, int GroupId) { List prevConnectedDevices = mService.getConnectedDevices(); @@ -1223,8 +1305,11 @@ public class LeAudioServiceTest { // 250ms for processing two messages should be way more than enough. Anything that breaks // this indicate some breakage in other part of Android OS - verifyConnectionStateIntent(ASYNC_CALL_TIMEOUT_MILLIS, device, - BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); + verifyConnectionStateIntent( + ASYNC_CALL_TIMEOUT_MILLIS, + device, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); assertThat(BluetoothProfile.STATE_CONNECTING) .isEqualTo(mService.getConnectionState(device)); @@ -1235,11 +1320,13 @@ public class LeAudioServiceTest { connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); - verifyConnectionStateIntent(ASYNC_CALL_TIMEOUT_MILLIS, device, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + verifyConnectionStateIntent( + ASYNC_CALL_TIMEOUT_MILLIS, + device, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING); - assertThat(BluetoothProfile.STATE_CONNECTED) - .isEqualTo(mService.getConnectionState(device)); + assertThat(BluetoothProfile.STATE_CONNECTED).isEqualTo(mService.getConnectionState(device)); LeAudioStackEvent nodeGroupAdded = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); @@ -1252,13 +1339,11 @@ public class LeAudioServiceTest { assertThat(mService.getConnectedDevices().contains(device)).isTrue(); // Verify the list of previously connected devices for (BluetoothDevice prevDevice : prevConnectedDevices) { - assertThat(mService.getConnectedDevices().contains(prevDevice)).isTrue(); + assertThat(mService.getConnectedDevices().contains(prevDevice)).isTrue(); } } - /** - * Test adding node - */ + /** Test adding node */ @Test public void testGroupAddRemoveNode() { int groupId = 1; @@ -1270,9 +1355,7 @@ public class LeAudioServiceTest { assertThat(mService.groupRemoveNode(groupId, mSingleDevice)).isTrue(); } - /** - * Test setting active device group with Ringtone context - */ + /** Test setting active device group with Ringtone context */ @Test public void testSetActiveDeviceGroup() { int groupId = 1; @@ -1303,7 +1386,7 @@ public class LeAudioServiceTest { assertThat(mService.setActiveDevice(mSingleDevice)).isTrue(); verify(mNativeInterface).groupSetActive(groupId); - //Set group and device as active + // Set group and device as active LeAudioStackEvent groupStatusChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); groupStatusChangedEvent.valueInt1 = groupId; @@ -1316,7 +1399,7 @@ public class LeAudioServiceTest { assertThat(mService.removeActiveDevice(false)).isTrue(); verify(mNativeInterface).groupSetActive(BluetoothLeAudio.GROUP_ID_INVALID); - //Set group and device as inactive active + // Set group and device as inactive active groupStatusChangedEvent.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; mService.messageFromNative(groupStatusChangedEvent); @@ -1531,9 +1614,7 @@ public class LeAudioServiceTest { mSingleDevice_2, AudioDeviceInfo.TYPE_BLE_HEADSET, true, false, true); } - /** - * Test setting active device group without Ringtone context - */ + /** Test setting active device group without Ringtone context */ @Test public void testSetActiveDeviceGroupWithoutRingtoneContext() { int groupId = 1; @@ -1550,9 +1631,9 @@ public class LeAudioServiceTest { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); - // Add location support + // Add location support LeAudioStackEvent audioConfChangedEvent = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); audioConfChangedEvent.device = mSingleDevice; audioConfChangedEvent.valueInt1 = direction; audioConfChangedEvent.valueInt2 = groupId; @@ -1564,8 +1645,7 @@ public class LeAudioServiceTest { assertThat(mService.setActiveDevice(mSingleDevice)).isTrue(); verify(mNativeInterface).groupSetActive(groupId); - - //Set group and device as active + // Set group and device as active LeAudioStackEvent groupStatusChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); groupStatusChangedEvent.valueInt1 = groupId; @@ -1576,7 +1656,7 @@ public class LeAudioServiceTest { assertThat(mService.removeActiveDevice(false)).isTrue(); verify(mNativeInterface).groupSetActive(BluetoothLeAudio.GROUP_ID_INVALID); - //Set group and device as inactive active + // Set group and device as inactive active groupStatusChangedEvent.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; mService.messageFromNative(groupStatusChangedEvent); @@ -1626,9 +1706,7 @@ public class LeAudioServiceTest { verify(mNativeInterface, times(0)).groupSetActive(anyInt()); } - /** - * Test getting active device - */ + /** Test getting active device */ @Test public void testGetActiveDevices() { int groupId = 1; @@ -1799,45 +1877,44 @@ public class LeAudioServiceTest { assertThat(connInfos.get(4).isLeOutput()).isEqualTo(false); } - /** - * Test native interface audio configuration changed message handling - */ + /** Test native interface audio configuration changed message handling */ @Test public void testMessageFromNativeAudioConfChangedActiveGroup() { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); - injectAudioConfChanged(testGroupId, BluetoothLeAudio.CONTEXT_TYPE_MEDIA | - BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL, 3); + injectAudioConfChanged( + testGroupId, + BluetoothLeAudio.CONTEXT_TYPE_MEDIA | BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL, + 3); injectGroupStatusChange(testGroupId, BluetoothLeAudio.GROUP_STATUS_ACTIVE); /* Expect 2 calles to Audio Manager - one for output and second for input as this is * Conversational use case */ - verify(mAudioManager, times(2)).handleBluetoothActiveDeviceChanged(any(), any(), - any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(2)) + .handleBluetoothActiveDeviceChanged( + any(), any(), any(BluetoothProfileConnectionInfo.class)); /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback * mAudioManager.onAudioDeviceAdded */ injectAudioDeviceAdded(mSingleDevice, AudioDeviceInfo.TYPE_BLE_HEADSET, true, false, true); } - /** - * Test native interface audio configuration changed message handling - */ + + /** Test native interface audio configuration changed message handling */ @Test public void testMessageFromNativeAudioConfChangedInactiveGroup() { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); String action = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED; - Integer contexts = BluetoothLeAudio.CONTEXT_TYPE_MEDIA | - BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL; + Integer contexts = + BluetoothLeAudio.CONTEXT_TYPE_MEDIA | BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL; injectAudioConfChanged(testGroupId, contexts, 3); Intent intent = TestUtils.waitForNoIntent(TIMEOUT_MS, mDeviceQueueMap.get(mSingleDevice)); assertThat(intent).isNull(); } - /** - * Test native interface audio configuration changed message handling - */ + + /** Test native interface audio configuration changed message handling */ @Test public void testMessageFromNativeAudioConfChangedNoGroupChanged() { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); @@ -1999,19 +2076,21 @@ public class LeAudioServiceTest { mService.mLeAudioCallbacks.unregister(leAudioCallbacks); } - /** - * Test native interface group status message handling - */ + /** Test native interface group status message handling */ @Test public void testMessageFromNativeGroupStatusChanged() { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); - injectAudioConfChanged(testGroupId, BluetoothLeAudio.CONTEXT_TYPE_MEDIA | - BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL, 3); + injectAudioConfChanged( + testGroupId, + BluetoothLeAudio.CONTEXT_TYPE_MEDIA | BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL, + 3); - sendEventAndVerifyIntentForGroupStatusChanged(testGroupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); - sendEventAndVerifyIntentForGroupStatusChanged(testGroupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); + sendEventAndVerifyIntentForGroupStatusChanged( + testGroupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); + sendEventAndVerifyIntentForGroupStatusChanged( + testGroupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); } private void sendEventAndVerifyGroupStreamStatusChanged(int groupId, int groupStreamStatus) { @@ -2068,14 +2147,15 @@ public class LeAudioServiceTest { testGroupId, LeAudioStackEvent.GROUP_STREAM_STATUS_STREAMING); } - private void injectLocalCodecConfigCapaChanged(List inputCodecCapa, - List outputCodecCapa) { + private void injectLocalCodecConfigCapaChanged( + List inputCodecCapa, + List outputCodecCapa) { int eventType = LeAudioStackEvent.EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED; // Add device to group LeAudioStackEvent localCodecCapaEvent = new LeAudioStackEvent(eventType); localCodecCapaEvent.valueCodecList1 = inputCodecCapa; - localCodecCapaEvent.valueCodecList2 = outputCodecCapa; + localCodecCapaEvent.valueCodecList2 = outputCodecCapa; mService.messageFromNative(localCodecCapaEvent); } @@ -2103,13 +2183,11 @@ public class LeAudioServiceTest { LeAudioStackEvent groupCodecConfigChangedEvent = new LeAudioStackEvent(eventType); groupCodecConfigChangedEvent.valueInt1 = groupId; groupCodecConfigChangedEvent.valueCodecList1 = inputSelectableCodecConfig; - groupCodecConfigChangedEvent.valueCodecList2 = outputSelectableCodecConfig; + groupCodecConfigChangedEvent.valueCodecList2 = outputSelectableCodecConfig; mService.messageFromNative(groupCodecConfigChangedEvent); } - /** - * Test native interface group status message handling - */ + /** Test native interface group status message handling */ @Test public void testMessageFromNativeGroupCodecConfigChanged() { onGroupCodecConfChangedCallbackCalled = false; @@ -2119,10 +2197,14 @@ public class LeAudioServiceTest { doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); - testCodecStatus = new BluetoothLeAudioCodecStatus(LC3_16KHZ_CONFIG, - LC3_48KHZ_CONFIG, INPUT_CAPABILITIES_CONFIG, - OUTPUT_CAPABILITIES_CONFIG, INPUT_SELECTABLE_CONFIG, - OUTPUT_SELECTABLE_CONFIG); + testCodecStatus = + new BluetoothLeAudioCodecStatus( + LC3_16KHZ_CONFIG, + LC3_48KHZ_CONFIG, + INPUT_CAPABILITIES_CONFIG, + OUTPUT_CAPABILITIES_CONFIG, + INPUT_SELECTABLE_CONFIG, + OUTPUT_SELECTABLE_CONFIG); IBluetoothLeAudioCallback leAudioCallbacks = new IBluetoothLeAudioCallback.Stub() { @@ -2223,9 +2305,7 @@ public class LeAudioServiceTest { assertThat(device).isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); } - /** - * Test native interface group status message handling - */ + /** Test native interface group status message handling */ @Test public void testLeadGroupDeviceDisconnects() { int groupId = 1; @@ -2233,7 +2313,8 @@ public class LeAudioServiceTest { int direction = 1; int snkAudioLocation = 3; int srcAudioLocation = 4; - int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE;; + int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; + ; int groupStatus = LeAudioStackEvent.GROUP_STATUS_ACTIVE; BluetoothDevice leadDevice; BluetoothDevice memberDevice = mLeftDevice; @@ -2244,12 +2325,12 @@ public class LeAudioServiceTest { leadDevice = mService.getConnectedGroupLeadDevice(groupId); if (Objects.equals(leadDevice, mLeftDevice)) { - memberDevice = mRightDevice; + memberDevice = mRightDevice; } assertThat(mService.setActiveDevice(leadDevice)).isFalse(); - //Add location support + // Add location support LeAudioStackEvent audioConfChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); audioConfChangedEvent.valueInt1 = direction; @@ -2261,7 +2342,7 @@ public class LeAudioServiceTest { assertThat(mService.setActiveDevice(leadDevice)).isTrue(); - //Set group and device as active + // Set group and device as active LeAudioStackEvent groupStatusChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); groupStatusChangedEvent.valueInt1 = groupId; @@ -2269,8 +2350,9 @@ public class LeAudioServiceTest { mService.messageFromNative(groupStatusChangedEvent); assertThat(mService.getActiveDevices().contains(leadDevice)).isTrue(); - verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(leadDevice), any(), - any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(leadDevice), any(), any(BluetoothProfileConnectionInfo.class)); /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback * mAudioManager.onAudioDeviceAdded */ @@ -2285,19 +2367,21 @@ public class LeAudioServiceTest { injectAndVerifyDeviceDisconnected(memberDevice); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, leadDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + TIMEOUT_MS, + leadDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); - verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(any(), eq(leadDevice), - any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + any(), eq(leadDevice), any(BluetoothProfileConnectionInfo.class)); verify(mTbsService).setInbandRingtoneSupport(mLeftDevice); verify(mTbsService).setInbandRingtoneSupport(mRightDevice); } - /** - * Test native interface group status message handling - */ + /** Test native interface group status message handling */ @Test public void testLeadGroupDeviceReconnects() { int groupId = 1; @@ -2305,7 +2389,8 @@ public class LeAudioServiceTest { int direction = 1; int snkAudioLocation = 3; int srcAudioLocation = 4; - int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE;; + int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; + ; int groupStatus = LeAudioStackEvent.GROUP_STATUS_ACTIVE; BluetoothDevice leadDevice; BluetoothDevice memberDevice = mLeftDevice; @@ -2316,12 +2401,12 @@ public class LeAudioServiceTest { leadDevice = mService.getConnectedGroupLeadDevice(groupId); if (Objects.equals(leadDevice, mLeftDevice)) { - memberDevice = mRightDevice; + memberDevice = mRightDevice; } assertThat(mService.setActiveDevice(leadDevice)).isFalse(); - //Add location support + // Add location support LeAudioStackEvent audioConfChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); audioConfChangedEvent.valueInt1 = direction; @@ -2333,7 +2418,7 @@ public class LeAudioServiceTest { assertThat(mService.setActiveDevice(leadDevice)).isTrue(); - //Set group and device as active + // Set group and device as active LeAudioStackEvent groupStatusChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); groupStatusChangedEvent.valueInt1 = groupId; @@ -2341,8 +2426,9 @@ public class LeAudioServiceTest { mService.messageFromNative(groupStatusChangedEvent); assertThat(mService.getActiveDevices().contains(leadDevice)).isTrue(); - verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(leadDevice), any(), - any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(leadDevice), any(), any(BluetoothProfileConnectionInfo.class)); /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback * mAudioManager.onAudioDeviceAdded */ @@ -2363,16 +2449,15 @@ public class LeAudioServiceTest { injectAndVerifyDeviceDisconnected(memberDevice); injectAndVerifyDeviceDisconnected(leadDevice); - verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(null), eq(leadDevice), - any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(leadDevice), any(BluetoothProfileConnectionInfo.class)); verify(mTbsService).setInbandRingtoneSupport(mLeftDevice); verify(mTbsService).setInbandRingtoneSupport(mRightDevice); } - /** - * Test volume caching for the group - */ + /** Test volume caching for the group */ @Test public void testVolumeCache() { int groupId = 1; @@ -2388,20 +2473,20 @@ public class LeAudioServiceTest { assertThat(mService.setActiveDevice(mLeftDevice)).isFalse(); ArgumentCaptor profileInfo = - ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); + ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); - //Add location support. + // Add location support. injectAudioConfChanged(groupId, availableContexts, direction); assertThat(mService.setActiveDevice(mLeftDevice)).isTrue(); TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper()); doReturn(-1).when(mVolumeControlService).getAudioDeviceGroupVolume(groupId); - //Set group and device as active. + // Set group and device as active. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); - verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(any(), eq(null), - profileInfo.capture()); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged(any(), eq(null), profileInfo.capture()); assertThat(profileInfo.getValue().getVolume()).isEqualTo(-1); mService.setVolume(volume); @@ -2410,17 +2495,18 @@ public class LeAudioServiceTest { // Set group to inactive. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); - verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(null), any(), - any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), any(), any(BluetoothProfileConnectionInfo.class)); TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper()); doReturn(100).when(mVolumeControlService).getAudioDeviceGroupVolume(groupId); - //Set back to active and check if last volume is restored. + // Set back to active and check if last volume is restored. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); - verify(mAudioManager, times(2)).handleBluetoothActiveDeviceChanged(any(), eq(null), - profileInfo.capture()); + verify(mAudioManager, times(2)) + .handleBluetoothActiveDeviceChanged(any(), eq(null), profileInfo.capture()); assertThat(profileInfo.getValue().getVolume()).isEqualTo(volume); } @@ -2520,11 +2606,11 @@ public class LeAudioServiceTest { public void testGetDevicesMatchingConnectionStates() { assertThat(mService.getDevicesMatchingConnectionStates(null)).isEmpty(); - int[] states = new int[] { BluetoothProfile.STATE_CONNECTED }; + int[] states = new int[] {BluetoothProfile.STATE_CONNECTED}; doReturn(null).when(mAdapterService).getBondedDevices(); assertThat(mService.getDevicesMatchingConnectionStates(states)).isEmpty(); - doReturn(new BluetoothDevice[] { mSingleDevice }).when(mAdapterService).getBondedDevices(); + doReturn(new BluetoothDevice[] {mSingleDevice}).when(mAdapterService).getBondedDevices(); assertThat(mService.getDevicesMatchingConnectionStates(states)).isEmpty(); } @@ -2562,11 +2648,11 @@ public class LeAudioServiceTest { @Test public void testDump_doesNotCrash() { - doReturn(new ParcelUuid[]{BluetoothUuid.LE_AUDIO}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - doReturn(new BluetoothDevice[]{mSingleDevice}).when(mAdapterService).getBondedDevices(); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + doReturn(new BluetoothDevice[] {mSingleDevice}).when(mAdapterService).getBondedDevices(); + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); @@ -2577,9 +2663,7 @@ public class LeAudioServiceTest { mService.dump(sb); } - /** - * Test setting authorization for LeAudio device in the McpService - */ + /** Test setting authorization for LeAudio device in the McpService */ @Test public void testAuthorizeMcpServiceWhenDeviceConnecting() { int groupId = 1; @@ -2592,9 +2676,7 @@ public class LeAudioServiceTest { verify(mMcpService, times(1)).setDeviceAuthorized(mRightDevice, true); } - /** - * Test setting authorization for LeAudio device in the McpService - */ + /** Test setting authorization for LeAudio device in the McpService */ @Test public void testAuthorizeMcpServiceOnBluetoothEnableAndNodeRemoval() { int groupId = 1; @@ -2622,10 +2704,10 @@ public class LeAudioServiceTest { } /** - * Test verifying that when the LE Audio connection policy of a device is set to - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, we unauthorize McpService and - * TbsService. When the LE Audio connection policy is set to - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, we will authorize these services. + * Test verifying that when the LE Audio connection policy of a device is set to {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, we unauthorize McpService and TbsService. When + * the LE Audio connection policy is set to {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * we will authorize these services. */ @Test public void testMcsAndTbsAuthorizationWithConnectionPolicy() { @@ -2634,14 +2716,17 @@ public class LeAudioServiceTest { mService.handleBluetoothEnabled(); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); - doReturn(true).when(mDatabaseManager).setProfileConnectionPolicy(any(BluetoothDevice.class), - anyInt(), anyInt()); + doReturn(true) + .when(mDatabaseManager) + .setProfileConnectionPolicy(any(BluetoothDevice.class), anyInt(), anyInt()); when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); // Ensures GATT server services are not authorized when the device does not have a group - assertThat(mService.setConnectionPolicy(mSingleDevice, - BluetoothProfile.CONNECTION_POLICY_ALLOWED)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED)) + .isTrue(); verify(mMcpService, never()).setDeviceAuthorized(mSingleDevice, false); verify(mTbsService, never()).setDeviceAuthorized(mSingleDevice, false); @@ -2651,14 +2736,18 @@ public class LeAudioServiceTest { verify(mTbsService, times(1)).setDeviceAuthorized(mSingleDevice, true); // Ensure that disconnecting unauthorizes GATT server services - assertThat(mService.setConnectionPolicy(mSingleDevice, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mSingleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)) + .isTrue(); verify(mMcpService, times(1)).setDeviceAuthorized(mSingleDevice, false); verify(mTbsService, times(1)).setDeviceAuthorized(mSingleDevice, false); // Connecting a device that has a group re-authorizes the GATT server services - assertThat(mService.setConnectionPolicy(mSingleDevice, - BluetoothProfile.CONNECTION_POLICY_ALLOWED)).isTrue(); + assertThat( + mService.setConnectionPolicy( + mSingleDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED)) + .isTrue(); verify(mMcpService, times(2)).setDeviceAuthorized(mSingleDevice, true); verify(mTbsService, times(2)).setDeviceAuthorized(mSingleDevice, true); } @@ -2676,8 +2765,8 @@ public class LeAudioServiceTest { // Checks group device lists for groupId 1 List firstGroupDevicesById = mService.getGroupDevices(firstGroupId); List firstGroupDevicesByLeftDevice = mService.getGroupDevices(mLeftDevice); - List firstGroupDevicesByRightDevice = mService.getGroupDevices( - mRightDevice); + List firstGroupDevicesByRightDevice = + mService.getGroupDevices(mRightDevice); assertThat(firstGroupDevicesById.size()).isEqualTo(2); assertThat(firstGroupDevicesById.contains(mLeftDevice)).isTrue(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java index 2921483669d..7f28da4771b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java @@ -98,13 +98,11 @@ public class LeAudioStateMachineTest { TestUtils.clearAdapterService(mAdapterService); } - /** - * Test that default state is disconnected - */ + /** Test that default state is disconnected */ @Test public void testDefaultDisconnectedState() { - assertThat(BluetoothProfile.STATE_DISCONNECTED).isEqualTo( - mLeAudioStateMachine.getConnectionState()); + assertThat(BluetoothProfile.STATE_DISCONNECTED) + .isEqualTo(mLeAudioStateMachine.getConnectionState()); } /** @@ -116,9 +114,7 @@ public class LeAudioStateMachineTest { doReturn(allow).when(mLeAudioService).okToConnect(any(BluetoothDevice.class)); } - /** - * Test that an incoming connection with low priority is rejected - */ + /** Test that an incoming connection with low priority is rejected */ @Test public void testIncomingPriorityReject() { allowConnection(false); @@ -131,23 +127,21 @@ public class LeAudioStateMachineTest { mLeAudioStateMachine.sendMessage(LeAudioStateMachine.STACK_EVENT, connStCh); // Verify that no connection state broadcast is executed - verify(mLeAudioService, after(TIMEOUT_MS).never()).sendBroadcast(any(Intent.class), - anyString(), any(Bundle.class)); + verify(mLeAudioService, after(TIMEOUT_MS).never()) + .sendBroadcast(any(Intent.class), anyString(), any(Bundle.class)); // Check that we are in Disconnected state assertThat(mLeAudioStateMachine.getCurrentState()) .isInstanceOf(LeAudioStateMachine.Disconnected.class); } - /** - * Test that an incoming connection with high priority is accepted - */ + /** Test that an incoming connection with high priority is accepted */ @Test public void testIncomingPriorityAccept() { allowConnection(true); // Inject an event for when incoming connection is requested LeAudioStackEvent connStCh = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connStCh.device = mTestDevice; connStCh.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTING; mLeAudioStateMachine.sendMessage(LeAudioStateMachine.STACK_EVENT, connStCh); @@ -181,16 +175,12 @@ public class LeAudioStateMachineTest { .isInstanceOf(LeAudioStateMachine.Connected.class); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingTimeout() { allowConnection(true); - doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any( - BluetoothDevice.class)); - doReturn(true).when(mLeAudioNativeInterface).disconnectLeAudio(any( - BluetoothDevice.class)); + doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + doReturn(true).when(mLeAudioNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); // Send a connect request mLeAudioStateMachine.sendMessage(LeAudioStateMachine.CONNECT, mTestDevice); @@ -214,16 +204,12 @@ public class LeAudioStateMachineTest { .isInstanceOf(LeAudioStateMachine.Disconnected.class); } - /** - * Test that an incoming connection times out - */ + /** Test that an incoming connection times out */ @Test public void testIncomingTimeout() { allowConnection(true); - doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any( - BluetoothDevice.class)); - doReturn(true).when(mLeAudioNativeInterface).disconnectLeAudio(any( - BluetoothDevice.class)); + doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + doReturn(true).when(mLeAudioNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); // Inject an event for when incoming connection is requested LeAudioStackEvent connStCh = diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java index 6afe455ca19..0eea74fe333 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java @@ -53,8 +53,7 @@ public class LeAudioTmapGattServerTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private LeAudioTmapGattServer.BluetoothGattServerProxy mGattServerProxy; + @Mock private LeAudioTmapGattServer.BluetoothGattServerProxy mGattServerProxy; private LeAudioTmapGattServer mServer; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java index 674278dee7d..c56769fa969 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java @@ -24,9 +24,7 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; -/** - * Test cases for {@link AdvtFilterOnFoundOnLostInfoTest}. - */ +/** Test cases for {@link AdvtFilterOnFoundOnLostInfoTest}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AdvtFilterOnFoundOnLostInfoTest { @@ -35,9 +33,9 @@ public class AdvtFilterOnFoundOnLostInfoTest { public void advtFilterOnFoundOnLostInfoParams() { int clientIf = 0; int advPktLen = 1; - byte[] advPkt = new byte[]{0x02}; + byte[] advPkt = new byte[] {0x02}; int scanRspLen = 3; - byte[] scanRsp = new byte[]{0x04}; + byte[] scanRsp = new byte[] {0x04}; int filtIndex = 5; int advState = 6; int advInfoPresent = 7; @@ -47,21 +45,21 @@ public class AdvtFilterOnFoundOnLostInfoTest { int rssiValue = 10; int timeStamp = 11; - AdvtFilterOnFoundOnLostInfo advtFilterOnFoundOnLostInfo = new AdvtFilterOnFoundOnLostInfo( - clientIf, - advPktLen, - advPkt, - scanRspLen, - scanRsp, - filtIndex, - advState, - advInfoPresent, - address, - addrType, - txPower, - rssiValue, - timeStamp - ); + AdvtFilterOnFoundOnLostInfo advtFilterOnFoundOnLostInfo = + new AdvtFilterOnFoundOnLostInfo( + clientIf, + advPktLen, + advPkt, + scanRspLen, + scanRsp, + filtIndex, + advState, + advInfoPresent, + address, + addrType, + txPower, + rssiValue, + timeStamp); assertThat(advtFilterOnFoundOnLostInfo.getClientIf()).isEqualTo(clientIf); assertThat(advtFilterOnFoundOnLostInfo.getFiltIndex()).isEqualTo(filtIndex); @@ -77,7 +75,7 @@ public class AdvtFilterOnFoundOnLostInfoTest { assertThat(advtFilterOnFoundOnLostInfo.getScanRspData()).isEqualTo(scanRsp); assertThat(advtFilterOnFoundOnLostInfo.getScanRspLen()).isEqualTo(scanRspLen); - byte[] resultByteArray = new byte[]{2, 4}; + byte[] resultByteArray = new byte[] {2, 4}; assertThat(advtFilterOnFoundOnLostInfo.getResult()).isEqualTo(resultByteArray); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java index d7b92e0ec6d..93ae20319b7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java @@ -47,20 +47,16 @@ import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; -/** - * Test cases for {@link AppScanStats}. - */ +/** Test cases for {@link AppScanStats}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AppScanStatsTest { - @Rule - public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private ContextMap map; + @Mock private ContextMap map; @Mock private Context mMockContext; @Mock private TransitionalScanHelper mMockScanHelper; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java index 973ae194964..55ae14f223e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java @@ -29,9 +29,7 @@ import org.junit.runner.RunWith; import java.util.UUID; -/** - * Test cases for {@link ScanFilterQueue}. - */ +/** Test cases for {@link ScanFilterQueue}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class ScanFilterQueueTest { @@ -42,7 +40,7 @@ public class ScanFilterQueueTest { String address = "address"; byte type = 1; - byte[] irk = new byte[]{0x02}; + byte[] irk = new byte[] {0x02}; queue.addDeviceAddress(address, type, irk); queue.addServiceChanged(); @@ -61,20 +59,20 @@ public class ScanFilterQueueTest { queue.addName(name); int company = 2; - byte[] data = new byte[]{0x04}; + byte[] data = new byte[] {0x04}; queue.addManufacturerData(company, data); int companyMask = 2; - byte[] dataMask = new byte[]{0x05}; + byte[] dataMask = new byte[] {0x05}; queue.addManufacturerData(company, companyMask, data, dataMask); - byte[] serviceData = new byte[]{0x06}; - byte[] serviceDataMask = new byte[]{0x08}; + byte[] serviceData = new byte[] {0x06}; + byte[] serviceDataMask = new byte[] {0x08}; queue.addServiceData(serviceData, serviceDataMask); int adType = 3; - byte[] adData = new byte[]{0x10}; - byte[] adDataMask = new byte[]{0x12}; + byte[] adData = new byte[] {0x10}; + byte[] adDataMask = new byte[] {0x12}; queue.addAdvertisingDataType(adType, adData, adDataMask); ScanFilterQueue.Entry[] entries = queue.toArray(); @@ -130,8 +128,8 @@ public class ScanFilterQueueTest { public void popFromQueue() { ScanFilterQueue queue = new ScanFilterQueue(); - byte[] serviceData = new byte[]{0x02}; - byte[] serviceDataMask = new byte[]{0x04}; + byte[] serviceData = new byte[] {0x02}; + byte[] serviceDataMask = new byte[] {0x04}; queue.addServiceData(serviceData, serviceDataMask); ScanFilterQueue.Entry entry = queue.pop(); @@ -143,8 +141,8 @@ public class ScanFilterQueueTest { public void checkFeatureSelection() { ScanFilterQueue queue = new ScanFilterQueue(); - byte[] serviceData = new byte[]{0x02}; - byte[] serviceDataMask = new byte[]{0x04}; + byte[] serviceData = new byte[] {0x02}; + byte[] serviceDataMask = new byte[] {0x04}; queue.addServiceData(serviceData, serviceDataMask); int feature = 1 << ScanFilterQueue.TYPE_SERVICE_DATA; @@ -155,8 +153,8 @@ public class ScanFilterQueueTest { public void convertQueueToArray() { ScanFilterQueue queue = new ScanFilterQueue(); - byte[] serviceData = new byte[]{0x02}; - byte[] serviceDataMask = new byte[]{0x04}; + byte[] serviceData = new byte[] {0x02}; + byte[] serviceDataMask = new byte[] {0x04}; queue.addServiceData(serviceData, serviceDataMask); ScanFilterQueue.Entry[] entries = queue.toArray(); @@ -182,15 +180,16 @@ public class ScanFilterQueueTest { byte[] serviceData = new byte[0]; int advertisingDataType = 1; - ScanFilter filter = new ScanFilter.Builder() - .setDeviceName(name) - .setDeviceAddress(deviceAddress) - .setServiceUuid(serviceUuid) - .setServiceSolicitationUuid(serviceSolicitationUuid) - .setManufacturerData(manufacturerId, manufacturerData) - .setServiceData(serviceDataUuid, serviceData) - .setAdvertisingDataType(advertisingDataType) - .build(); + ScanFilter filter = + new ScanFilter.Builder() + .setDeviceName(name) + .setDeviceAddress(deviceAddress) + .setServiceUuid(serviceUuid) + .setServiceSolicitationUuid(serviceSolicitationUuid) + .setManufacturerData(manufacturerId, manufacturerData) + .setServiceData(serviceDataUuid, serviceData) + .setAdvertisingDataType(advertisingDataType) + .build(); queue.addScanFilter(filter); int numOfEntries = 7; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java index 6816b9654db..9746c58cb9a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java @@ -99,9 +99,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -/** - * Test cases for {@link ScanManager}. - */ +/** Test cases for {@link ScanManager}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class ScanManagerTest { @@ -140,7 +138,7 @@ public class ScanManagerTest { @Spy private GattObjectsFactory mFactory = GattObjectsFactory.getInstance(); @Mock private GattNativeInterface mNativeInterface; @Mock private ScanNativeInterface mScanNativeInterface; - @Mock private MetricsLogger mMetricsLogger; + @Mock private MetricsLogger mMetricsLogger; private AppScanStats mMockAppScanStats; private MockContentResolver mMockContentResolver; @@ -269,8 +267,7 @@ public class ScanManagerTest { } private ScanClient createScanClient( - int id, boolean isFiltered, int scanMode, - boolean isBatch, boolean isAutoBatch) { + int id, boolean isFiltered, int scanMode, boolean isBatch, boolean isAutoBatch) { return createScanClient(id, isFiltered, false, scanMode, isBatch, isAutoBatch); } @@ -297,12 +294,18 @@ public class ScanManagerTest { ScanSettings scanSettings = null; if (isBatch && isAutoBatch) { int autoCallbackType = CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH; - scanSettings = new ScanSettings.Builder().setScanMode(scanMode) - .setReportDelay(mScanReportDelay).setCallbackType(autoCallbackType) - .build(); + scanSettings = + new ScanSettings.Builder() + .setScanMode(scanMode) + .setReportDelay(mScanReportDelay) + .setCallbackType(autoCallbackType) + .build(); } else if (isBatch) { - scanSettings = new ScanSettings.Builder().setScanMode(scanMode) - .setReportDelay(mScanReportDelay).build(); + scanSettings = + new ScanSettings.Builder() + .setScanMode(scanMode) + .setReportDelay(mScanReportDelay) + .build(); } else { scanSettings = new ScanSettings.Builder().setScanMode(scanMode).build(); } @@ -347,9 +350,10 @@ public class ScanManagerTest { } private Message createImportanceMessage(boolean isForeground) { - final int importance = isForeground ? ActivityManager.RunningAppProcessInfo - .IMPORTANCE_FOREGROUND_SERVICE : ActivityManager.RunningAppProcessInfo - .IMPORTANCE_FOREGROUND_SERVICE + 1; + final int importance = + isForeground + ? ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE + : ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE + 1; final int uid = Binder.getCallingUid(); Message message = new Message(); message.what = ScanManager.MSG_IMPORTANCE_CHANGE; @@ -359,8 +363,8 @@ public class ScanManagerTest { private Message createConnectingMessage(boolean isConnectingOn) { Message message = new Message(); - message.what = isConnectingOn ? ScanManager.MSG_START_CONNECTING : - ScanManager.MSG_STOP_CONNECTING; + message.what = + isConnectingOn ? ScanManager.MSG_START_CONNECTING : ScanManager.MSG_STOP_CONNECTING; message.obj = null; return message; } @@ -379,8 +383,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -408,8 +416,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -438,8 +450,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -467,8 +483,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -496,8 +516,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -525,8 +549,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -559,8 +587,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -595,8 +627,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -642,8 +678,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen mHandler.sendMessage(createScreenOnOffMessage(true)); @@ -729,8 +769,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -768,8 +812,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -804,14 +852,18 @@ public class ScanManagerTest { scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_LOW_LATENCY); // Set scan upgrade duration through Mock - when(mAdapterService.getScanUpgradeDurationMillis()). - thenReturn((long) DELAY_SCAN_UPGRADE_DURATION_MS); + when(mAdapterService.getScanUpgradeDurationMillis()) + .thenReturn((long) DELAY_SCAN_UPGRADE_DURATION_MS); for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -842,17 +894,21 @@ public class ScanManagerTest { scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_BALANCED); scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_BALANCED); // Set scan upgrade duration through Mock - when(mAdapterService.getScanUpgradeDurationMillis()). - thenReturn((long) DELAY_SCAN_UPGRADE_DURATION_MS); + when(mAdapterService.getScanUpgradeDurationMillis()) + .thenReturn((long) DELAY_SCAN_UPGRADE_DURATION_MS); // Set scan downgrade duration through Mock - when(mAdapterService.getScanDowngradeDurationMillis()). - thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); + when(mAdapterService.getScanDowngradeDurationMillis()) + .thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -868,8 +924,10 @@ public class ScanManagerTest { assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); // Wait for upgrade and downgrade duration - int max_duration = DELAY_SCAN_UPGRADE_DURATION_MS > DELAY_SCAN_DOWNGRADE_DURATION_MS ? - DELAY_SCAN_UPGRADE_DURATION_MS : DELAY_SCAN_DOWNGRADE_DURATION_MS; + int max_duration = + DELAY_SCAN_UPGRADE_DURATION_MS > DELAY_SCAN_DOWNGRADE_DURATION_MS + ? DELAY_SCAN_UPGRADE_DURATION_MS + : DELAY_SCAN_DOWNGRADE_DURATION_MS; testSleep(max_duration + DELAY_ASYNC_MS); TestUtils.waitForLooperToFinishScheduledTask(mHandler.getLooper()); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); @@ -887,14 +945,18 @@ public class ScanManagerTest { scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_BALANCED); scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_AMBIENT_DISCOVERY); // Set scan downgrade duration through Mock - when(mAdapterService.getScanDowngradeDurationMillis()). - thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); + when(mAdapterService.getScanDowngradeDurationMillis()) + .thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -929,14 +991,18 @@ public class ScanManagerTest { scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_SCREEN_OFF_BALANCED); // Set scan downgrade duration through Mock - when(mAdapterService.getScanDowngradeDurationMillis()). - thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); + when(mAdapterService.getScanDowngradeDurationMillis()) + .thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen mHandler.sendMessage(createScreenOnOffMessage(true)); @@ -980,14 +1046,18 @@ public class ScanManagerTest { scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_POWER); scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_LOW_POWER); // Set scan downgrade duration through Mock - when(mAdapterService.getScanDowngradeDurationMillis()). - thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); + when(mAdapterService.getScanDowngradeDurationMillis()) + .thenReturn((long) DELAY_SCAN_DOWNGRADE_DURATION_MS); for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -1029,8 +1099,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -1066,8 +1140,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -1106,8 +1184,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -1153,8 +1235,12 @@ public class ScanManagerTest { for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); int expectedScanMode = scanModeMap.get(ScanMode); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " expectedScanMode: " + String.valueOf(expectedScanMode)); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " expectedScanMode: " + + String.valueOf(expectedScanMode)); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); @@ -1187,10 +1273,12 @@ public class ScanManagerTest { // Set filtered scan flag final boolean isFiltered = false; // Set scan mode array - int[] scanModeArr = {SCAN_MODE_LOW_POWER, - SCAN_MODE_BALANCED, - SCAN_MODE_LOW_LATENCY, - SCAN_MODE_AMBIENT_DISCOVERY}; + int[] scanModeArr = { + SCAN_MODE_LOW_POWER, + SCAN_MODE_BALANCED, + SCAN_MODE_LOW_LATENCY, + SCAN_MODE_AMBIENT_DISCOVERY + }; for (int i = 0; i < scanModeArr.length; i++) { int ScanMode = scanModeArr[i]; @@ -1241,8 +1329,10 @@ public class ScanManagerTest { .cacheCount( eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), anyLong()); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount( + eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), + anyLong()); Mockito.clearInvocations(mMetricsLogger); testSleep(50); // Stop scan @@ -1253,8 +1343,10 @@ public class ScanManagerTest { .cacheCount( eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), anyLong()); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount( + eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), + anyLong()); Mockito.clearInvocations(mMetricsLogger); } @@ -1317,8 +1409,10 @@ public class ScanManagerTest { .cacheCount( eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), anyLong()); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount( + eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), + anyLong()); Mockito.clearInvocations(mMetricsLogger); } @@ -1340,8 +1434,10 @@ public class ScanManagerTest { .cacheCount( eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), anyLong()); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount( + eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), + anyLong()); Mockito.clearInvocations(mMetricsLogger); testSleep(50); // Start scan with higher duty cycle @@ -1352,8 +1448,10 @@ public class ScanManagerTest { .cacheCount( eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), anyLong()); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount( + eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), + anyLong()); Mockito.clearInvocations(mMetricsLogger); testSleep(50); // Stop scan with lower duty cycle @@ -1368,8 +1466,10 @@ public class ScanManagerTest { .cacheCount( eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), anyLong()); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount( + eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), + anyLong()); Mockito.clearInvocations(mMetricsLogger); } @@ -1391,9 +1491,14 @@ public class ScanManagerTest { Mockito.clearInvocations(mMetricsLogger); for (int i = 0; i < scanModeMap.size(); i++) { int ScanMode = scanModeMap.keyAt(i); - long weightedScanDuration = (long)(scanTestDuration * scanModeMap.get(ScanMode) * 0.01); - Log.d(TAG, "ScanMode: " + String.valueOf(ScanMode) - + " weightedScanDuration: " + String.valueOf(weightedScanDuration)); + long weightedScanDuration = + (long) (scanTestDuration * scanModeMap.get(ScanMode) * 0.01); + Log.d( + TAG, + "ScanMode: " + + String.valueOf(ScanMode) + + " weightedScanDuration: " + + String.valueOf(weightedScanDuration)); // Create scan client ScanClient client = createScanClient(i, isFiltered, ScanMode); @@ -1423,17 +1528,17 @@ public class ScanManagerTest { Mockito.clearInvocations(mMetricsLogger); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.SCREEN_OFF_EVENT), anyLong()); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.SCREEN_ON_EVENT), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount(eq(BluetoothProtoEnums.SCREEN_OFF_EVENT), anyLong()); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.SCREEN_ON_EVENT), anyLong()); Mockito.clearInvocations(mMetricsLogger); // Turn off screen sendMessageWaitForProcessed(createScreenOnOffMessage(false)); - verify(mMetricsLogger, never()).cacheCount( - eq(BluetoothProtoEnums.SCREEN_ON_EVENT), anyLong()); - verify(mMetricsLogger, times(1)).cacheCount( - eq(BluetoothProtoEnums.SCREEN_OFF_EVENT), anyLong()); + verify(mMetricsLogger, never()) + .cacheCount(eq(BluetoothProtoEnums.SCREEN_ON_EVENT), anyLong()); + verify(mMetricsLogger, times(1)) + .cacheCount(eq(BluetoothProtoEnums.SCREEN_OFF_EVENT), anyLong()); Mockito.clearInvocations(mMetricsLogger); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java index 9b2e2ec633d..4993b863a60 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java @@ -39,9 +39,16 @@ public class BluetoothMapAccountItemTest { @Test public void create_withAllParameters() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItem.getId()).isEqualTo(TEST_ID); assertThat(accountItem.getAccountId()).isEqualTo(Long.parseLong(TEST_ID)); assertThat(accountItem.getName()).isEqualTo(TEST_NAME); @@ -55,8 +62,14 @@ public class BluetoothMapAccountItemTest { @Test public void create_withoutIdAndUciData() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(/*id=*/null, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + /* id= */ null, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE); assertThat(accountItem.getId()).isNull(); assertThat(accountItem.getAccountId()).isEqualTo(-1); assertThat(accountItem.getName()).isEqualTo(TEST_NAME); @@ -70,17 +83,38 @@ public class BluetoothMapAccountItemTest { @Test public void getUciFull() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - - BluetoothMapAccountItem accountItemWithoutUciPrefix = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, null); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithoutUci = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, null, null); + BluetoothMapAccountItem accountItemWithoutUciPrefix = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + null); + + BluetoothMapAccountItem accountItemWithoutUci = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + null, + null); assertThat(accountItem.getUciFull()).isEqualTo("uci_prefix:uci"); assertThat(accountItemWithoutUciPrefix.getUciFull()).isNull(); @@ -89,13 +123,25 @@ public class BluetoothMapAccountItemTest { @Test public void compareIfTwoObjectsAreEqual_returnFalse_whenTypesAreDifferent() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithDifferentType = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - BluetoothMapUtils.TYPE.MMS); + BluetoothMapAccountItem accountItemWithDifferentType = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + BluetoothMapUtils.TYPE.MMS); assertThat(accountItem.equals(accountItemWithDifferentType)).isFalse(); assertThat(accountItem.compareTo(accountItemWithDifferentType)).isEqualTo(-1); @@ -103,12 +149,25 @@ public class BluetoothMapAccountItemTest { @Test public void compareIfTwoObjectsAreEqual_returnTrue_evenWhenUcisAreDifferent() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithoutUciData = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE); + BluetoothMapAccountItem accountItemWithoutUciData = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE); assertThat(accountItem.equals(accountItemWithoutUciData)).isTrue(); assertThat(accountItem.compareTo(accountItemWithoutUciData)).isEqualTo(0); @@ -116,17 +175,32 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withSameInstance() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItem.equals(accountItem)).isTrue(); } + @Test public void equals_withNull() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItem).isNotEqualTo(null); } @@ -134,9 +208,16 @@ public class BluetoothMapAccountItemTest { @SuppressWarnings("EqualsIncompatibleType") @Test public void equals_withDifferentClass() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); String accountItemString = "accountItem_string"; assertThat(accountItem.equals(accountItemString)).isFalse(); @@ -144,12 +225,26 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withNullId() { - BluetoothMapAccountItem accountItemWithNullId = BluetoothMapAccountItem.create(/*id=*/null, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, - TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithNonNullId = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, - TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNullId = + BluetoothMapAccountItem.create( + /* id= */ null, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNonNullId = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItemWithNullId).isNotEqualTo(accountItemWithNonNullId); } @@ -157,24 +252,52 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withDifferentId() { String TEST_ID_DIFFERENT = "2222"; - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithDifferentId = BluetoothMapAccountItem.create( - TEST_ID_DIFFERENT, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, - TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithDifferentId = + BluetoothMapAccountItem.create( + TEST_ID_DIFFERENT, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItem).isNotEqualTo(accountItemWithDifferentId); } @Test public void equals_withNullName() { - BluetoothMapAccountItem accountItemWithNullName = BluetoothMapAccountItem.create( - TEST_ID, /*name=*/null, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithNonNullName = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, - TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNullName = + BluetoothMapAccountItem.create( + TEST_ID, + /* name= */ null, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNonNullName = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItemWithNullName).isNotEqualTo(accountItemWithNonNullName); } @@ -182,24 +305,52 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withDifferentName() { String TEST_NAME_DIFFERENT = "test_name_different"; - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithDifferentName = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME_DIFFERENT, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, - TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithDifferentName = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME_DIFFERENT, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItem).isNotEqualTo(accountItemWithDifferentName); } @Test public void equals_withNullPackageName() { - BluetoothMapAccountItem accountItemWithNullPackageName = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, /*package_name=*/null, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithNonNullPackageName = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNullPackageName = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + /* package_name= */ null, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNonNullPackageName = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItemWithNullPackageName).isNotEqualTo(accountItemWithNonNullPackageName); } @@ -207,12 +358,25 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withDifferentPackageName() { String TEST_PACKAGE_NAME_DIFFERENT = "test.different.package.name"; - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); BluetoothMapAccountItem accountItemWithDifferentPackageName = - BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME_DIFFERENT, - TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME_DIFFERENT, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, TEST_UCI_PREFIX); assertThat(accountItem).isNotEqualTo(accountItemWithDifferentPackageName); @@ -220,12 +384,26 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withNullAuthority() { - BluetoothMapAccountItem accountItemWithNullAuthority = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, /*provider_authority=*/null, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithNonNullAuthority = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNullAuthority = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + /* provider_authority= */ null, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNonNullAuthority = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItemWithNullAuthority).isNotEqualTo(accountItemWithNonNullAuthority); } @@ -233,12 +411,25 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withDifferentAuthority() { String TEST_PROVIDER_AUTHORITY_DIFFERENT = "test.project.different.provider"; - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); BluetoothMapAccountItem accountItemWithDifferentAuthority = - BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, - TEST_PROVIDER_AUTHORITY_DIFFERENT, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY_DIFFERENT, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, TEST_UCI_PREFIX); assertThat(accountItem).isNotEqualTo(accountItemWithDifferentAuthority); @@ -246,20 +437,34 @@ public class BluetoothMapAccountItemTest { @Test public void equals_withNullType() { - BluetoothMapAccountItem accountItemWithNullType = BluetoothMapAccountItem.create( - TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - /*type=*/null, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapAccountItem accountItemWithNonNullType = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, - TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNullType = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + /* type= */ null, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItemWithNonNullType = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); assertThat(accountItemWithNullType).isNotEqualTo(accountItemWithNonNullType); } @Test public void hashCode_withOnlyIdNotNull() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, null, - null, null, null, null); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create(TEST_ID, null, null, null, null, null); int expected = (31 + TEST_ID.hashCode()) * 31 * 31 * 31; assertThat(accountItem.hashCode()).isEqualTo(expected); @@ -267,12 +472,19 @@ public class BluetoothMapAccountItemTest { @Test public void toString_returnsNameAndUriInfo() { - BluetoothMapAccountItem accountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, - TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + BluetoothMapAccountItem accountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); String expected = TEST_NAME + " (" + "content://" + TEST_PROVIDER_AUTHORITY + "/" + TEST_ID + ")"; assertThat(accountItem.toString()).isEqualTo(expected); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java index 900835a4622..95fa60a6e8f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java @@ -149,9 +149,10 @@ public class BluetoothMapAppParamsTest { assertThat(appParamsDecoded.getPresenceStatus()).isEqualTo(TEST_PRESENCE_STATUS); assertThat(appParamsDecoded.getLastActivity()).isEqualTo(TEST_LAST_ACTIVITY); assertThat(appParamsDecoded.getConvoListingSize()).isEqualTo(TEST_CONVO_LISTING_SIZE); - assertThat(appParamsDecoded.getChatStateConvoId()).isEqualTo(new SignedLongLong( - TEST_ID_HIGH, TEST_ID_LOW)); + assertThat(appParamsDecoded.getChatStateConvoId()) + .isEqualTo(new SignedLongLong(TEST_ID_HIGH, TEST_ID_LOW)); } + @Test public void settersAndGetters() throws Exception { ByteBuffer ret = ByteBuffer.allocate(16); @@ -204,22 +205,25 @@ public class BluetoothMapAppParamsTest { assertThat(appParams.getAttachment()).isEqualTo(TEST_ATTACHMENT); assertThat(appParams.getCharset()).isEqualTo(TEST_CHARSET); assertThat(appParams.getChatState()).isEqualTo(TEST_CHAT_STATE); - assertThat(appParams.getChatStateConvoId()).isEqualTo(new SignedLongLong( - TEST_ID_HIGH, TEST_ID_LOW)); + assertThat(appParams.getChatStateConvoId()) + .isEqualTo(new SignedLongLong(TEST_ID_HIGH, TEST_ID_LOW)); assertThat(appParams.getChatStateConvoIdByteArray()).isEqualTo(ret.array()); assertThat(appParams.getChatStateConvoIdString()).isEqualTo(new String(ret.array())); assertThat(appParams.getConvoListingSize()).isEqualTo(TEST_CONVO_LISTING_SIZE); assertThat(appParams.getConvoListingVerCounter()).isEqualTo(ret.array()); assertThat(appParams.getConvoParameterMask()).isEqualTo(TEST_CONVO_PARAMETER_MASK); assertThat(appParams.getDatabaseIdentifier()).isEqualTo(ret.array()); - assertThat(appParams.getFilterConvoId()).isEqualTo( - SignedLongLong.fromString(TEST_FILTER_CONVO_ID)); - assertThat(appParams.getFilterConvoIdString()).isEqualTo(BluetoothMapUtils.getLongAsString( - SignedLongLong.fromString(TEST_FILTER_CONVO_ID).getLeastSignificantBits())); - assertThat(appParams.getFilterMsgHandle()).isEqualTo( - BluetoothMapUtils.getLongFromString(TEST_FILTER_MSG_HANDLE)); - assertThat(appParams.getFilterMsgHandleString()).isEqualTo( - BluetoothMapUtils.getLongAsString(appParams.getFilterMsgHandle())); + assertThat(appParams.getFilterConvoId()) + .isEqualTo(SignedLongLong.fromString(TEST_FILTER_CONVO_ID)); + assertThat(appParams.getFilterConvoIdString()) + .isEqualTo( + BluetoothMapUtils.getLongAsString( + SignedLongLong.fromString(TEST_FILTER_CONVO_ID) + .getLeastSignificantBits())); + assertThat(appParams.getFilterMsgHandle()) + .isEqualTo(BluetoothMapUtils.getLongFromString(TEST_FILTER_MSG_HANDLE)); + assertThat(appParams.getFilterMsgHandleString()) + .isEqualTo(BluetoothMapUtils.getLongAsString(appParams.getFilterMsgHandle())); assertThat(appParams.getFilterOriginator()).isEqualTo(TEST_FILTER_ORIGINATOR); assertThat(appParams.getFilterPresence()).isEqualTo(TEST_FILTER_PRESENCE); assertThat(appParams.getFilterReadStatus()).isEqualTo(TEST_FILTER_READ_STATUS); @@ -254,8 +258,8 @@ public class BluetoothMapAppParamsTest { appParams.setFilterLastActivityBegin(lastActivityBeginString); appParams.setFilterLastActivityEnd(lastActivityEndString); - assertThat(appParams.getFilterLastActivityBegin()).isEqualTo( - TEST_FILTER_LAST_ACTIVITY_BEGIN); + assertThat(appParams.getFilterLastActivityBegin()) + .isEqualTo(TEST_FILTER_LAST_ACTIVITY_BEGIN); assertThat(appParams.getFilterLastActivityEnd()).isEqualTo(TEST_FILTER_LAST_ACTIVITY_END); } @@ -302,59 +306,84 @@ public class BluetoothMapAppParamsTest { int ILLEGAL_PARAMETER_INT = -2; long ILLEGAL_PARAMETER_LONG = -2; - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setAttachment(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, - () -> appParams.setCharset(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setCharset(ILLEGAL_PARAMETER_INT)); + assertThrows( + IllegalArgumentException.class, () -> appParams.setChatState(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setConvoListingSize(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setConvoParameterMask(ILLEGAL_PARAMETER_LONG)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFilterMessageType(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFilterPresence(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFilterPriority(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFilterReadStatus(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFilterUidPresent(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFolderListingSize(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFractionDeliver(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setFractionRequest(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setMasInstanceId(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setMaxListCount(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setMessageListingSize(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setNewMessage(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setNotificationFilter(ILLEGAL_PARAMETER_LONG)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setNotificationStatus(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setParameterMask(ILLEGAL_PARAMETER_LONG)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setPresenceAvailability(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, - () -> appParams.setRetry(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setRetry(ILLEGAL_PARAMETER_INT)); + assertThrows( + IllegalArgumentException.class, () -> appParams.setStartOffset(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setStatusIndicator(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setStatusValue(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setSubjectLength(ILLEGAL_PARAMETER_INT)); - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> appParams.setTransparent(ILLEGAL_PARAMETER_INT)); } @@ -368,4 +397,4 @@ public class BluetoothMapAppParamsTest { assertThat(appParams.getFilterConvoId()).isNull(); assertThat(appParams.getFilterMsgHandle()).isEqualTo(-1); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java index 2cb6a218e2d..99a83597047 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java @@ -124,24 +124,15 @@ public class BluetoothMapContentObserverTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Mock - private BluetoothMnsObexClient mClient; - @Mock - private BluetoothMapMasInstance mInstance; - @Mock - private TelephonyManager mTelephonyManager; - @Mock - private UserManager mUserService; - @Mock - private Context mContext; - @Mock - private ContentProviderClient mProviderClient; - @Mock - private BluetoothMapAccountItem mItem; - @Mock - private Intent mIntent; - @Spy - private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); + @Mock private BluetoothMnsObexClient mClient; + @Mock private BluetoothMapMasInstance mInstance; + @Mock private TelephonyManager mTelephonyManager; + @Mock private UserManager mUserService; + @Mock private Context mContext; + @Mock private ContentProviderClient mProviderClient; + @Mock private BluetoothMapAccountItem mItem; + @Mock private Intent mIntent; + @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); private ExceptionTestProvider mProvider; private MockContentResolver mMockContentResolver; @@ -222,8 +213,8 @@ public class BluetoothMapContentObserverTest { message.setType(BluetoothMapUtils.TYPE.MMS); message.setFolder("telecom/msg/outbox"); message.addSender("Zero", "0"); - message.addRecipient("One", new String[]{TEST_NUMBER_ONE}, null); - message.addRecipient("Two", new String[]{TEST_NUMBER_TWO}, null); + message.addRecipient("One", new String[] {TEST_NUMBER_ONE}, null); + message.addRecipient("Two", new String[] {TEST_NUMBER_TWO}, null); BluetoothMapbMessageMime.MimePart body = message.addMimePart(); try { body.mContentType = "text/plain"; @@ -247,8 +238,8 @@ public class BluetoothMapContentObserverTest { } catch (IOException e) { Assert.fail("Threw IOException"); } catch (NullPointerException e) { - //expected that the test case will end in a NPE as part of the sendMultimediaMessage - //pendingSendIntent + // expected that the test case will end in a NPE as part of the sendMultimediaMessage + // pendingSendIntent } // Validate that 3 addresses were inserted into the database with 2 being the recipients @@ -263,8 +254,8 @@ public class BluetoothMapContentObserverTest { mObserver.setNotificationFilter(0); String eventType = BluetoothMapContentObserver.EVENT_TYPE_NEW; - BluetoothMapContentObserver.Event event = mObserver.new Event(eventType, TEST_HANDLE_ONE, - null, null); + BluetoothMapContentObserver.Event event = + mObserver.new Event(eventType, TEST_HANDLE_ONE, null, null); mObserver.sendEvent(event); verify(mClient, never()).sendEvent(any(), anyInt()); @@ -314,8 +305,8 @@ public class BluetoothMapContentObserverTest { when(mClient.isConnected()).thenReturn(true); String eventType = BluetoothMapContentObserver.EVENT_TYPE_NEW; - BluetoothMapContentObserver.Event event = mObserver.new Event(eventType, TEST_HANDLE_ONE, - null, null); + BluetoothMapContentObserver.Event event = + mObserver.new Event(eventType, TEST_HANDLE_ONE, null, null); mObserver.sendEvent(event); @@ -402,11 +393,13 @@ public class BluetoothMapContentObserverTest { BluetoothMapContentObserver.Msg msg = createSimpleMsg(); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); - Assert.assertTrue(mObserver.setMessageStatusRead(TEST_HANDLE_ONE, type, TEST_URI_STR, - TEST_STATUS_VALUE)); + Assert.assertTrue( + mObserver.setMessageStatusRead( + TEST_HANDLE_ONE, type, TEST_URI_STR, TEST_STATUS_VALUE)); Assert.assertEquals(msg.flagRead, TEST_STATUS_VALUE); } @@ -418,11 +411,13 @@ public class BluetoothMapContentObserverTest { BluetoothMapContentObserver.Msg msg = createSimpleMsg(); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMms(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); - Assert.assertTrue(mObserver.setMessageStatusRead(TEST_HANDLE_ONE, type, TEST_URI_STR, - TEST_STATUS_VALUE)); + Assert.assertTrue( + mObserver.setMessageStatusRead( + TEST_HANDLE_ONE, type, TEST_URI_STR, TEST_STATUS_VALUE)); Assert.assertEquals(msg.flagRead, TEST_STATUS_VALUE); } @@ -437,8 +432,9 @@ public class BluetoothMapContentObserverTest { mObserver.mProviderClient = mProviderClient; when(mProviderClient.update(any(), any(), any(), any())).thenReturn(TEST_PLACEHOLDER_INT); - Assert.assertTrue(mObserver.setMessageStatusRead(TEST_HANDLE_ONE, type, TEST_URI_STR, - TEST_STATUS_VALUE)); + Assert.assertTrue( + mObserver.setMessageStatusRead( + TEST_HANDLE_ONE, type, TEST_URI_STR, TEST_STATUS_VALUE)); Assert.assertEquals(msg.flagRead, TEST_STATUS_VALUE); } @@ -446,18 +442,20 @@ public class BluetoothMapContentObserverTest { @Test public void testDeleteMessageMms_withNonDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); MatrixCursor cursor = new MatrixCursor(new String[] {Mms.THREAD_ID}); cursor.addRow(new Object[] {TEST_THREAD_ID}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); Assert.assertTrue(mObserver.deleteMessageMms(TEST_HANDLE_ONE)); @@ -467,18 +465,20 @@ public class BluetoothMapContentObserverTest { @Test public void testDeleteMessageMms_withDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMms(map, true); Assert.assertNotNull(mObserver.getMsgListMms().get(TEST_HANDLE_ONE)); MatrixCursor cursor = new MatrixCursor(new String[] {Mms.THREAD_ID}); cursor.addRow(new Object[] {BluetoothMapContentObserver.DELETED_THREAD_ID}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverDelete(any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverDelete(any(), any(), any(), any()); Assert.assertTrue(mObserver.deleteMessageMms(TEST_HANDLE_ONE)); @@ -488,18 +488,20 @@ public class BluetoothMapContentObserverTest { @Test public void testDeleteMessageSms_withNonDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); MatrixCursor cursor = new MatrixCursor(new String[] {Mms.THREAD_ID}); cursor.addRow(new Object[] {TEST_THREAD_ID}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); Assert.assertTrue(mObserver.deleteMessageSms(TEST_HANDLE_ONE)); @@ -509,18 +511,20 @@ public class BluetoothMapContentObserverTest { @Test public void testDeleteMessageSms_withDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); Assert.assertNotNull(mObserver.getMsgListSms().get(TEST_HANDLE_ONE)); MatrixCursor cursor = new MatrixCursor(new String[] {Mms.THREAD_ID}); cursor.addRow(new Object[] {BluetoothMapContentObserver.DELETED_THREAD_ID}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverDelete(any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverDelete(any(), any(), any(), any()); Assert.assertTrue(mObserver.deleteMessageSms(TEST_HANDLE_ONE)); @@ -530,23 +534,32 @@ public class BluetoothMapContentObserverTest { @Test public void testUnDeleteMessageMms_withDeletedThreadId_andMessageBoxInbox() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); Assert.assertEquals(msg.type, Mms.MESSAGE_BOX_ALL); - MatrixCursor cursor = new MatrixCursor( - new String[] {Mms.THREAD_ID, Mms._ID, Mms.MESSAGE_BOX, Mms.Addr.ADDRESS}); - cursor.addRow(new Object[] {BluetoothMapContentObserver.DELETED_THREAD_ID, 1L, - Mms.MESSAGE_BOX_INBOX, TEST_ADDRESS}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - doReturn(TEST_OLD_THREAD_ID).when(mMapMethodProxy).telephonyGetOrCreateThreadId(any(), - any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] {Mms.THREAD_ID, Mms._ID, Mms.MESSAGE_BOX, Mms.Addr.ADDRESS}); + cursor.addRow( + new Object[] { + BluetoothMapContentObserver.DELETED_THREAD_ID, + 1L, + Mms.MESSAGE_BOX_INBOX, + TEST_ADDRESS + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + doReturn(TEST_OLD_THREAD_ID) + .when(mMapMethodProxy) + .telephonyGetOrCreateThreadId(any(), any()); Assert.assertTrue(mObserver.unDeleteMessageMms(TEST_HANDLE_ONE)); @@ -557,23 +570,32 @@ public class BluetoothMapContentObserverTest { @Test public void testUnDeleteMessageMms_withDeletedThreadId_andMessageBoxSent() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); Assert.assertEquals(msg.type, Mms.MESSAGE_BOX_ALL); - MatrixCursor cursor = new MatrixCursor( - new String[] {Mms.THREAD_ID, Mms._ID, Mms.MESSAGE_BOX, Mms.Addr.ADDRESS}); - cursor.addRow(new Object[] {BluetoothMapContentObserver.DELETED_THREAD_ID, 1L, - Mms.MESSAGE_BOX_SENT, TEST_ADDRESS}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - doReturn(TEST_OLD_THREAD_ID).when(mMapMethodProxy).telephonyGetOrCreateThreadId(any(), - any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] {Mms.THREAD_ID, Mms._ID, Mms.MESSAGE_BOX, Mms.Addr.ADDRESS}); + cursor.addRow( + new Object[] { + BluetoothMapContentObserver.DELETED_THREAD_ID, + 1L, + Mms.MESSAGE_BOX_SENT, + TEST_ADDRESS + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + doReturn(TEST_OLD_THREAD_ID) + .when(mMapMethodProxy) + .telephonyGetOrCreateThreadId(any(), any()); Assert.assertTrue(mObserver.unDeleteMessageMms(TEST_HANDLE_ONE)); @@ -584,20 +606,25 @@ public class BluetoothMapContentObserverTest { @Test public void testUnDeleteMessageMms_withoutDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Mms.MESSAGE_BOX_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); Assert.assertEquals(msg.type, Mms.MESSAGE_BOX_ALL); - MatrixCursor cursor = new MatrixCursor( - new String[] {Mms.THREAD_ID, Mms._ID, Mms.MESSAGE_BOX, Mms.Addr.ADDRESS,}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms.THREAD_ID, Mms._ID, Mms.MESSAGE_BOX, Mms.Addr.ADDRESS, + }); cursor.addRow(new Object[] {TEST_THREAD_ID, 1L, Mms.MESSAGE_BOX_SENT, TEST_ADDRESS}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_OLD_THREAD_ID).when(mMapMethodProxy).telephonyGetOrCreateThreadId(any(), - any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_OLD_THREAD_ID) + .when(mMapMethodProxy) + .telephonyGetOrCreateThreadId(any(), any()); Assert.assertTrue(mObserver.unDeleteMessageMms(TEST_HANDLE_ONE)); @@ -609,22 +636,24 @@ public class BluetoothMapContentObserverTest { @Test public void testUnDeleteMessageSms_withDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); Assert.assertEquals(msg.type, Sms.MESSAGE_TYPE_ALL); - MatrixCursor cursor = new MatrixCursor( - new String[] {Sms.THREAD_ID, Sms.ADDRESS}); + MatrixCursor cursor = new MatrixCursor(new String[] {Sms.THREAD_ID, Sms.ADDRESS}); cursor.addRow(new Object[] {BluetoothMapContentObserver.DELETED_THREAD_ID, TEST_ADDRESS}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - doReturn(TEST_OLD_THREAD_ID).when(mMapMethodProxy).telephonyGetOrCreateThreadId(any(), - any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + doReturn(TEST_OLD_THREAD_ID) + .when(mMapMethodProxy) + .telephonyGetOrCreateThreadId(any(), any()); Assert.assertTrue(mObserver.unDeleteMessageSms(TEST_HANDLE_ONE)); @@ -635,20 +664,21 @@ public class BluetoothMapContentObserverTest { @Test public void testUnDeleteMessageSms_withoutDeletedThreadId() { Map map = new HashMap<>(); - BluetoothMapContentObserver.Msg msg = createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, - TEST_THREAD_ID); + BluetoothMapContentObserver.Msg msg = + createMsgWithTypeAndThreadId(Sms.MESSAGE_TYPE_ALL, TEST_THREAD_ID); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); Assert.assertEquals(msg.threadId, TEST_THREAD_ID); Assert.assertEquals(msg.type, Sms.MESSAGE_TYPE_ALL); - MatrixCursor cursor = new MatrixCursor( - new String[] {Sms.THREAD_ID, Sms.ADDRESS}); + MatrixCursor cursor = new MatrixCursor(new String[] {Sms.THREAD_ID, Sms.ADDRESS}); cursor.addRow(new Object[] {TEST_THREAD_ID, TEST_ADDRESS}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_OLD_THREAD_ID).when(mMapMethodProxy).telephonyGetOrCreateThreadId(any(), - any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_OLD_THREAD_ID) + .when(mMapMethodProxy) + .telephonyGetOrCreateThreadId(any(), any()); Assert.assertTrue(mObserver.unDeleteMessageSms(TEST_HANDLE_ONE)); @@ -677,45 +707,53 @@ public class BluetoothMapContentObserverTest { @Test public void setEmailMessageStatusDelete_withStatusValueYes() { - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); Map map = new HashMap<>(); BluetoothMapContentObserver.Msg msg = createSimpleMsg(); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - - Assert.assertTrue(mObserver.setEmailMessageStatusDelete(mCurrentFolder, TEST_URI_STR, - TEST_HANDLE_ONE, BluetoothMapAppParams.STATUS_VALUE_YES)); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + + Assert.assertTrue( + mObserver.setEmailMessageStatusDelete( + mCurrentFolder, + TEST_URI_STR, + TEST_HANDLE_ONE, + BluetoothMapAppParams.STATUS_VALUE_YES)); Assert.assertEquals(msg.folderId, TEST_DELETE_FOLDER_ID); } @Test public void setEmailMessageStatusDelete_withStatusValueYes_andUpdateCountZero() { - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); Map map = new HashMap<>(); BluetoothMapContentObserver.Msg msg = createSimpleMsg(); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); - doReturn(0).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(0).when(mMapMethodProxy).contentResolverUpdate(any(), any(), any(), any(), any()); - Assert.assertFalse(mObserver.setEmailMessageStatusDelete(mCurrentFolder, TEST_URI_STR, - TEST_HANDLE_ONE, BluetoothMapAppParams.STATUS_VALUE_YES)); + Assert.assertFalse( + mObserver.setEmailMessageStatusDelete( + mCurrentFolder, + TEST_URI_STR, + TEST_HANDLE_ONE, + BluetoothMapAppParams.STATUS_VALUE_YES)); } @Test public void setEmailMessageStatusDelete_withStatusValueNo() { - setFolderStructureWithTelecomAndMsg(mCurrentFolder, BluetoothMapContract.FOLDER_NAME_INBOX, - TEST_INBOX_FOLDER_ID); - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mCurrentFolder, BluetoothMapContract.FOLDER_NAME_INBOX, TEST_INBOX_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); Map map = new HashMap<>(); @@ -724,21 +762,26 @@ public class BluetoothMapContentObserverTest { msg.folderId = TEST_DELETE_FOLDER_ID; map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - - Assert.assertTrue(mObserver.setEmailMessageStatusDelete(mCurrentFolder, TEST_URI_STR, - TEST_HANDLE_ONE, BluetoothMapAppParams.STATUS_VALUE_NO)); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + + Assert.assertTrue( + mObserver.setEmailMessageStatusDelete( + mCurrentFolder, + TEST_URI_STR, + TEST_HANDLE_ONE, + BluetoothMapAppParams.STATUS_VALUE_NO)); Assert.assertEquals(msg.folderId, TEST_INBOX_FOLDER_ID); } @Test public void setEmailMessageStatusDelete_withStatusValueNo_andOldFolderIdMinusOne() { int oldFolderId = -1; - setFolderStructureWithTelecomAndMsg(mCurrentFolder, BluetoothMapContract.FOLDER_NAME_INBOX, - TEST_INBOX_FOLDER_ID); - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mCurrentFolder, BluetoothMapContract.FOLDER_NAME_INBOX, TEST_INBOX_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); Map map = new HashMap<>(); @@ -747,21 +790,28 @@ public class BluetoothMapContentObserverTest { msg.folderId = TEST_DELETE_FOLDER_ID; map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - - Assert.assertTrue(mObserver.setEmailMessageStatusDelete(mCurrentFolder, TEST_URI_STR, - TEST_HANDLE_ONE, BluetoothMapAppParams.STATUS_VALUE_NO)); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + + Assert.assertTrue( + mObserver.setEmailMessageStatusDelete( + mCurrentFolder, + TEST_URI_STR, + TEST_HANDLE_ONE, + BluetoothMapAppParams.STATUS_VALUE_NO)); Assert.assertEquals(msg.folderId, TEST_INBOX_FOLDER_ID); } @Test public void setEmailMessageStatusDelete_withStatusValueNo_andInboxFolderNull() { // This sets mCurrentFolder to have a sent folder, but not an inbox folder - setFolderStructureWithTelecomAndMsg(mCurrentFolder, BluetoothMapContract.FOLDER_NAME_SENT, + setFolderStructureWithTelecomAndMsg( + mCurrentFolder, + BluetoothMapContract.FOLDER_NAME_SENT, BluetoothMapContract.FOLDER_ID_SENT); - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); Map map = new HashMap<>(); @@ -770,75 +820,124 @@ public class BluetoothMapContentObserverTest { msg.folderId = TEST_DELETE_FOLDER_ID; map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); - - Assert.assertTrue(mObserver.setEmailMessageStatusDelete(mCurrentFolder, TEST_URI_STR, - TEST_HANDLE_ONE, BluetoothMapAppParams.STATUS_VALUE_NO)); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); + + Assert.assertTrue( + mObserver.setEmailMessageStatusDelete( + mCurrentFolder, + TEST_URI_STR, + TEST_HANDLE_ONE, + BluetoothMapAppParams.STATUS_VALUE_NO)); Assert.assertEquals(msg.folderId, TEST_OLD_FOLDER_ID); } @Test public void setMessageStatusDeleted_withTypeEmail() { - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); Map map = new HashMap<>(); BluetoothMapContentObserver.Msg msg = createSimpleMsg(); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); - Assert.assertTrue(mObserver.setMessageStatusDeleted(TEST_HANDLE_ONE, TYPE.EMAIL, - mCurrentFolder, TEST_URI_STR, BluetoothMapAppParams.STATUS_VALUE_YES)); + Assert.assertTrue( + mObserver.setMessageStatusDeleted( + TEST_HANDLE_ONE, + TYPE.EMAIL, + mCurrentFolder, + TEST_URI_STR, + BluetoothMapAppParams.STATUS_VALUE_YES)); } @Test public void setMessageStatusDeleted_withTypeIm() { - Assert.assertFalse(mObserver.setMessageStatusDeleted(TEST_HANDLE_ONE, TYPE.IM, - mCurrentFolder, TEST_URI_STR, BluetoothMapAppParams.STATUS_VALUE_YES)); + Assert.assertFalse( + mObserver.setMessageStatusDeleted( + TEST_HANDLE_ONE, + TYPE.IM, + mCurrentFolder, + TEST_URI_STR, + BluetoothMapAppParams.STATUS_VALUE_YES)); } @Test public void setMessageStatusDeleted_withTypeGsmOrMms_andStatusValueNo() { - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_OLD_THREAD_ID).when(mMapMethodProxy).telephonyGetOrCreateThreadId(any(), - any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_OLD_THREAD_ID) + .when(mMapMethodProxy) + .telephonyGetOrCreateThreadId(any(), any()); // setMessageStatusDeleted with type Gsm or Mms calls either deleteMessage() or // unDeleteMessage(), which returns false when no cursor is set with BluetoothMethodProxy. - Assert.assertFalse(mObserver.setMessageStatusDeleted(TEST_HANDLE_ONE, TYPE.MMS, - mCurrentFolder, TEST_URI_STR, BluetoothMapAppParams.STATUS_VALUE_NO)); - Assert.assertFalse(mObserver.setMessageStatusDeleted(TEST_HANDLE_ONE, TYPE.SMS_GSM, - mCurrentFolder, TEST_URI_STR, BluetoothMapAppParams.STATUS_VALUE_NO)); + Assert.assertFalse( + mObserver.setMessageStatusDeleted( + TEST_HANDLE_ONE, + TYPE.MMS, + mCurrentFolder, + TEST_URI_STR, + BluetoothMapAppParams.STATUS_VALUE_NO)); + Assert.assertFalse( + mObserver.setMessageStatusDeleted( + TEST_HANDLE_ONE, + TYPE.SMS_GSM, + mCurrentFolder, + TEST_URI_STR, + BluetoothMapAppParams.STATUS_VALUE_NO)); } @Test public void setMessageStatusDeleted_withTypeGsmOrMms_andStatusValueYes() { - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); // setMessageStatusDeleted with type Gsm or Mms calls either deleteMessage() or // unDeleteMessage(), which returns false when no cursor is set with BluetoothMethodProxy. - Assert.assertFalse(mObserver.setMessageStatusDeleted(TEST_HANDLE_ONE, TYPE.MMS, - mCurrentFolder, TEST_URI_STR, BluetoothMapAppParams.STATUS_VALUE_YES)); - Assert.assertFalse(mObserver.setMessageStatusDeleted(TEST_HANDLE_ONE, TYPE.SMS_GSM, - mCurrentFolder, TEST_URI_STR, BluetoothMapAppParams.STATUS_VALUE_YES)); + Assert.assertFalse( + mObserver.setMessageStatusDeleted( + TEST_HANDLE_ONE, + TYPE.MMS, + mCurrentFolder, + TEST_URI_STR, + BluetoothMapAppParams.STATUS_VALUE_YES)); + Assert.assertFalse( + mObserver.setMessageStatusDeleted( + TEST_HANDLE_ONE, + TYPE.SMS_GSM, + mCurrentFolder, + TEST_URI_STR, + BluetoothMapAppParams.STATUS_VALUE_YES)); } @Test public void initMsgList_withMsgSms() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ}); - cursor.addRow(new Object[] {(long) TEST_ID, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, - TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContentObserver.SMS_PROJECTION_SHORT), any(), any(), any()); + MatrixCursor cursor = + new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, Sms.READ}); + cursor.addRow( + new Object[] { + (long) TEST_ID, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContentObserver.SMS_PROJECTION_SHORT), + any(), + any(), + any()); cursor.moveToFirst(); Map map = new HashMap<>(); mObserver.setMsgListMsg(map, true); @@ -854,14 +953,30 @@ public class BluetoothMapContentObserverTest { @Test public void initMsgList_withMsgMms() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.THREAD_ID, Mms.READ}); - cursor.addRow(new Object[] {(long) TEST_ID, TEST_MMS_TYPE_ALL, TEST_THREAD_ID, - TEST_READ_FLAG_ZERO}); - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContentObserver.SMS_PROJECTION_SHORT), any(), any(), any()); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContentObserver.MMS_PROJECTION_SHORT), any(), any(), any()); + MatrixCursor cursor = + new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, Mms.THREAD_ID, Mms.READ}); + cursor.addRow( + new Object[] { + (long) TEST_ID, TEST_MMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO + }); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContentObserver.SMS_PROJECTION_SHORT), + any(), + any(), + any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContentObserver.MMS_PROJECTION_SHORT), + any(), + any(), + any()); cursor.moveToFirst(); Map map = new HashMap<>(); mObserver.setMsgListMsg(map, true); @@ -877,13 +992,30 @@ public class BluetoothMapContentObserverTest { @Test public void initMsgList_withMsg() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] {MessageColumns._ID, - MessageColumns.FOLDER_ID, MessageColumns.FLAG_READ}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + MessageColumns._ID, MessageColumns.FOLDER_ID, MessageColumns.FLAG_READ + }); cursor.addRow(new Object[] {(long) TEST_ID, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE}); - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContentObserver.SMS_PROJECTION_SHORT), any(), any(), any()); - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContentObserver.MMS_PROJECTION_SHORT), any(), any(), any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContentObserver.SMS_PROJECTION_SHORT), + any(), + any(), + any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContentObserver.MMS_PROJECTION_SHORT), + any(), + any(), + any()); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); cursor.moveToFirst(); Map map = new HashMap<>(); @@ -899,23 +1031,38 @@ public class BluetoothMapContentObserverTest { @Test public void initContactsList() throws Exception { - MatrixCursor cursor = new MatrixCursor( - new String[] {BluetoothMapContract.ConvoContactColumns.CONVO_ID, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY, - BluetoothMapContract.ConvoContactColumns.LAST_ONLINE}); - cursor.addRow(new Object[] {TEST_CONVO_ID, TEST_NAME, TEST_DISPLAY_NAME, TEST_BT_UID, - TEST_CHAT_STATE, TEST_UCI, TEST_LAST_ACTIVITY, TEST_PRESENCE_STATE, - TEST_STATUS_TEXT, TEST_PRIORITY, TEST_LAST_ONLINE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConvoContactColumns.CONVO_ID, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY, + BluetoothMapContract.ConvoContactColumns.LAST_ONLINE + }); + cursor.addRow( + new Object[] { + TEST_CONVO_ID, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_BT_UID, + TEST_CHAT_STATE, + TEST_UCI, + TEST_LAST_ACTIVITY, + TEST_PRESENCE_STATE, + TEST_STATUS_TEXT, + TEST_PRIORITY, + TEST_LAST_ONLINE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mObserver.mContactUri = mock(Uri.class); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); @@ -933,30 +1080,42 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(contactElement.getChatState(), TEST_CHAT_STATE); Assert.assertEquals(contactElement.getPresenceStatus(), TEST_STATUS_TEXT); Assert.assertEquals(contactElement.getPresenceAvailability(), TEST_PRESENCE_STATE); - Assert.assertEquals(contactElement.getLastActivityString(), format.format( - TEST_LAST_ACTIVITY)); + Assert.assertEquals( + contactElement.getLastActivityString(), format.format(TEST_LAST_ACTIVITY)); Assert.assertEquals(contactElement.getPriority(), TEST_PRIORITY); } @Test public void handleMsgListChangesMsg_withNonExistingMessage_andVersion11() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE, - TEST_DATE_MS, TEST_SUBJECT, TEST_ADDRESS, 1}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_INBOX_FOLDER_ID, + TEST_READ_FLAG_ONE, + TEST_DATE_MS, + TEST_SUBJECT, + TEST_ADDRESS, + 1 + }); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMsg() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); msg.localInitiatedSend = true; msg.transparent = true; map.put(TEST_HANDLE_TWO, msg); @@ -968,33 +1127,47 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).type, - TEST_INBOX_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).type, TEST_INBOX_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMsg_withNonExistingMessage_andVersion12() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, - BluetoothMapContract.MessageColumns.THREAD_ID, - BluetoothMapContract.MessageColumns.THREAD_NAME}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE, - TEST_DATE_MS, TEST_SUBJECT, TEST_ADDRESS, 1, 1, "threadName"}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, + BluetoothMapContract.MessageColumns.THREAD_ID, + BluetoothMapContract.MessageColumns.THREAD_NAME + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_INBOX_FOLDER_ID, + TEST_READ_FLAG_ONE, + TEST_DATE_MS, + TEST_SUBJECT, + TEST_ADDRESS, + 1, + 1, + "threadName" + }); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMsg() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); msg.localInitiatedSend = false; msg.transparent = false; map.put(TEST_HANDLE_TWO, msg); @@ -1004,26 +1177,30 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).type, - TEST_INBOX_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).type, TEST_INBOX_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMsg_withNonExistingMessage_andVersion10() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ + }); cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE}); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMsg() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); msg.localInitiatedSend = false; msg.transparent = false; map.put(TEST_HANDLE_TWO, msg); @@ -1035,161 +1212,198 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).type, - TEST_INBOX_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).type, TEST_INBOX_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMsg_withExistingMessage_andNonNullDeletedFolder() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ,}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + }); cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_DELETE_FOLDER_ID, TEST_READ_FLAG_ONE}); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMsg() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, - TEST_DELETE_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DELETED, TEST_DELETE_FOLDER_ID); mObserver.setFolderStructure(mFolders); mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, - TEST_DELETE_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, TEST_DELETE_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMsg_withExistingMessage_andNonNullSentFolder() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ,}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + }); cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SENT_FOLDER_ID, TEST_READ_FLAG_ONE}); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMsg() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ZERO); msg.localInitiatedSend = true; msg.transparent = false; map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_SENT, - TEST_SENT_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_SENT, TEST_SENT_FOLDER_ID); mObserver.setFolderStructure(mFolders); mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, - TEST_SENT_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, TEST_SENT_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMsg_withExistingMessage_andNonNullTransparentSentFolder() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ,}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + }); cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SENT_FOLDER_ID, TEST_READ_FLAG_ONE}); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMsg() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ZERO); msg.localInitiatedSend = true; msg.transparent = true; map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverDelete(any(), any(), - any(), any()); - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_SENT, - TEST_SENT_FOLDER_ID); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverDelete(any(), any(), any(), any()); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_SENT, TEST_SENT_FOLDER_ID); mObserver.setFolderStructure(mFolders); mObserver.mMessageUri = Mms.CONTENT_URI; mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, - TEST_SENT_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, TEST_SENT_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test - public void handleMsgListChangesMsg_withExistingMessage_andUnknownOldFolder() - throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ,}); + public void handleMsgListChangesMsg_withExistingMessage_andUnknownOldFolder() throws Exception { + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + }); cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE}); when(mProviderClient.query(any(), any(), any(), any(), any())).thenReturn(cursor); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMsg() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_SENT_FOLDER_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_SENT_FOLDER_ID, TEST_READ_FLAG_ZERO); msg.localInitiatedSend = true; msg.transparent = false; map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListMsg(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; - setFolderStructureWithTelecomAndMsg(mFolders, BluetoothMapContract.FOLDER_NAME_DRAFT, - TEST_DRAFT_FOLDER_ID); + setFolderStructureWithTelecomAndMsg( + mFolders, BluetoothMapContract.FOLDER_NAME_DRAFT, TEST_DRAFT_FOLDER_ID); mObserver.setFolderStructure(mFolders); mObserver.handleMsgListChangesMsg(TEST_URI); Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, - TEST_INBOX_FOLDER_ID); - Assert.assertEquals(mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).folderId, TEST_INBOX_FOLDER_ID); + Assert.assertEquals( + mObserver.getMsgListMsg().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMms_withNonExistingMessage_andVersion11() { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ, Mms.DATE, Mms.SUBJECT, - Mms.PRIORITY, Mms.Addr.ADDRESS}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - TEST_THREAD_ID, TEST_READ_FLAG_ONE, TEST_DATE_SEC, TEST_SUBJECT, - PduHeaders.PRIORITY_HIGH, null}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, + Mms.MESSAGE_BOX, + Mms.MESSAGE_TYPE, + Mms.THREAD_ID, + Mms.READ, + Mms.DATE, + Mms.SUBJECT, + Mms.PRIORITY, + Mms.Addr.ADDRESS + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE, + TEST_DATE_SEC, + TEST_SUBJECT, + PduHeaders.PRIORITY_HIGH, + null + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListMms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; @@ -1198,28 +1412,49 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMms_withNonExistingMessage_andVersion12() { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ, Mms.DATE, Mms.SUBJECT, - Mms.PRIORITY, Mms.Addr.ADDRESS}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - TEST_THREAD_ID, TEST_READ_FLAG_ONE, TEST_DATE_SEC, TEST_SUBJECT, - PduHeaders.PRIORITY_HIGH, null}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, + Mms.MESSAGE_BOX, + Mms.MESSAGE_TYPE, + Mms.THREAD_ID, + Mms.READ, + Mms.DATE, + Mms.SUBJECT, + Mms.PRIORITY, + Mms.Addr.ADDRESS + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE, + TEST_DATE_SEC, + TEST_SUBJECT, + PduHeaders.PRIORITY_HIGH, + null + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListMms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1228,10 +1463,10 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test @@ -1242,20 +1477,41 @@ public class BluetoothMapContentObserverTest { cal.add(Calendar.DATE, -1); long timestampSec = TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis()); - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ, Mms.DATE, Mms.SUBJECT, - Mms.PRIORITY, Mms.Addr.ADDRESS}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - TEST_THREAD_ID, TEST_READ_FLAG_ONE, timestampSec, TEST_SUBJECT, - PduHeaders.PRIORITY_HIGH, null}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, + Mms.MESSAGE_BOX, + Mms.MESSAGE_TYPE, + Mms.THREAD_ID, + Mms.READ, + Mms.DATE, + Mms.SUBJECT, + Mms.PRIORITY, + Mms.Addr.ADDRESS + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE, + timestampSec, + TEST_SUBJECT, + PduHeaders.PRIORITY_HIGH, + null + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListMms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1319,18 +1575,29 @@ public class BluetoothMapContentObserverTest { @Test public void handleMsgListChangesMms_withNonExistingMessage_andVersion10() { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - TEST_THREAD_ID, TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, Mms.MESSAGE_BOX, Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_INBOX_FOLDER_ID, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListMms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V10; @@ -1339,26 +1606,37 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMms_withExistingMessage_withNonEqualType_andLocalSendFalse() { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - TEST_THREAD_ID, TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, Mms.MESSAGE_BOX, Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_MMS_TYPE_INBOX, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_MMS_TYPE_INBOX, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); msg.localInitiatedSend = false; mObserver.setMsgListMms(map, true); @@ -1368,26 +1646,37 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMms_withExistingMessage_withNonEqualType_andLocalSendTrue() { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - TEST_THREAD_ID, TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, Mms.MESSAGE_BOX, Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_MMS_TYPE_INBOX, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_MMS_TYPE_INBOX, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); msg.localInitiatedSend = true; mObserver.setMsgListMms(map, true); @@ -1397,26 +1686,37 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMms_withExistingMessage_withDeletedThreadId() { - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - BluetoothMapContentObserver.DELETED_THREAD_ID, TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, Mms.MESSAGE_BOX, Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + BluetoothMapContentObserver.DELETED_THREAD_ID, + TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_MMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); msg.localInitiatedSend = true; mObserver.setMsgListMms(map, true); @@ -1426,27 +1726,39 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, BluetoothMapContentObserver.DELETED_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesMms_withExistingMessage_withUndeletedThreadId() { int undeletedThreadId = 0; - MatrixCursor cursor = new MatrixCursor(new String[] {Mms._ID, Mms.MESSAGE_BOX, - Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_MMS_MTYPE, - undeletedThreadId, TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Mms._ID, Mms.MESSAGE_BOX, Mms.MESSAGE_TYPE, Mms.THREAD_ID, Mms.READ + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_MMS_TYPE_ALL, + TEST_MMS_MTYPE, + undeletedThreadId, + TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesMms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_MMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_MMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); msg.localInitiatedSend = true; mObserver.setMsgListMms(map, true); @@ -1456,26 +1768,47 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).type, TEST_MMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, - undeletedThreadId); - Assert.assertEquals(mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).threadId, undeletedThreadId); + Assert.assertEquals( + mObserver.getMsgListMms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesSms_withNonExistingMessage_andVersion11() { - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ, Sms.DATE, Sms.BODY, Sms.ADDRESS, ContactsContract.Contacts.DISPLAY_NAME}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SMS_TYPE_INBOX, TEST_THREAD_ID, - TEST_READ_FLAG_ONE, TEST_DATE_MS, TEST_SUBJECT, TEST_ADDRESS, null}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Sms._ID, + Sms.TYPE, + Sms.THREAD_ID, + Sms.READ, + Sms.DATE, + Sms.BODY, + Sms.ADDRESS, + ContactsContract.Contacts.DISPLAY_NAME + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_SMS_TYPE_INBOX, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE, + TEST_DATE_MS, + TEST_SUBJECT, + TEST_ADDRESS, + null + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesSms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_SMS_TYPE_ALL, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_SMS_TYPE_ALL, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; @@ -1483,28 +1816,47 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesSms(); Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, - TEST_SMS_TYPE_INBOX); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, TEST_SMS_TYPE_INBOX); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesSms_withNonExistingMessage_andVersion12() { - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ, Sms.DATE, Sms.BODY, Sms.ADDRESS}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, - TEST_READ_FLAG_ONE, TEST_DATE_MS, "", null}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Sms._ID, + Sms.TYPE, + Sms.THREAD_ID, + Sms.READ, + Sms.DATE, + Sms.BODY, + Sms.ADDRESS + }); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_SMS_TYPE_ALL, + TEST_THREAD_ID, + TEST_READ_FLAG_ONE, + TEST_DATE_MS, + "", + null + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesSms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_SMS_TYPE_INBOX, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_SMS_TYPE_INBOX, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1512,12 +1864,11 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesSms(); Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, - TEST_SMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, TEST_SMS_TYPE_ALL); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test @@ -1595,14 +1946,16 @@ public class BluetoothMapContentObserverTest { "", null }); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesMms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_SMS_TYPE_INBOX, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_SMS_TYPE_INBOX, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1614,18 +1967,22 @@ public class BluetoothMapContentObserverTest { @Test public void handleMsgListChangesSms_withNonExistingMessage_andVersion10() { - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, - TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, Sms.READ}); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving a different handle for msg below and cursor above makes handleMsgListChangesSms() // function for a non-existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_TWO, - TEST_SMS_TYPE_INBOX, TEST_READ_FLAG_ONE); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_TWO, TEST_SMS_TYPE_INBOX, TEST_READ_FLAG_ONE); map.put(TEST_HANDLE_TWO, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V10; @@ -1633,28 +1990,31 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesSms(); Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, - TEST_SMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, TEST_SMS_TYPE_ALL); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesSms_withExistingMessage_withNonEqualType() { - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, - TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, Sms.READ}); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesSms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_SMS_TYPE_INBOX, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_SMS_TYPE_INBOX, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1662,28 +2022,34 @@ public class BluetoothMapContentObserverTest { mObserver.handleMsgListChangesSms(); Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, - TEST_SMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, - TEST_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, TEST_SMS_TYPE_ALL); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, TEST_THREAD_ID); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesSms_withExistingMessage_withDeletedThreadId() { - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, - BluetoothMapContentObserver.DELETED_THREAD_ID, TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, Sms.READ}); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, + TEST_SMS_TYPE_ALL, + BluetoothMapContentObserver.DELETED_THREAD_ID, + TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesSms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1692,27 +2058,32 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, TEST_SMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, BluetoothMapContentObserver.DELETED_THREAD_ID); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test public void handleMsgListChangesSms_withExistingMessage_withUndeletedThreadId() { int undeletedThreadId = 0; - MatrixCursor cursor = new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, - Sms.READ}); - cursor.addRow(new Object[] {TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, undeletedThreadId, - TEST_READ_FLAG_ONE}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = + new MatrixCursor(new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID, Sms.READ}); + cursor.addRow( + new Object[] { + TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, undeletedThreadId, TEST_READ_FLAG_ONE + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); Map map = new HashMap<>(); // Giving the same handle for msg below and cursor above makes handleMsgListChangesSms() // function for an existing message - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_HANDLE_ONE, - TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg( + TEST_HANDLE_ONE, TEST_SMS_TYPE_ALL, TEST_THREAD_ID, TEST_READ_FLAG_ZERO); map.put(TEST_HANDLE_ONE, msg); mObserver.setMsgListSms(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -1721,10 +2092,10 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).id, TEST_HANDLE_ONE); Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).type, TEST_SMS_TYPE_ALL); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, - undeletedThreadId); - Assert.assertEquals(mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, - TEST_READ_FLAG_ONE); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).threadId, undeletedThreadId); + Assert.assertEquals( + mObserver.getMsgListSms().get(TEST_HANDLE_ONE).flagRead, TEST_READ_FLAG_ONE); } @Test @@ -1737,8 +2108,9 @@ public class BluetoothMapContentObserverTest { @Test public void handleMmsSendIntent_withInvalidHandle() { when(mClient.isConnected()).thenReturn(true); - doReturn((long) -1).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn((long) -1) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); Assert.assertTrue(mObserver.handleMmsSendIntent(mContext, mIntent)); } @@ -1746,12 +2118,17 @@ public class BluetoothMapContentObserverTest { @Test public void handleMmsSendIntent_withActivityResultOk() { when(mClient.isConnected()).thenReturn(true); - doReturn(TEST_HANDLE_ONE).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); - doReturn(Activity.RESULT_OK).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, Activity.RESULT_CANCELED); - doReturn(0).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_HANDLE_ONE) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(Activity.RESULT_OK) + .when(mIntent) + .getIntExtra( + BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, + Activity.RESULT_CANCELED); + doReturn(0) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); mObserver.mObserverRegistered = true; Assert.assertTrue(mObserver.handleMmsSendIntent(mContext, mIntent)); @@ -1760,13 +2137,18 @@ public class BluetoothMapContentObserverTest { @Test public void handleMmsSendIntent_withActivityResultFirstUser() { when(mClient.isConnected()).thenReturn(true); - doReturn(TEST_HANDLE_ONE).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); - doReturn(Activity.RESULT_FIRST_USER).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, Activity.RESULT_CANCELED); + doReturn(TEST_HANDLE_ONE) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(Activity.RESULT_FIRST_USER) + .when(mIntent) + .getIntExtra( + BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, + Activity.RESULT_CANCELED); mObserver.mObserverRegistered = true; - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverDelete(any(), any(), - any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverDelete(any(), any(), any(), any()); Assert.assertTrue(mObserver.handleMmsSendIntent(mContext, mIntent)); } @@ -1776,13 +2158,18 @@ public class BluetoothMapContentObserverTest { Map mmsMsgList = new HashMap<>(); BluetoothMapContentObserver.Msg msg = createSimpleMsg(); mmsMsgList.put(TEST_HANDLE_ONE, msg); - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn((long) -1).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn((long) -1) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); // This mock sets type to MMS - doReturn(4).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal()); + doReturn(4) + .when(mIntent) + .getIntExtra( + BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE, + TYPE.NONE.ordinal()); mObserver.actionMessageSentDisconnected(mContext, mIntent, 1); @@ -1792,13 +2179,18 @@ public class BluetoothMapContentObserverTest { @Test public void actionMessageSentDisconnected_withTypeEmail() { // This sets to null uriString - doReturn(null).when(mIntent).getStringExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(null) + .when(mIntent) + .getStringExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); // This mock sets type to Email - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal()); + doReturn(1) + .when(mIntent) + .getIntExtra( + BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE, + TYPE.NONE.ordinal()); clearInvocations(mContext); mObserver.actionMessageSentDisconnected(mContext, mIntent, Activity.RESULT_FIRST_USER); @@ -1811,10 +2203,12 @@ public class BluetoothMapContentObserverTest { Map mmsMsgList = new HashMap<>(); BluetoothMapContentObserver.Msg msg = createSimpleMsg(); mmsMsgList.put(TEST_HANDLE_ONE, msg); - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn((long) -1).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn((long) -1) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); mObserver.actionMmsSent(mContext, mIntent, 1, mmsMsgList); @@ -1827,12 +2221,15 @@ public class BluetoothMapContentObserverTest { BluetoothMapContentObserver.Msg msg = createSimpleMsg(); mmsMsgList.put(TEST_HANDLE_ONE, msg); // This mock turns on the transparent flag - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn(TEST_HANDLE_ONE).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverDelete(any(), any(), - any(), any()); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_HANDLE_ONE) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverDelete(any(), any(), any(), any()); mObserver.actionMmsSent(mContext, mIntent, 1, mmsMsgList); @@ -1845,16 +2242,20 @@ public class BluetoothMapContentObserverTest { BluetoothMapContentObserver.Msg msg = createSimpleMsg(); mmsMsgList.put(TEST_HANDLE_ONE, msg); // This mock turns off the transparent flag - doReturn(0).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn(TEST_HANDLE_ONE).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(0) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_HANDLE_ONE) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); MatrixCursor cursor = new MatrixCursor(new String[] {}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); mObserver.actionMmsSent(mContext, mIntent, Activity.RESULT_OK, mmsMsgList); @@ -1867,10 +2268,12 @@ public class BluetoothMapContentObserverTest { BluetoothMapContentObserver.Msg msg = createSimpleMsg(); mmsMsgList.put(TEST_HANDLE_ONE, msg); // This mock turns off the transparent flag - doReturn(0).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn(TEST_HANDLE_ONE).when(mIntent).getLongExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); + doReturn(0) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_HANDLE_ONE) + .when(mIntent) + .getLongExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_HANDLE, -1); mObserver.actionMmsSent(mContext, mIntent, Activity.RESULT_FIRST_USER, mmsMsgList); @@ -1880,10 +2283,12 @@ public class BluetoothMapContentObserverTest { @Test public void actionSmsSentDisconnected_withNullUriString() { // This sets to null uriString - doReturn(null).when(mIntent).getStringExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(null) + .when(mIntent) + .getStringExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); clearInvocations(mContext); mObserver.actionSmsSentDisconnected(mContext, mIntent, Activity.RESULT_FIRST_USER); @@ -1893,13 +2298,16 @@ public class BluetoothMapContentObserverTest { @Test public void actionSmsSentDisconnected_withActivityResultOk_andTransparentOff() { - doReturn(TEST_URI_STR).when(mIntent).getStringExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); + doReturn(TEST_URI_STR) + .when(mIntent) + .getStringExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); // This mock turns off the transparent flag - doReturn(0).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(0) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); clearInvocations(mContext); mObserver.actionSmsSentDisconnected(mContext, mIntent, Activity.RESULT_OK); @@ -1909,13 +2317,16 @@ public class BluetoothMapContentObserverTest { @Test public void actionSmsSentDisconnected_withActivityResultOk_andTransparentOn() { - doReturn(TEST_URI_STR).when(mIntent).getStringExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); + doReturn(TEST_URI_STR) + .when(mIntent) + .getStringExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); // This mock turns on the transparent flag - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverDelete(any(), any(), - any(), any()); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverDelete(any(), any(), any(), any()); clearInvocations(mContext); mObserver.actionSmsSentDisconnected(mContext, mIntent, Activity.RESULT_OK); @@ -1925,13 +2336,16 @@ public class BluetoothMapContentObserverTest { @Test public void actionSmsSentDisconnected_withActivityResultFirstUser_andTransparentOff() { - doReturn(TEST_URI_STR).when(mIntent).getStringExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); + doReturn(TEST_URI_STR) + .when(mIntent) + .getStringExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); // This mock turns off the transparent flag - doReturn(0).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); - doReturn(TEST_PLACEHOLDER_INT).when(mMapMethodProxy).contentResolverUpdate(any(), any(), - any(), any(), any()); + doReturn(0) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(TEST_PLACEHOLDER_INT) + .when(mMapMethodProxy) + .contentResolverUpdate(any(), any(), any(), any(), any()); clearInvocations(mContext); mObserver.actionSmsSentDisconnected(mContext, mIntent, Activity.RESULT_OK); @@ -1941,11 +2355,13 @@ public class BluetoothMapContentObserverTest { @Test public void actionSmsSentDisconnected_withActivityResultFirstUser_andTransparentOn() { - doReturn(TEST_URI_STR).when(mIntent).getStringExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); + doReturn(TEST_URI_STR) + .when(mIntent) + .getStringExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_URI); // This mock turns on the transparent flag - doReturn(1).when(mIntent).getIntExtra( - BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); + doReturn(1) + .when(mIntent) + .getIntExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_TRANSPARENT, 0); doReturn(null).when(mContext).getContentResolver(); clearInvocations(mContext); @@ -1960,21 +2376,35 @@ public class BluetoothMapContentObserverTest { mObserver.mAuthority = TEST_AUTHORITY; when(uri.getAuthority()).thenReturn(TEST_AUTHORITY); - MatrixCursor cursor = new MatrixCursor( - new String[]{BluetoothMapContract.ConvoContactColumns.CONVO_ID, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY, - BluetoothMapContract.ConvoContactColumns.LAST_ONLINE}); - cursor.addRow(new Object[] {TEST_CONVO_ID, TEST_NAME, TEST_DISPLAY_NAME, TEST_BT_UID, - TEST_CHAT_STATE, TEST_UCI, TEST_LAST_ACTIVITY, TEST_PRESENCE_STATE, - TEST_STATUS_TEXT, TEST_PRIORITY, TEST_LAST_ONLINE}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConvoContactColumns.CONVO_ID, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY, + BluetoothMapContract.ConvoContactColumns.LAST_ONLINE + }); + cursor.addRow( + new Object[] { + TEST_CONVO_ID, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_BT_UID, + TEST_CHAT_STATE, + TEST_UCI, + TEST_LAST_ACTIVITY, + TEST_PRESENCE_STATE, + TEST_STATUS_TEXT, + TEST_PRIORITY, + TEST_LAST_ONLINE + }); doReturn(cursor).when(mProviderClient).query(any(), any(), any(), any(), any()); Map map = new HashMap<>(); @@ -1993,8 +2423,8 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(contactElement.getChatState(), TEST_CHAT_STATE); Assert.assertEquals(contactElement.getPresenceStatus(), TEST_STATUS_TEXT); Assert.assertEquals(contactElement.getPresenceAvailability(), TEST_PRESENCE_STATE); - Assert.assertEquals(contactElement.getLastActivityString(), format.format( - TEST_LAST_ACTIVITY)); + Assert.assertEquals( + contactElement.getLastActivityString(), format.format(TEST_LAST_ACTIVITY)); Assert.assertEquals(contactElement.getPriority(), TEST_PRIORITY); } @@ -2004,29 +2434,50 @@ public class BluetoothMapContentObserverTest { mObserver.mAuthority = TEST_AUTHORITY; when(uri.getAuthority()).thenReturn(TEST_AUTHORITY); - MatrixCursor cursor = new MatrixCursor( - new String[]{BluetoothMapContract.ConvoContactColumns.CONVO_ID, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY, - BluetoothMapContract.ConvoContactColumns.LAST_ONLINE}); - cursor.addRow(new Object[] {TEST_CONVO_ID, TEST_NAME, TEST_DISPLAY_NAME, TEST_BT_UID, - TEST_CHAT_STATE, TEST_UCI, TEST_LAST_ACTIVITY, TEST_PRESENCE_STATE, - TEST_STATUS_TEXT, TEST_PRIORITY, TEST_LAST_ONLINE}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConvoContactColumns.CONVO_ID, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY, + BluetoothMapContract.ConvoContactColumns.LAST_ONLINE + }); + cursor.addRow( + new Object[] { + TEST_CONVO_ID, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_BT_UID, + TEST_CHAT_STATE, + TEST_UCI, + TEST_LAST_ACTIVITY, + TEST_PRESENCE_STATE, + TEST_STATUS_TEXT, + TEST_PRIORITY, + TEST_LAST_ONLINE + }); doReturn(cursor).when(mProviderClient).query(any(), any(), any(), any(), any()); Map map = new HashMap<>(); map.put(TEST_UCI_DIFFERENT, null); - BluetoothMapConvoContactElement contact = new BluetoothMapConvoContactElement(TEST_UCI, - TEST_NAME, TEST_DISPLAY_NAME, TEST_STATUS_TEXT_DIFFERENT, - TEST_PRESENCE_STATE_DIFFERENT, TEST_LAST_ACTIVITY, TEST_CHAT_STATE_DIFFERENT, - TEST_PRIORITY, TEST_BT_UID); + BluetoothMapConvoContactElement contact = + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_STATUS_TEXT_DIFFERENT, + TEST_PRESENCE_STATE_DIFFERENT, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE_DIFFERENT, + TEST_PRIORITY, + TEST_BT_UID); map.put(TEST_UCI, contact); mObserver.setContactList(map, true); mObserver.mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; @@ -2043,8 +2494,8 @@ public class BluetoothMapContentObserverTest { Assert.assertEquals(contactElement.getChatState(), TEST_CHAT_STATE); Assert.assertEquals(contactElement.getPresenceStatus(), TEST_STATUS_TEXT); Assert.assertEquals(contactElement.getPresenceAvailability(), TEST_PRESENCE_STATE); - Assert.assertEquals(contactElement.getLastActivityString(), format.format( - TEST_LAST_ACTIVITY)); + Assert.assertEquals( + contactElement.getLastActivityString(), format.format(TEST_LAST_ACTIVITY)); Assert.assertEquals(contactElement.getPriority(), TEST_PRIORITY); } @@ -2068,12 +2519,12 @@ public class BluetoothMapContentObserverTest { return new BluetoothMapContentObserver.Msg(1, type, threadId, 1); } - private void setFolderStructureWithTelecomAndMsg(BluetoothMapFolderElement folderElement, - String folderName, long folderId) { + private void setFolderStructureWithTelecomAndMsg( + BluetoothMapFolderElement folderElement, String folderName, long folderId) { folderElement.addFolder("telecom"); folderElement.getSubFolder("telecom").addFolder("msg"); - BluetoothMapFolderElement subFolder = folderElement.getSubFolder("telecom").getSubFolder( - "msg").addFolder(folderName); + BluetoothMapFolderElement subFolder = + folderElement.getSubFolder("telecom").getSubFolder("msg").addFolder(folderName); subFolder.setFolderId(folderId); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java index 20237fe8961..c464035f440 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java @@ -115,20 +115,13 @@ public class BluetoothMapContentTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private BluetoothMapAccountItem mAccountItem; - @Mock - private BluetoothMapMasInstance mMasInstance; - @Mock - private Context mContext; - @Mock - private TelephonyManager mTelephonyManager; - @Mock - private ContentResolver mContentResolver; - @Mock - private BluetoothMapAppParams mParams; - @Spy - private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); + @Mock private BluetoothMapAccountItem mAccountItem; + @Mock private BluetoothMapMasInstance mMasInstance; + @Mock private Context mContext; + @Mock private TelephonyManager mTelephonyManager; + @Mock private ContentResolver mContentResolver; + @Mock private BluetoothMapAppParams mParams; + @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); private BluetoothMapContent mContent; private FilterInfo mInfo; @@ -154,8 +147,7 @@ public class BluetoothMapContentTest { @Test public void constructor_withNonNullAccountItem() { - BluetoothMapContent content = new BluetoothMapContent(mContext, mAccountItem, - mMasInstance); + BluetoothMapContent content = new BluetoothMapContent(mContext, mAccountItem, mMasInstance); assertThat(content.mBaseUri).isNotNull(); } @@ -176,8 +168,9 @@ public class BluetoothMapContentTest { when(cursor.getString(1)).thenReturn("text/plain"); when(cursor.getColumnIndex("text")).thenReturn(2); when(cursor.getString(2)).thenReturn(TEST_TEXT); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); assertThat(BluetoothMapContent.getTextPartsMms(mContentResolver, id)).isEqualTo(TEST_TEXT); } @@ -189,12 +182,12 @@ public class BluetoothMapContentTest { when(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)).thenReturn(1); when(cursor.getCount()).thenReturn(1); when(cursor.getString(1)).thenReturn(TEST_TEXT); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); - assertThat( - BluetoothMapContent.getContactNameFromPhone(phoneName, mContentResolver)).isEqualTo( - TEST_TEXT); + assertThat(BluetoothMapContent.getContactNameFromPhone(phoneName, mContentResolver)) + .isEqualTo(TEST_TEXT); } @Test @@ -205,12 +198,12 @@ public class BluetoothMapContentTest { when(cursor.getString(0)).thenReturn("recipientIdOne recipientIdTwo"); when(cursor.getColumnIndex(Telephony.CanonicalAddressesColumns.ADDRESS)).thenReturn(1); when(cursor.getString(1)).thenReturn("recipientAddress"); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); - assertThat( - BluetoothMapContent.getCanonicalAddressSms(mContentResolver, threadId)).isEqualTo( - "recipientAddress"); + assertThat(BluetoothMapContent.getCanonicalAddressSms(mContentResolver, threadId)) + .isEqualTo("recipientAddress"); } @Test @@ -221,23 +214,24 @@ public class BluetoothMapContentTest { when(cursor.moveToFirst()).thenReturn(true); when(cursor.getColumnIndex(Telephony.Mms.Addr.ADDRESS)).thenReturn(1); when(cursor.getString(1)).thenReturn(TEST_TEXT); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); - assertThat(BluetoothMapContent.getAddressMms(mContentResolver, id, type)).isEqualTo( - TEST_TEXT); + assertThat(BluetoothMapContent.getAddressMms(mContentResolver, id, type)) + .isEqualTo(TEST_TEXT); } @Test public void setAttachment_withTypeMms() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_ATTACHMENT_SIZE); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_ATTACHMENT_SIZE); mInfo.mMsgType = FilterInfo.TYPE_MMS; mInfo.mMmsColTextOnly = 0; mInfo.mMmsColAttachmentSize = 1; - MatrixCursor cursor = new MatrixCursor( - new String[]{"MmsColTextOnly", "MmsColAttachmentSize"}); - cursor.addRow(new Object[]{0, -1}); + MatrixCursor cursor = + new MatrixCursor(new String[] {"MmsColTextOnly", "MmsColAttachmentSize"}); + cursor.addRow(new Object[] {0, -1}); cursor.moveToFirst(); mContent.setAttachment(mMessageListingElement, cursor, mInfo, mParams); @@ -247,14 +241,14 @@ public class BluetoothMapContentTest { @Test public void setAttachment_withTypeEmail() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_ATTACHMENT_SIZE); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_ATTACHMENT_SIZE); mInfo.mMsgType = FilterInfo.TYPE_EMAIL; mInfo.mMessageColAttachment = 0; mInfo.mMessageColAttachmentSize = 1; - MatrixCursor cursor = new MatrixCursor(new String[]{"MessageColAttachment", - "MessageColAttachmentSize"}); - cursor.addRow(new Object[]{1, 0}); + MatrixCursor cursor = + new MatrixCursor(new String[] {"MessageColAttachment", "MessageColAttachmentSize"}); + cursor.addRow(new Object[] {1, 0}); cursor.moveToFirst(); mContent.setAttachment(mMessageListingElement, cursor, mInfo, mParams); @@ -271,10 +265,14 @@ public class BluetoothMapContentTest { mInfo.mMessageColAttachment = 0; mInfo.mMessageColAttachmentSize = 1; mInfo.mMessageColAttachmentMime = 2; - MatrixCursor cursor = new MatrixCursor(new String[]{"MessageColAttachment", - "MessageColAttachmentSize", - "MessageColAttachmentMime"}); - cursor.addRow(new Object[]{1, 0, "test_mime_type"}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MessageColAttachment", + "MessageColAttachmentSize", + "MessageColAttachmentMime" + }); + cursor.addRow(new Object[] {1, 0, "test_mime_type"}); cursor.moveToFirst(); mContent.setRemoteFeatureMask(featureMask); @@ -291,8 +289,8 @@ public class BluetoothMapContentTest { mContent.setRemoteFeatureMask(featureMask); assertThat(mContent.getRemoteFeatureMask()).isEqualTo(featureMask); - assertThat(mContent.mMsgListingVersion).isEqualTo( - BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V11); + assertThat(mContent.mMsgListingVersion) + .isEqualTo(BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V11); } @Test @@ -311,14 +309,8 @@ public class BluetoothMapContentTest { StringBuilder expected = new StringBuilder(); expected.append(" AND ").append(Threads.READ).append(" = 0"); expected.append(" AND ").append(Threads.READ).append(" = 1"); - expected.append(" AND ") - .append(Threads.DATE) - .append(" >= ") - .append(lastActivity); - expected.append(" AND ") - .append(Threads.DATE) - .append(" <= ") - .append(lastActivity); + expected.append(" AND ").append(Threads.DATE).append(" >= ").append(lastActivity); + expected.append(" AND ").append(Threads.DATE).append(" <= ").append(lastActivity); expected.append(" AND ") .append(Threads._ID) .append(" = ") @@ -331,8 +323,8 @@ public class BluetoothMapContentTest { when(mParams.getParameterMask()).thenReturn((long) BluetoothMapContent.MASK_DATETIME); mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mSmsColDate = 0; - MatrixCursor cursor = new MatrixCursor(new String[]{"SmsColDate"}); - cursor.addRow(new Object[]{2L}); + MatrixCursor cursor = new MatrixCursor(new String[] {"SmsColDate"}); + cursor.addRow(new Object[] {2L}); cursor.moveToFirst(); mContent.setDateTime(mMessageListingElement, cursor, mInfo, mParams); @@ -345,8 +337,8 @@ public class BluetoothMapContentTest { when(mParams.getParameterMask()).thenReturn((long) BluetoothMapContent.MASK_DATETIME); mInfo.mMsgType = FilterInfo.TYPE_MMS; mInfo.mMmsColDate = 0; - MatrixCursor cursor = new MatrixCursor(new String[]{"MmsColDate"}); - cursor.addRow(new Object[]{2L}); + MatrixCursor cursor = new MatrixCursor(new String[] {"MmsColDate"}); + cursor.addRow(new Object[] {2L}); cursor.moveToFirst(); mContent.setDateTime(mMessageListingElement, cursor, mInfo, mParams); @@ -359,8 +351,8 @@ public class BluetoothMapContentTest { when(mParams.getParameterMask()).thenReturn((long) BluetoothMapContent.MASK_DATETIME); mInfo.mMsgType = FilterInfo.TYPE_IM; mInfo.mMessageColDate = 0; - MatrixCursor cursor = new MatrixCursor(new String[]{"MessageColDate"}); - cursor.addRow(new Object[]{2L}); + MatrixCursor cursor = new MatrixCursor(new String[] {"MessageColDate"}); + cursor.addRow(new Object[] {2L}); cursor.moveToFirst(); mContent.setDateTime(mMessageListingElement, cursor, mInfo, mParams); @@ -370,12 +362,12 @@ public class BluetoothMapContentTest { @Test public void setDeliveryStatus() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_DELIVERY_STATUS); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_DELIVERY_STATUS); mInfo.mMsgType = FilterInfo.TYPE_EMAIL; mInfo.mMessageColDelivery = 0; - MatrixCursor cursor = new MatrixCursor(new String[]{"MessageColDelivery"}); - cursor.addRow(new Object[]{"test_delivery_status"}); + MatrixCursor cursor = new MatrixCursor(new String[] {"MessageColDelivery"}); + cursor.addRow(new Object[] {"test_delivery_status"}); cursor.moveToFirst(); mContent.setDeliveryStatus(mMessageListingElement, cursor, mInfo, mParams); @@ -397,8 +389,8 @@ public class BluetoothMapContentTest { @Test public void smsSelected_withInvalidFilter() { - when(mParams.getFilterMessageType()).thenReturn( - BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getFilterMessageType()) + .thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER); assertThat(mContent.smsSelected(mInfo, mParams)).isTrue(); } @@ -443,8 +435,8 @@ public class BluetoothMapContentTest { @Test public void mmsSelected_withInvalidFilter() { - when(mParams.getFilterMessageType()).thenReturn( - BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getFilterMessageType()) + .thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER); assertThat(mContent.mmsSelected(mParams)).isTrue(); } @@ -469,9 +461,12 @@ public class BluetoothMapContentTest { mInfo.mMessageColCcAddress = 1; mInfo.mMessageColBccAddress = 2; - MatrixCursor cursor = new MatrixCursor( - new String[]{"MessageColToAddress", "MessageColCcAddress", "MessageColBccAddress"}); - cursor.addRow(new Object[]{TEST_TO_ADDRESS, TEST_CC_ADDRESS, TEST_BCC_ADDRESS}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MessageColToAddress", "MessageColCcAddress", "MessageColBccAddress" + }); + cursor.addRow(new Object[] {TEST_TO_ADDRESS, TEST_CC_ADDRESS, TEST_BCC_ADDRESS}); cursor.moveToFirst(); StringBuilder expected = new StringBuilder(); @@ -480,8 +475,7 @@ public class BluetoothMapContentTest { expected.append(Rfc822Tokenizer.tokenize(TEST_CC_ADDRESS)[0].getName()); expected.append("; "); expected.append(Rfc822Tokenizer.tokenize(TEST_BCC_ADDRESS)[0].getName()); - assertThat(mContent.getRecipientNameEmail(cursor, mInfo)).isEqualTo( - expected.toString()); + assertThat(mContent.getRecipientNameEmail(cursor, mInfo)).isEqualTo(expected.toString()); } @Test @@ -490,9 +484,12 @@ public class BluetoothMapContentTest { mInfo.mMessageColCcAddress = 1; mInfo.mMessageColBccAddress = 2; - MatrixCursor cursor = new MatrixCursor( - new String[]{"MessageColToAddress", "MessageColCcAddress", "MessageColBccAddress"}); - cursor.addRow(new Object[]{TEST_TO_ADDRESS, TEST_CC_ADDRESS, TEST_BCC_ADDRESS}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MessageColToAddress", "MessageColCcAddress", "MessageColBccAddress" + }); + cursor.addRow(new Object[] {TEST_TO_ADDRESS, TEST_CC_ADDRESS, TEST_BCC_ADDRESS}); cursor.moveToFirst(); StringBuilder expected = new StringBuilder(); @@ -501,14 +498,14 @@ public class BluetoothMapContentTest { expected.append(Rfc822Tokenizer.tokenize(TEST_CC_ADDRESS)[0].getAddress()); expected.append("; "); expected.append(Rfc822Tokenizer.tokenize(TEST_BCC_ADDRESS)[0].getAddress()); - assertThat(mContent.getRecipientAddressingEmail(cursor, mInfo)).isEqualTo( - expected.toString()); + assertThat(mContent.getRecipientAddressingEmail(cursor, mInfo)) + .isEqualTo(expected.toString()); } @Test public void setRecipientAddressing_withFilterMsgTypeSms_andSmsMsgTypeInbox() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mPhoneNum = TEST_ADDRESS; mInfo.mSmsColType = 0; @@ -523,15 +520,27 @@ public class BluetoothMapContentTest { @Test public void setRecipientAddressing_withFilterMsgTypeSms_andSmsMsgTypeDraft() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mSmsColType = 2; - MatrixCursor cursor = new MatrixCursor(new String[] {"RecipientIds", - Telephony.CanonicalAddressesColumns.ADDRESS, "SmsColType", - Telephony.Sms.ADDRESS, Telephony.Sms.THREAD_ID}); - cursor.addRow(new Object[] {"recipientIdOne recipientIdTwo", "recipientAddress", - Telephony.Sms.MESSAGE_TYPE_DRAFT, null, "0"}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "RecipientIds", + Telephony.CanonicalAddressesColumns.ADDRESS, + "SmsColType", + Telephony.Sms.ADDRESS, + Telephony.Sms.THREAD_ID + }); + cursor.addRow( + new Object[] { + "recipientIdOne recipientIdTwo", + "recipientAddress", + Telephony.Sms.MESSAGE_TYPE_DRAFT, + null, + "0" + }); cursor.moveToFirst(); mContent.setRecipientAddressing(mMessageListingElement, cursor, mInfo, mParams); @@ -541,15 +550,16 @@ public class BluetoothMapContentTest { @Test public void setRecipientAddressing_withFilterMsgTypeMms() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_MMS; - MatrixCursor cursor = new MatrixCursor( - new String[]{BaseColumns._ID, Telephony.Mms.Addr.ADDRESS}); + MatrixCursor cursor = + new MatrixCursor(new String[] {BaseColumns._ID, Telephony.Mms.Addr.ADDRESS}); cursor.addRow(new Object[] {Telephony.Sms.MESSAGE_TYPE_INBOX, null}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setRecipientAddressing(mMessageListingElement, cursor, mInfo, mParams); @@ -558,15 +568,18 @@ public class BluetoothMapContentTest { @Test public void setRecipientAddressing_withFilterMsgTypeEmail() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_RECIPIENT_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_EMAIL; mInfo.mMessageColToAddress = 0; mInfo.mMessageColCcAddress = 1; mInfo.mMessageColBccAddress = 2; - MatrixCursor cursor = new MatrixCursor( - new String[]{"MessageColToAddress", "MessageColCcAddress", "MessageColBccAddress"}); - cursor.addRow(new Object[]{TEST_TO_ADDRESS, TEST_CC_ADDRESS, TEST_BCC_ADDRESS}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MessageColToAddress", "MessageColCcAddress", "MessageColBccAddress" + }); + cursor.addRow(new Object[] {TEST_TO_ADDRESS, TEST_CC_ADDRESS, TEST_BCC_ADDRESS}); cursor.moveToFirst(); mContent.setRecipientAddressing(mMessageListingElement, cursor, mInfo, mParams); @@ -582,27 +595,28 @@ public class BluetoothMapContentTest { @Test public void setSenderAddressing_withFilterMsgTypeSms_andSmsMsgTypeInbox() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_SENDER_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_SENDER_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mSmsColType = 0; mInfo.mSmsColAddress = 1; MatrixCursor cursor = new MatrixCursor(new String[] {"SmsColType", "SmsColAddress"}); cursor.addRow(new Object[] {Telephony.Sms.MESSAGE_TYPE_INBOX, TEST_ADDRESS}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderAddressing(mMessageListingElement, cursor, mInfo, mParams); - assertThat(mMessageListingElement.getSenderAddressing()).isEqualTo( - PhoneNumberUtils.extractNetworkPortion(TEST_ADDRESS)); + assertThat(mMessageListingElement.getSenderAddressing()) + .isEqualTo(PhoneNumberUtils.extractNetworkPortion(TEST_ADDRESS)); } @Test public void setSenderAddressing_withFilterMsgTypeSms_andSmsMsgTypeDraft() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_SENDER_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_SENDER_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mPhoneNum = null; mInfo.mSmsColType = 0; @@ -617,16 +631,17 @@ public class BluetoothMapContentTest { @Test public void setSenderAddressing_withFilterMsgTypeMms() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_SENDER_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_SENDER_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_MMS; mInfo.mMmsColId = 0; - MatrixCursor cursor = new MatrixCursor( - new String[]{"MmsColId", Telephony.Mms.Addr.ADDRESS}); + MatrixCursor cursor = + new MatrixCursor(new String[] {"MmsColId", Telephony.Mms.Addr.ADDRESS}); cursor.addRow(new Object[] {0, ""}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderAddressing(mMessageListingElement, cursor, mInfo, mParams); @@ -635,13 +650,12 @@ public class BluetoothMapContentTest { @Test public void setSenderAddressing_withFilterTypeEmail() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_SENDER_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_SENDER_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_EMAIL; mInfo.mMessageColFromAddress = 0; - MatrixCursor cursor = new MatrixCursor( - new String[]{"MessageColFromAddress"}); - cursor.addRow(new Object[]{TEST_FROM_ADDRESS}); + MatrixCursor cursor = new MatrixCursor(new String[] {"MessageColFromAddress"}); + cursor.addRow(new Object[] {TEST_FROM_ADDRESS}); cursor.moveToFirst(); mContent.setSenderAddressing(mMessageListingElement, cursor, mInfo, mParams); @@ -653,16 +667,20 @@ public class BluetoothMapContentTest { @Test public void setSenderAddressing_withFilterTypeIm() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapContent.MASK_SENDER_ADDRESSING); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapContent.MASK_SENDER_ADDRESSING); mInfo.mMsgType = FilterInfo.TYPE_IM; mInfo.mMessageColFromAddress = 0; - MatrixCursor cursor = new MatrixCursor(new String[] {"MessageColFromAddress", - BluetoothMapContract.ConvoContactColumns.UCI}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MessageColFromAddress", BluetoothMapContract.ConvoContactColumns.UCI + }); cursor.addRow(new Object[] {(long) 1, TEST_ADDRESS}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderAddressing(mMessageListingElement, cursor, mInfo, mParams); @@ -674,12 +692,18 @@ public class BluetoothMapContentTest { when(mParams.getParameterMask()).thenReturn((long) BluetoothMapContent.MASK_SENDER_NAME); mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mSmsColAddress = 1; - MatrixCursor cursor = new MatrixCursor(new String[] {Telephony.Sms.TYPE, "SmsColAddress", - ContactsContract.Contacts.DISPLAY_NAME}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + Telephony.Sms.TYPE, + "SmsColAddress", + ContactsContract.Contacts.DISPLAY_NAME + }); cursor.addRow(new Object[] {Telephony.Sms.MESSAGE_TYPE_INBOX, TEST_PHONE, TEST_PHONE_NAME}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderName(mMessageListingElement, cursor, mInfo, mParams); @@ -694,8 +718,9 @@ public class BluetoothMapContentTest { MatrixCursor cursor = new MatrixCursor(new String[] {Telephony.Sms.TYPE}); cursor.addRow(new Object[] {Telephony.Sms.MESSAGE_TYPE_DRAFT}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderName(mMessageListingElement, cursor, mInfo, mParams); @@ -708,12 +733,18 @@ public class BluetoothMapContentTest { mInfo.mMsgType = FilterInfo.TYPE_MMS; mInfo.mMmsColId = 0; mMessageListingElement.setSenderAddressing(TEST_ADDRESS); - MatrixCursor cursor = new MatrixCursor(new String[] {"MmsColId", Telephony.Mms.Addr.ADDRESS, - ContactsContract.Contacts.DISPLAY_NAME}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MmsColId", + Telephony.Mms.Addr.ADDRESS, + ContactsContract.Contacts.DISPLAY_NAME + }); cursor.addRow(new Object[] {0, TEST_PHONE, TEST_PHONE_NAME}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderName(mMessageListingElement, cursor, mInfo, mParams); @@ -728,8 +759,9 @@ public class BluetoothMapContentTest { MatrixCursor cursor = new MatrixCursor(new String[] {"MmsColId"}); cursor.addRow(new Object[] {0}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderName(mMessageListingElement, cursor, mInfo, mParams); @@ -757,12 +789,16 @@ public class BluetoothMapContentTest { when(mParams.getParameterMask()).thenReturn((long) BluetoothMapContent.MASK_SENDER_NAME); mInfo.mMsgType = FilterInfo.TYPE_IM; mInfo.mMessageColFromAddress = 0; - MatrixCursor cursor = new MatrixCursor(new String[] {"MessageColFromAddress", - BluetoothMapContract.ConvoContactColumns.NAME}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + "MessageColFromAddress", BluetoothMapContract.ConvoContactColumns.NAME + }); cursor.addRow(new Object[] {(long) 1, TEST_NAME}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContent.setSenderName(mMessageListingElement, cursor, mInfo, mParams); @@ -789,8 +825,8 @@ public class BluetoothMapContentTest { public void setLastActivity_withFilterTypeSms() { mInfo.mMsgType = FilterInfo.TYPE_SMS; mInfo.mConvoColLastActivity = 0; - MatrixCursor cursor = new MatrixCursor(new String[] {"ConvoColLastActivity", - "MmsSmsThreadColDate"}); + MatrixCursor cursor = + new MatrixCursor(new String[] {"ConvoColLastActivity", "MmsSmsThreadColDate"}); cursor.addRow(new Object[] {TEST_DATE_EMAIL, TEST_DATE_SMS}); cursor.moveToFirst(); @@ -803,8 +839,8 @@ public class BluetoothMapContentTest { public void setLastActivity_withFilterTypeEmail() { mInfo.mMsgType = FilterInfo.TYPE_EMAIL; mInfo.mConvoColLastActivity = 0; - MatrixCursor cursor = new MatrixCursor(new String[] {"ConvoColLastActivity", - "MmsSmsThreadColDate"}); + MatrixCursor cursor = + new MatrixCursor(new String[] {"ConvoColLastActivity", "MmsSmsThreadColDate"}); cursor.addRow(new Object[] {TEST_DATE_EMAIL, TEST_DATE_SMS}); cursor.moveToFirst(); @@ -817,19 +853,22 @@ public class BluetoothMapContentTest { public void getEmailMessage_withCharsetNative() { when(mParams.getCharset()).thenReturn(BluetoothMapContent.MAP_MESSAGE_CHARSET_NATIVE); - assertThrows(IllegalArgumentException.class, () -> mContent.getEmailMessage(TEST_ID, - mParams, mCurrentFolder)); + assertThrows( + IllegalArgumentException.class, + () -> mContent.getEmailMessage(TEST_ID, mParams, mCurrentFolder)); } @Test public void getEmailMessage_withEmptyCursor() { when(mParams.getCharset()).thenReturn(BluetoothMapContent.MAP_MESSAGE_CHARSET_UTF8); MatrixCursor cursor = new MatrixCursor(new String[] {}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); - assertThrows(IllegalArgumentException.class, () -> mContent.getEmailMessage(TEST_ID, - mParams, mCurrentFolder)); + assertThrows( + IllegalArgumentException.class, + () -> mContent.getEmailMessage(TEST_ID, mParams, mCurrentFolder)); } @Test @@ -838,41 +877,51 @@ public class BluetoothMapContentTest { when(mParams.getFractionRequest()).thenReturn(BluetoothMapAppParams.FRACTION_REQUEST_FIRST); when(mParams.getAttachment()).thenReturn(0); - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns.RECEPTION_STATE, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.TO_LIST, - BluetoothMapContract.MessageColumns.FROM_LIST - }); - cursor.addRow(new Object[] {BluetoothMapContract.RECEPTION_STATE_FRACTIONED, "1", - TEST_INBOX_FOLDER_ID, TEST_TO_ADDRESS, TEST_FROM_ADDRESS}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.RECEPTION_STATE, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.TO_LIST, + BluetoothMapContract.MessageColumns.FROM_LIST + }); + cursor.addRow( + new Object[] { + BluetoothMapContract.RECEPTION_STATE_FRACTIONED, + "1", + TEST_INBOX_FOLDER_ID, + TEST_TO_ADDRESS, + TEST_FROM_ADDRESS + }); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mCurrentFolder.setFolderId(TEST_INBOX_FOLDER_ID); // This mock sets up FileNotFoundException during email body access - doThrow(FileNotFoundException.class).when( - mMapMethodProxy).contentResolverOpenFileDescriptor(any(), any(), any()); + doThrow(FileNotFoundException.class) + .when(mMapMethodProxy) + .contentResolverOpenFileDescriptor(any(), any(), any()); byte[] encodedMessageEmail = mContent.getEmailMessage(TEST_ID, mParams, mCurrentFolder); InputStream inputStream = new ByteArrayInputStream(encodedMessageEmail); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_UTF8); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_UTF8); assertThat(messageParsed.getType()).isEqualTo(TYPE.EMAIL); - assertThat(messageParsed.getVersionString()).isEqualTo("VERSION:" + - mContent.mMessageVersion); + assertThat(messageParsed.getVersionString()) + .isEqualTo("VERSION:" + mContent.mMessageVersion); assertThat(messageParsed.getFolder()).isEqualTo(mCurrentFolder.getFullPath()); - assertThat(messageParsed.getRecipients().get(0).getName()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getName()); - assertThat(messageParsed.getRecipients().get(0).getFirstEmail()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getAddress()); - assertThat(messageParsed.getOriginators().get(0).getName()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getName()); - assertThat(messageParsed.getOriginators().get(0).getFirstEmail()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getAddress()); + assertThat(messageParsed.getRecipients().get(0).getName()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getName()); + assertThat(messageParsed.getRecipients().get(0).getFirstEmail()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getAddress()); + assertThat(messageParsed.getOriginators().get(0).getName()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getName()); + assertThat(messageParsed.getOriginators().get(0).getFirstEmail()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getAddress()); } @Test @@ -881,41 +930,51 @@ public class BluetoothMapContentTest { when(mParams.getFractionRequest()).thenReturn(BluetoothMapAppParams.FRACTION_REQUEST_FIRST); when(mParams.getAttachment()).thenReturn(0); - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns.RECEPTION_STATE, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.TO_LIST, - BluetoothMapContract.MessageColumns.FROM_LIST - }); - cursor.addRow(new Object[] {BluetoothMapContract.RECEPTION_STATE_FRACTIONED, null, - TEST_INBOX_FOLDER_ID, TEST_TO_ADDRESS, TEST_FROM_ADDRESS}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.RECEPTION_STATE, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.TO_LIST, + BluetoothMapContract.MessageColumns.FROM_LIST + }); + cursor.addRow( + new Object[] { + BluetoothMapContract.RECEPTION_STATE_FRACTIONED, + null, + TEST_INBOX_FOLDER_ID, + TEST_TO_ADDRESS, + TEST_FROM_ADDRESS + }); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mCurrentFolder.setFolderId(TEST_INBOX_FOLDER_ID); // This mock sets up NullPointerException during email body access - doThrow(NullPointerException.class).when( - mMapMethodProxy).contentResolverOpenFileDescriptor(any(), any(), any()); + doThrow(NullPointerException.class) + .when(mMapMethodProxy) + .contentResolverOpenFileDescriptor(any(), any(), any()); byte[] encodedMessageEmail = mContent.getEmailMessage(TEST_ID, mParams, mCurrentFolder); InputStream inputStream = new ByteArrayInputStream(encodedMessageEmail); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_UTF8); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_UTF8); assertThat(messageParsed.getType()).isEqualTo(TYPE.EMAIL); - assertThat(messageParsed.getVersionString()).isEqualTo("VERSION:" + - mContent.mMessageVersion); + assertThat(messageParsed.getVersionString()) + .isEqualTo("VERSION:" + mContent.mMessageVersion); assertThat(messageParsed.getFolder()).isEqualTo(mCurrentFolder.getFullPath()); - assertThat(messageParsed.getRecipients().get(0).getName()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getName()); - assertThat(messageParsed.getRecipients().get(0).getFirstEmail()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getAddress()); - assertThat(messageParsed.getOriginators().get(0).getName()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getName()); - assertThat(messageParsed.getOriginators().get(0).getFirstEmail()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getAddress()); + assertThat(messageParsed.getRecipients().get(0).getName()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getName()); + assertThat(messageParsed.getRecipients().get(0).getFirstEmail()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getAddress()); + assertThat(messageParsed.getOriginators().get(0).getName()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getName()); + assertThat(messageParsed.getOriginators().get(0).getFirstEmail()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getAddress()); } @Test @@ -924,18 +983,27 @@ public class BluetoothMapContentTest { when(mParams.getFractionRequest()).thenReturn(BluetoothMapAppParams.FRACTION_REQUEST_FIRST); when(mParams.getAttachment()).thenReturn(0); - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns.RECEPTION_STATE, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.TO_LIST, - BluetoothMapContract.MessageColumns.FROM_LIST - }); - cursor.addRow(new Object[] {BluetoothMapContract.RECEPTION_STATE_FRACTIONED, "1", - TEST_INBOX_FOLDER_ID, TEST_TO_ADDRESS, TEST_FROM_ADDRESS}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.RECEPTION_STATE, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.TO_LIST, + BluetoothMapContract.MessageColumns.FROM_LIST + }); + cursor.addRow( + new Object[] { + BluetoothMapContract.RECEPTION_STATE_FRACTIONED, + "1", + TEST_INBOX_FOLDER_ID, + TEST_TO_ADDRESS, + TEST_FROM_ADDRESS + }); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mCurrentFolder.setFolderId(TEST_INBOX_FOLDER_ID); FileDescriptor fd = new FileDescriptor(); @@ -945,29 +1013,30 @@ public class BluetoothMapContentTest { byte[] encodedMessageEmail = mContent.getEmailMessage(TEST_ID, mParams, mCurrentFolder); InputStream inputStream = new ByteArrayInputStream(encodedMessageEmail); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_UTF8); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_UTF8); assertThat(messageParsed.getType()).isEqualTo(TYPE.EMAIL); - assertThat(messageParsed.getVersionString()).isEqualTo("VERSION:" + - mContent.mMessageVersion); + assertThat(messageParsed.getVersionString()) + .isEqualTo("VERSION:" + mContent.mMessageVersion); assertThat(messageParsed.getFolder()).isEqualTo(mCurrentFolder.getFullPath()); - assertThat(messageParsed.getRecipients().get(0).getName()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getName()); - assertThat(messageParsed.getRecipients().get(0).getFirstEmail()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getAddress()); - assertThat(messageParsed.getOriginators().get(0).getName()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getName()); - assertThat(messageParsed.getOriginators().get(0).getFirstEmail()).isEqualTo( - Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getAddress()); + assertThat(messageParsed.getRecipients().get(0).getName()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getName()); + assertThat(messageParsed.getRecipients().get(0).getFirstEmail()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_TO_ADDRESS)[0].getAddress()); + assertThat(messageParsed.getOriginators().get(0).getName()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getName()); + assertThat(messageParsed.getOriginators().get(0).getFirstEmail()) + .isEqualTo(Rfc822Tokenizer.tokenize(TEST_FROM_ADDRESS)[0].getAddress()); } @Test public void getIMMessage_withCharsetNative() { when(mParams.getCharset()).thenReturn(BluetoothMapContent.MAP_MESSAGE_CHARSET_NATIVE); - assertThrows(IllegalArgumentException.class, () -> mContent.getIMMessage(TEST_ID, - mParams, mCurrentFolder)); + assertThrows( + IllegalArgumentException.class, + () -> mContent.getIMMessage(TEST_ID, mParams, mCurrentFolder)); } @Test @@ -975,11 +1044,13 @@ public class BluetoothMapContentTest { when(mParams.getCharset()).thenReturn(BluetoothMapContent.MAP_MESSAGE_CHARSET_UTF8); MatrixCursor cursor = new MatrixCursor(new String[] {}); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); - assertThrows(IllegalArgumentException.class, () -> mContent.getIMMessage(TEST_ID, - mParams, mCurrentFolder)); + assertThrows( + IllegalArgumentException.class, + () -> mContent.getIMMessage(TEST_ID, mParams, mCurrentFolder)); } @Test @@ -987,26 +1058,41 @@ public class BluetoothMapContentTest { when(mParams.getCharset()).thenReturn(BluetoothMapContent.MAP_MESSAGE_CHARSET_UTF8); when(mParams.getAttachment()).thenReturn(1); - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.THREAD_ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, - BluetoothMapContract.MessageColumns.BODY, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.UCI, - }); - cursor.addRow(new Object[] {1, 1, TEST_SENT_FOLDER_ID, TEST_SUBJECT, TEST_MESSAGE_ID, - TEST_DATE, 0, "body", TEST_NAME, TEST_FIRST_BT_UID, TEST_FORMATTED_NAME, - TEST_FIRST_BT_UCI_RECIPIENT}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.THREAD_ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, + BluetoothMapContract.MessageColumns.BODY, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.UCI, + }); + cursor.addRow( + new Object[] { + 1, + 1, + TEST_SENT_FOLDER_ID, + TEST_SUBJECT, + TEST_MESSAGE_ID, + TEST_DATE, + 0, + "body", + TEST_NAME, + TEST_FIRST_BT_UID, + TEST_FORMATTED_NAME, + TEST_FIRST_BT_UCI_RECIPIENT + }); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mCurrentFolder.setFolderId(TEST_SENT_FOLDER_ID); when(mAccountItem.getUciFull()).thenReturn(TEST_FIRST_BT_UCI_ORIGINATOR); @@ -1017,14 +1103,14 @@ public class BluetoothMapContentTest { assertThat(messageMimeParsed.mAppParamCharset).isEqualTo(1); assertThat(messageMimeParsed.getType()).isEqualTo(TYPE.IM); - assertThat(messageMimeParsed.getVersionString()).isEqualTo("VERSION:" + - mContent.mMessageVersion); + assertThat(messageMimeParsed.getVersionString()) + .isEqualTo("VERSION:" + mContent.mMessageVersion); assertThat(messageMimeParsed.getFolder()).isEqualTo(mCurrentFolder.getFullPath()); assertThat(messageMimeParsed.getRecipients().size()).isEqualTo(1); assertThat(messageMimeParsed.getOriginators().size()).isEqualTo(1); assertThat(messageMimeParsed.getOriginators().get(0).getName()).isEmpty(); - assertThat(messageMimeParsed.getRecipients().get(0).getName()).isEqualTo( - TEST_FORMATTED_NAME); + assertThat(messageMimeParsed.getRecipients().get(0).getName()) + .isEqualTo(TEST_FORMATTED_NAME); } @Test @@ -1032,26 +1118,41 @@ public class BluetoothMapContentTest { when(mParams.getCharset()).thenReturn(BluetoothMapContent.MAP_MESSAGE_CHARSET_UTF8); when(mParams.getAttachment()).thenReturn(1); - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.THREAD_ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, - BluetoothMapContract.MessageColumns.BODY, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.UCI, - }); - cursor.addRow(new Object[] {0, 1, TEST_INBOX_FOLDER_ID, TEST_SUBJECT, TEST_MESSAGE_ID, - TEST_DATE, 0, "body", TEST_NAME, TEST_FIRST_BT_UID, TEST_FORMATTED_NAME, - TEST_FIRST_BT_UCI_ORIGINATOR}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.THREAD_ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, + BluetoothMapContract.MessageColumns.BODY, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.UCI, + }); + cursor.addRow( + new Object[] { + 0, + 1, + TEST_INBOX_FOLDER_ID, + TEST_SUBJECT, + TEST_MESSAGE_ID, + TEST_DATE, + 0, + "body", + TEST_NAME, + TEST_FIRST_BT_UID, + TEST_FORMATTED_NAME, + TEST_FIRST_BT_UCI_ORIGINATOR + }); cursor.moveToFirst(); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mCurrentFolder.setFolderId(TEST_INBOX_FOLDER_ID); when(mAccountItem.getUciFull()).thenReturn(TEST_FIRST_BT_UCI_RECIPIENT); @@ -1062,55 +1163,88 @@ public class BluetoothMapContentTest { assertThat(messageMimeParsed.mAppParamCharset).isEqualTo(1); assertThat(messageMimeParsed.getType()).isEqualTo(TYPE.IM); - assertThat(messageMimeParsed.getVersionString()).isEqualTo("VERSION:" + - mContent.mMessageVersion); + assertThat(messageMimeParsed.getVersionString()) + .isEqualTo("VERSION:" + mContent.mMessageVersion); assertThat(messageMimeParsed.getFolder()).isEqualTo(mCurrentFolder.getFullPath()); assertThat(messageMimeParsed.getRecipients().size()).isEqualTo(1); assertThat(messageMimeParsed.getOriginators().size()).isEqualTo(1); - assertThat(messageMimeParsed.getOriginators().get(0).getName()).isEqualTo( - TEST_FORMATTED_NAME); + assertThat(messageMimeParsed.getOriginators().get(0).getName()) + .isEqualTo(TEST_FORMATTED_NAME); assertThat(messageMimeParsed.getRecipients().get(0).getName()).isEmpty(); } @Test public void convoListing_withNullFilterRecipient() { - when(mParams.getConvoParameterMask()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getConvoParameterMask()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(mParams.getFilterMessageType()).thenReturn(TEST_NO_FILTER); when(mParams.getMaxListCount()).thenReturn(2); when(mParams.getStartOffset()).thenReturn(0); // This mock sets filter recipient to null when(mParams.getFilterRecipient()).thenReturn(null); - MatrixCursor smsMmsCursor = new MatrixCursor(new String[] {"MmsSmsThreadColId", - "MmsSmsThreadColDate", "MmsSmsThreadColSnippet", "MmsSmsThreadSnippetCharset", - "MmsSmsThreadColRead", "MmsSmsThreadColRecipientIds"}); - smsMmsCursor.addRow(new Object[] {TEST_ID, TEST_DATE_SMS, "test_col_snippet", - "test_col_snippet_cs", 1, "test_recipient_ids"}); + MatrixCursor smsMmsCursor = + new MatrixCursor( + new String[] { + "MmsSmsThreadColId", + "MmsSmsThreadColDate", + "MmsSmsThreadColSnippet", + "MmsSmsThreadSnippetCharset", + "MmsSmsThreadColRead", + "MmsSmsThreadColRecipientIds" + }); + smsMmsCursor.addRow( + new Object[] { + TEST_ID, + TEST_DATE_SMS, + "test_col_snippet", + "test_col_snippet_cs", + 1, + "test_recipient_ids" + }); smsMmsCursor.moveToFirst(); - doReturn(smsMmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.MMS_SMS_THREAD_PROJECTION), any(), any(), any()); - - MatrixCursor imEmailCursor = new MatrixCursor( - new String[] {BluetoothMapContract.ConversationColumns.THREAD_ID, - BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY, - BluetoothMapContract.ConversationColumns.THREAD_NAME, - BluetoothMapContract.ConversationColumns.READ_STATUS, - BluetoothMapContract.ConversationColumns.VERSION_COUNTER, - BluetoothMapContract.ConversationColumns.SUMMARY, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY}); - imEmailCursor.addRow(new Object[] {TEST_ID, TEST_DATE_EMAIL, TEST_NAME, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}); - doReturn(imEmailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_CONVERSATION_PROJECTION), any(), any(), any()); + doReturn(smsMmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContent.MMS_SMS_THREAD_PROJECTION), + any(), + any(), + any()); + + MatrixCursor imEmailCursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConversationColumns.THREAD_ID, + BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY, + BluetoothMapContract.ConversationColumns.THREAD_NAME, + BluetoothMapContract.ConversationColumns.READ_STATUS, + BluetoothMapContract.ConversationColumns.VERSION_COUNTER, + BluetoothMapContract.ConversationColumns.SUMMARY, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY + }); + imEmailCursor.addRow( + new Object[] { + TEST_ID, TEST_DATE_EMAIL, TEST_NAME, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }); + doReturn(imEmailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_CONVERSATION_PROJECTION), + any(), + any(), + any()); BluetoothMapConvoListing listing = mContent.convoListing(mParams, false); @@ -1129,55 +1263,92 @@ public class BluetoothMapContentTest { @Test public void convoListing_withNonNullFilterRecipient() { - when(mParams.getConvoParameterMask()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getConvoParameterMask()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(mParams.getFilterMessageType()).thenReturn(BluetoothMapAppParams.FILTER_NO_EMAIL); when(mParams.getMaxListCount()).thenReturn(2); when(mParams.getStartOffset()).thenReturn(0); // This mock sets filter recipient to non null when(mParams.getFilterRecipient()).thenReturn(TEST_CONTACT_NAME_FILTER); - MatrixCursor smsMmsCursor = new MatrixCursor(new String[] {"MmsSmsThreadColId", - "MmsSmsThreadColDate", "MmsSmsThreadColSnippet", "MmsSmsThreadSnippetCharset", - "MmsSmsThreadColRead", "MmsSmsThreadColRecipientIds"}); - smsMmsCursor.addRow(new Object[] {TEST_ID, TEST_DATE_SMS, "test_col_snippet", - "test_col_snippet_cs", 1, String.valueOf(TEST_ID)}); + MatrixCursor smsMmsCursor = + new MatrixCursor( + new String[] { + "MmsSmsThreadColId", + "MmsSmsThreadColDate", + "MmsSmsThreadColSnippet", + "MmsSmsThreadSnippetCharset", + "MmsSmsThreadColRead", + "MmsSmsThreadColRecipientIds" + }); + smsMmsCursor.addRow( + new Object[] { + TEST_ID, + TEST_DATE_SMS, + "test_col_snippet", + "test_col_snippet_cs", + 1, + String.valueOf(TEST_ID) + }); smsMmsCursor.moveToFirst(); - doReturn(smsMmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.MMS_SMS_THREAD_PROJECTION), any(), any(), any()); - - MatrixCursor addressCursor = new MatrixCursor(new String[] {"COL_ADDR_ID", - "COL_ADDR_ADDR"}); - addressCursor.addRow(new Object[]{TEST_ID, TEST_ADDRESS}); - doReturn(addressCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(SmsMmsContacts.ADDRESS_PROJECTION), any(), any(), any()); - - MatrixCursor contactCursor = new MatrixCursor(new String[] {"COL_CONTACT_ID", - "COL_CONTACT_NAME"}); - contactCursor.addRow(new Object[]{TEST_ID, TEST_NAME}); - doReturn(contactCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(SmsMmsContacts.CONTACT_PROJECTION), any(), any(), any()); - - MatrixCursor imEmailCursor = new MatrixCursor( - new String[] {BluetoothMapContract.ConversationColumns.THREAD_ID, - BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY, - BluetoothMapContract.ConversationColumns.THREAD_NAME, - BluetoothMapContract.ConversationColumns.READ_STATUS, - BluetoothMapContract.ConversationColumns.VERSION_COUNTER, - BluetoothMapContract.ConversationColumns.SUMMARY, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY}); - imEmailCursor.addRow(new Object[] {TEST_ID, TEST_DATE_EMAIL, TEST_NAME, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}); - doReturn(imEmailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_CONVERSATION_PROJECTION), any(), any(), any()); + doReturn(smsMmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContent.MMS_SMS_THREAD_PROJECTION), + any(), + any(), + any()); + + MatrixCursor addressCursor = + new MatrixCursor(new String[] {"COL_ADDR_ID", "COL_ADDR_ADDR"}); + addressCursor.addRow(new Object[] {TEST_ID, TEST_ADDRESS}); + doReturn(addressCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(SmsMmsContacts.ADDRESS_PROJECTION), any(), any(), any()); + + MatrixCursor contactCursor = + new MatrixCursor(new String[] {"COL_CONTACT_ID", "COL_CONTACT_NAME"}); + contactCursor.addRow(new Object[] {TEST_ID, TEST_NAME}); + doReturn(contactCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(SmsMmsContacts.CONTACT_PROJECTION), any(), any(), any()); + + MatrixCursor imEmailCursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConversationColumns.THREAD_ID, + BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY, + BluetoothMapContract.ConversationColumns.THREAD_NAME, + BluetoothMapContract.ConversationColumns.READ_STATUS, + BluetoothMapContract.ConversationColumns.VERSION_COUNTER, + BluetoothMapContract.ConversationColumns.SUMMARY, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY + }); + imEmailCursor.addRow( + new Object[] { + TEST_ID, TEST_DATE_EMAIL, TEST_NAME, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }); + doReturn(imEmailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_CONVERSATION_PROJECTION), + any(), + any(), + any()); BluetoothMapConvoListing listing = mContent.convoListing(mParams, false); @@ -1196,8 +1367,8 @@ public class BluetoothMapContentTest { @Test public void msgListing_withSmsCursorOnly() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); int noMms = BluetoothMapAppParams.FILTER_NO_MMS; when(mParams.getFilterMessageType()).thenReturn(noMms); when(mParams.getMaxListCount()).thenReturn(1); @@ -1207,16 +1378,46 @@ public class BluetoothMapContentTest { mCurrentFolder.setFolderId(TEST_ID); mContent.mMsgListingVersion = BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V11; - MatrixCursor smsCursor = new MatrixCursor(new String[] {BaseColumns._ID, Telephony.Sms.TYPE, - Telephony.Sms.READ, Telephony.Sms.BODY, Telephony.Sms.ADDRESS, Telephony.Sms.DATE, - Telephony.Sms.THREAD_ID, ContactsContract.Contacts.DISPLAY_NAME}); - smsCursor.addRow(new Object[] {TEST_ID, TEST_SENT_NO, TEST_READ_TRUE, TEST_SUBJECT, - TEST_ADDRESS, TEST_DATE_SMS, TEST_THREAD_ID, TEST_PHONE_NAME}); - doReturn(smsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.SMS_PROJECTION), any(), any(), any()); - doReturn(smsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(new String[] {ContactsContract.Contacts._ID, - ContactsContract.Contacts.DISPLAY_NAME}), any(), any(), any()); + MatrixCursor smsCursor = + new MatrixCursor( + new String[] { + BaseColumns._ID, + Telephony.Sms.TYPE, + Telephony.Sms.READ, + Telephony.Sms.BODY, + Telephony.Sms.ADDRESS, + Telephony.Sms.DATE, + Telephony.Sms.THREAD_ID, + ContactsContract.Contacts.DISPLAY_NAME + }); + smsCursor.addRow( + new Object[] { + TEST_ID, + TEST_SENT_NO, + TEST_READ_TRUE, + TEST_SUBJECT, + TEST_ADDRESS, + TEST_DATE_SMS, + TEST_THREAD_ID, + TEST_PHONE_NAME + }); + doReturn(smsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(BluetoothMapContent.SMS_PROJECTION), any(), any(), any()); + doReturn(smsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq( + new String[] { + ContactsContract.Contacts._ID, + ContactsContract.Contacts.DISPLAY_NAME + }), + any(), + any(), + any()); BluetoothMapMessageListing listing = mContent.msgListing(mCurrentFolder, mParams); assertThat(listing.getCount()).isEqualTo(1); @@ -1226,8 +1427,8 @@ public class BluetoothMapContentTest { assertThat(smsElement.getDateTime()).isEqualTo(TEST_DATE_SMS); assertThat(smsElement.getType()).isEqualTo(TYPE.SMS_GSM); assertThat(smsElement.getReadBool()).isTrue(); - assertThat(smsElement.getSenderAddressing()).isEqualTo( - PhoneNumberUtils.extractNetworkPortion(TEST_ADDRESS)); + assertThat(smsElement.getSenderAddressing()) + .isEqualTo(PhoneNumberUtils.extractNetworkPortion(TEST_ADDRESS)); assertThat(smsElement.getSenderName()).isEqualTo(TEST_PHONE_NAME); assertThat(smsElement.getSize()).isEqualTo(TEST_SUBJECT.length()); assertThat(smsElement.getPriority()).isEqualTo(TEST_NO); @@ -1240,10 +1441,11 @@ public class BluetoothMapContentTest { @Test public void msgListing_withMmsCursorOnly() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); int onlyMms = - BluetoothMapAppParams.FILTER_NO_EMAIL | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + BluetoothMapAppParams.FILTER_NO_EMAIL + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA | BluetoothMapAppParams.FILTER_NO_SMS_GSM | BluetoothMapAppParams.FILTER_NO_IM; when(mParams.getFilterMessageType()).thenReturn(onlyMms); @@ -1254,21 +1456,61 @@ public class BluetoothMapContentTest { mCurrentFolder.setFolderId(TEST_ID); mContent.mMsgListingVersion = BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V11; - MatrixCursor mmsCursor = new MatrixCursor(new String[] {BaseColumns._ID, - Telephony.Mms.MESSAGE_BOX, Telephony.Mms.READ, Telephony.Mms.MESSAGE_SIZE, - Telephony.Mms.TEXT_ONLY, Telephony.Mms.DATE, Telephony.Mms.SUBJECT, - Telephony.Mms.THREAD_ID, Telephony.Mms.Addr.ADDRESS, - ContactsContract.Contacts.DISPLAY_NAME, Telephony.Mms.PRIORITY}); - mmsCursor.addRow(new Object[] {TEST_ID, TEST_SENT_NO, TEST_READ_FALSE, TEST_SIZE, - TEST_TEXT_ONLY, TEST_DATE_MMS, TEST_SUBJECT, TEST_THREAD_ID, TEST_PHONE, - TEST_PHONE_NAME, PduHeaders.PRIORITY_HIGH}); - doReturn(mmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.MMS_PROJECTION), any(), any(), any()); - doReturn(mmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(new String[] {Telephony.Mms.Addr.ADDRESS}), any(), any(), any()); - doReturn(mmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(new String[] {ContactsContract.Contacts._ID, - ContactsContract.Contacts.DISPLAY_NAME}), any(), any(), any()); + MatrixCursor mmsCursor = + new MatrixCursor( + new String[] { + BaseColumns._ID, + Telephony.Mms.MESSAGE_BOX, + Telephony.Mms.READ, + Telephony.Mms.MESSAGE_SIZE, + Telephony.Mms.TEXT_ONLY, + Telephony.Mms.DATE, + Telephony.Mms.SUBJECT, + Telephony.Mms.THREAD_ID, + Telephony.Mms.Addr.ADDRESS, + ContactsContract.Contacts.DISPLAY_NAME, + Telephony.Mms.PRIORITY + }); + mmsCursor.addRow( + new Object[] { + TEST_ID, + TEST_SENT_NO, + TEST_READ_FALSE, + TEST_SIZE, + TEST_TEXT_ONLY, + TEST_DATE_MMS, + TEST_SUBJECT, + TEST_THREAD_ID, + TEST_PHONE, + TEST_PHONE_NAME, + PduHeaders.PRIORITY_HIGH + }); + doReturn(mmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(BluetoothMapContent.MMS_PROJECTION), any(), any(), any()); + doReturn(mmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(new String[] {Telephony.Mms.Addr.ADDRESS}), + any(), + any(), + any()); + doReturn(mmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq( + new String[] { + ContactsContract.Contacts._ID, + ContactsContract.Contacts.DISPLAY_NAME + }), + any(), + any(), + any()); BluetoothMapMessageListing listing = mContent.msgListing(mCurrentFolder, mParams); assertThat(listing.getCount()).isEqualTo(1); @@ -1291,10 +1533,11 @@ public class BluetoothMapContentTest { @Test public void msgListing_withEmailCursorOnly() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); int onlyEmail = - BluetoothMapAppParams.FILTER_NO_MMS | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + BluetoothMapAppParams.FILTER_NO_MMS + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA | BluetoothMapAppParams.FILTER_NO_SMS_GSM | BluetoothMapAppParams.FILTER_NO_IM; when(mParams.getFilterMessageType()).thenReturn(onlyEmail); @@ -1305,31 +1548,58 @@ public class BluetoothMapContentTest { mCurrentFolder.setFolderId(TEST_ID); mContent.mMsgListingVersion = BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V11; - MatrixCursor emailCursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.MESSAGE_SIZE, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.TO_LIST, - BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT, - BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, - BluetoothMapContract.MessageColumns.FLAG_PROTECTED, - BluetoothMapContract.MessageColumns.RECEPTION_STATE, - BluetoothMapContract.MessageColumns.DEVILERY_STATE, - BluetoothMapContract.MessageColumns.THREAD_ID, - BluetoothMapContract.MessageColumns.CC_LIST, - BluetoothMapContract.MessageColumns.BCC_LIST, - BluetoothMapContract.MessageColumns.REPLY_TO_LIST}); - emailCursor.addRow(new Object[] {TEST_ID, TEST_DATE_EMAIL, TEST_SUBJECT, TEST_SENT_YES, - TEST_READ_TRUE, TEST_SIZE, TEST_FROM_ADDRESS, TEST_TO_ADDRESS, TEST_ATTACHMENT_TRUE, - 0, TEST_PRIORITY_HIGH, TEST_PROTECTED, 0, TEST_DELIVERY_STATE, - TEST_THREAD_ID, TEST_CC_ADDRESS, TEST_BCC_ADDRESS, TEST_TO_ADDRESS}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_MESSAGE_PROJECTION), any(), any(), any()); + MatrixCursor emailCursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.MESSAGE_SIZE, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.TO_LIST, + BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT, + BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, + BluetoothMapContract.MessageColumns.FLAG_PROTECTED, + BluetoothMapContract.MessageColumns.RECEPTION_STATE, + BluetoothMapContract.MessageColumns.DEVILERY_STATE, + BluetoothMapContract.MessageColumns.THREAD_ID, + BluetoothMapContract.MessageColumns.CC_LIST, + BluetoothMapContract.MessageColumns.BCC_LIST, + BluetoothMapContract.MessageColumns.REPLY_TO_LIST + }); + emailCursor.addRow( + new Object[] { + TEST_ID, + TEST_DATE_EMAIL, + TEST_SUBJECT, + TEST_SENT_YES, + TEST_READ_TRUE, + TEST_SIZE, + TEST_FROM_ADDRESS, + TEST_TO_ADDRESS, + TEST_ATTACHMENT_TRUE, + 0, + TEST_PRIORITY_HIGH, + TEST_PROTECTED, + 0, + TEST_DELIVERY_STATE, + TEST_THREAD_ID, + TEST_CC_ADDRESS, + TEST_BCC_ADDRESS, + TEST_TO_ADDRESS + }); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_MESSAGE_PROJECTION), + any(), + any(), + any()); BluetoothMapMessageListing listing = mContent.msgListing(mCurrentFolder, mParams); assertThat(listing.getCount()).isEqualTo(1); @@ -1356,10 +1626,13 @@ public class BluetoothMapContentTest { @Test public void msgListing_withImCursorOnly() { - when(mParams.getParameterMask()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); - int onlyIm = BluetoothMapAppParams.FILTER_NO_MMS | BluetoothMapAppParams.FILTER_NO_SMS_CDMA - | BluetoothMapAppParams.FILTER_NO_SMS_GSM | BluetoothMapAppParams.FILTER_NO_EMAIL; + when(mParams.getParameterMask()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + int onlyIm = + BluetoothMapAppParams.FILTER_NO_MMS + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + | BluetoothMapAppParams.FILTER_NO_SMS_GSM + | BluetoothMapAppParams.FILTER_NO_EMAIL; when(mParams.getFilterMessageType()).thenReturn(onlyIm); when(mParams.getMaxListCount()).thenReturn(1); when(mParams.getStartOffset()).thenReturn(0); @@ -1368,35 +1641,71 @@ public class BluetoothMapContentTest { mCurrentFolder.setFolderId(TEST_ID); mContent.mMsgListingVersion = BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V11; - MatrixCursor imCursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.MESSAGE_SIZE, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.TO_LIST, - BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT, - BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, - BluetoothMapContract.MessageColumns.FLAG_PROTECTED, - BluetoothMapContract.MessageColumns.RECEPTION_STATE, - BluetoothMapContract.MessageColumns.DEVILERY_STATE, - BluetoothMapContract.MessageColumns.THREAD_ID, - BluetoothMapContract.MessageColumns.THREAD_NAME, - BluetoothMapContract.MessageColumns.ATTACHMENT_MINE_TYPES, - BluetoothMapContract.MessageColumns.BODY, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.NAME}); - imCursor.addRow(new Object[] {TEST_ID, TEST_DATE_IM, TEST_SUBJECT, TEST_SENT_NO, - TEST_READ_FALSE, TEST_SIZE, TEST_ID, TEST_TO_ADDRESS, TEST_ATTACHMENT_TRUE, - 0 /*=attachment size*/, TEST_PRIORITY_HIGH, TEST_PROTECTED, 0, TEST_DELIVERY_STATE, - TEST_THREAD_ID, TEST_NAME, TEST_ATTACHMENT_MIME_TYPE, 0, TEST_ADDRESS, TEST_NAME}); - doReturn(imCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION), any(), any(), any()); - doReturn(imCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_CONTACT_PROJECTION), any(), any(), any()); + MatrixCursor imCursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.MESSAGE_SIZE, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.TO_LIST, + BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT, + BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, + BluetoothMapContract.MessageColumns.FLAG_PROTECTED, + BluetoothMapContract.MessageColumns.RECEPTION_STATE, + BluetoothMapContract.MessageColumns.DEVILERY_STATE, + BluetoothMapContract.MessageColumns.THREAD_ID, + BluetoothMapContract.MessageColumns.THREAD_NAME, + BluetoothMapContract.MessageColumns.ATTACHMENT_MINE_TYPES, + BluetoothMapContract.MessageColumns.BODY, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.NAME + }); + imCursor.addRow( + new Object[] { + TEST_ID, + TEST_DATE_IM, + TEST_SUBJECT, + TEST_SENT_NO, + TEST_READ_FALSE, + TEST_SIZE, + TEST_ID, + TEST_TO_ADDRESS, + TEST_ATTACHMENT_TRUE, + 0 /*=attachment size*/, + TEST_PRIORITY_HIGH, + TEST_PROTECTED, + 0, + TEST_DELIVERY_STATE, + TEST_THREAD_ID, + TEST_NAME, + TEST_ATTACHMENT_MIME_TYPE, + 0, + TEST_ADDRESS, + TEST_NAME + }); + doReturn(imCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION), + any(), + any(), + any()); + doReturn(imCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_CONTACT_PROJECTION), + any(), + any(), + any()); BluetoothMapMessageListing listing = mContent.msgListing(mCurrentFolder, mParams); assertThat(listing.getCount()).isEqualTo(1); @@ -1430,26 +1739,44 @@ public class BluetoothMapContentTest { MatrixCursor smsCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 smsCursor.addRow(new Object[] {1}); - doReturn(smsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.SMS_PROJECTION), any(), any(), any()); + doReturn(smsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(BluetoothMapContent.SMS_PROJECTION), any(), any(), any()); MatrixCursor mmsCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 mmsCursor.addRow(new Object[] {1}); - doReturn(mmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.MMS_PROJECTION), any(), any(), any()); + doReturn(mmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(BluetoothMapContent.MMS_PROJECTION), any(), any(), any()); MatrixCursor emailCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 emailCursor.addRow(new Object[] {1}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_MESSAGE_PROJECTION), any(), any(), any()); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_MESSAGE_PROJECTION), + any(), + any(), + any()); MatrixCursor imCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 imCursor.addRow(new Object[] {1}); - doReturn(imCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION), any(), any(), any()); + doReturn(imCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION), + any(), + any(), + any()); assertThat(mContent.msgListingSize(mCurrentFolder, mParams)).isEqualTo(4); } @@ -1465,49 +1792,92 @@ public class BluetoothMapContentTest { MatrixCursor smsCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 smsCursor.addRow(new Object[] {1}); - doReturn(smsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.SMS_PROJECTION), any(), any(), any()); + doReturn(smsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(BluetoothMapContent.SMS_PROJECTION), any(), any(), any()); MatrixCursor mmsCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 mmsCursor.addRow(new Object[] {1}); - doReturn(mmsCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContent.MMS_PROJECTION), any(), any(), any()); + doReturn(mmsCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), any(), eq(BluetoothMapContent.MMS_PROJECTION), any(), any(), any()); MatrixCursor emailCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 emailCursor.addRow(new Object[] {1}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_MESSAGE_PROJECTION), any(), any(), any()); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_MESSAGE_PROJECTION), + any(), + any(), + any()); MatrixCursor imCursor = new MatrixCursor(new String[] {"Placeholder"}); // Making cursor.getCount() as 1 imCursor.addRow(new Object[] {1}); - doReturn(imCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), - eq(BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION), any(), any(), any()); + doReturn(imCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + eq(BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION), + any(), + any(), + any()); assertThat(mContent.msgListingHasUnread(mCurrentFolder, mParams)).isTrue(); } @Test public void extractMmsAddresses_withTypeMmsFrom() { - MatrixCursor addressCursor = new MatrixCursor(new String[] {Telephony.Mms.Addr.ADDRESS, - Telephony.Mms.Addr.TYPE}); + MatrixCursor addressCursor = + new MatrixCursor( + new String[] {Telephony.Mms.Addr.ADDRESS, Telephony.Mms.Addr.TYPE}); addressCursor.addRow(new Object[] {TEST_ADDRESS, BluetoothMapContent.MMS_FROM}); - doReturn(addressCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), any(), any()); - - MatrixCursor contactCursor = new MatrixCursor(new String[] {ContactsContract.Contacts._ID, - ContactsContract.Contacts.DISPLAY_NAME}); + doReturn(addressCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), + any(), + any()); + + MatrixCursor contactCursor = + new MatrixCursor( + new String[] { + ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME + }); contactCursor.addRow(new Object[] {TEST_ID_STRING, TEST_NAME}); - doReturn(contactCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), any(), any()); - - MatrixCursor emailCursor = new MatrixCursor( - new String[]{ContactsContract.CommonDataKinds.Email.ADDRESS}); + doReturn(contactCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), + any(), + any()); + + MatrixCursor emailCursor = + new MatrixCursor(new String[] {ContactsContract.CommonDataKinds.Email.ADDRESS}); emailCursor.addRow(new Object[] {TEST_EMAIL}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), any(), any()); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), + any(), + any()); BluetoothMapbMessageMime mime = new BluetoothMapbMessageMime(); mContent.extractMmsAddresses(TEST_ID, mime); @@ -1519,23 +1889,48 @@ public class BluetoothMapContentTest { @Test public void extractMmsAddresses_withTypeMmsTo() { - MatrixCursor addressCursor = new MatrixCursor(new String[] {Telephony.Mms.Addr.ADDRESS, - Telephony.Mms.Addr.TYPE}); + MatrixCursor addressCursor = + new MatrixCursor( + new String[] {Telephony.Mms.Addr.ADDRESS, Telephony.Mms.Addr.TYPE}); addressCursor.addRow(new Object[] {TEST_ADDRESS, BluetoothMapContent.MMS_TO}); - doReturn(addressCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), any(), any()); - - MatrixCursor contactCursor = new MatrixCursor(new String[] {ContactsContract.Contacts._ID, - ContactsContract.Contacts.DISPLAY_NAME}); + doReturn(addressCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), + any(), + any()); + + MatrixCursor contactCursor = + new MatrixCursor( + new String[] { + ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME + }); contactCursor.addRow(new Object[] {TEST_ID_STRING, TEST_NAME}); - doReturn(contactCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), any(), any()); - - MatrixCursor emailCursor = new MatrixCursor( - new String[]{ContactsContract.CommonDataKinds.Email.ADDRESS}); + doReturn(contactCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), + any(), + any()); + + MatrixCursor emailCursor = + new MatrixCursor(new String[] {ContactsContract.CommonDataKinds.Email.ADDRESS}); emailCursor.addRow(new Object[] {TEST_EMAIL}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), any(), any()); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), + any(), + any()); BluetoothMapbMessageMime mime = new BluetoothMapbMessageMime(); mContent.extractMmsAddresses(TEST_ID, mime); @@ -1547,23 +1942,48 @@ public class BluetoothMapContentTest { @Test public void extractMmsAddresses_withTypeMmsCc() { - MatrixCursor addressCursor = new MatrixCursor(new String[] {Telephony.Mms.Addr.ADDRESS, - Telephony.Mms.Addr.TYPE}); + MatrixCursor addressCursor = + new MatrixCursor( + new String[] {Telephony.Mms.Addr.ADDRESS, Telephony.Mms.Addr.TYPE}); addressCursor.addRow(new Object[] {TEST_ADDRESS, BluetoothMapContent.MMS_CC}); - doReturn(addressCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), any(), any()); - - MatrixCursor contactCursor = new MatrixCursor(new String[] {ContactsContract.Contacts._ID, - ContactsContract.Contacts.DISPLAY_NAME}); + doReturn(addressCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), + any(), + any()); + + MatrixCursor contactCursor = + new MatrixCursor( + new String[] { + ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME + }); contactCursor.addRow(new Object[] {TEST_ID_STRING, TEST_NAME}); - doReturn(contactCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), any(), any()); - - MatrixCursor emailCursor = new MatrixCursor( - new String[]{ContactsContract.CommonDataKinds.Email.ADDRESS}); + doReturn(contactCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), + any(), + any()); + + MatrixCursor emailCursor = + new MatrixCursor(new String[] {ContactsContract.CommonDataKinds.Email.ADDRESS}); emailCursor.addRow(new Object[] {TEST_EMAIL}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), any(), any()); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), + any(), + any()); BluetoothMapbMessageMime mime = new BluetoothMapbMessageMime(); mContent.extractMmsAddresses(TEST_ID, mime); @@ -1575,23 +1995,48 @@ public class BluetoothMapContentTest { @Test public void extractMmsAddresses_withTypeMmsBcc() { - MatrixCursor addressCursor = new MatrixCursor(new String[] {Telephony.Mms.Addr.ADDRESS, - Telephony.Mms.Addr.TYPE}); + MatrixCursor addressCursor = + new MatrixCursor( + new String[] {Telephony.Mms.Addr.ADDRESS, Telephony.Mms.Addr.TYPE}); addressCursor.addRow(new Object[] {TEST_ADDRESS, BluetoothMapContent.MMS_BCC}); - doReturn(addressCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), any(), any()); - - MatrixCursor contactCursor = new MatrixCursor(new String[] {ContactsContract.Contacts._ID, - ContactsContract.Contacts.DISPLAY_NAME}); + doReturn(addressCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(Telephony.Mms.Addr.MSG_ID + "=" + TEST_ID), + any(), + any()); + + MatrixCursor contactCursor = + new MatrixCursor( + new String[] { + ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME + }); contactCursor.addRow(new Object[] {TEST_ID_STRING, TEST_NAME}); - doReturn(contactCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), any(), any()); - - MatrixCursor emailCursor = new MatrixCursor( - new String[]{ContactsContract.CommonDataKinds.Email.ADDRESS}); + doReturn(contactCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"), + any(), + any()); + + MatrixCursor emailCursor = + new MatrixCursor(new String[] {ContactsContract.CommonDataKinds.Email.ADDRESS}); emailCursor.addRow(new Object[] {TEST_EMAIL}); - doReturn(emailCursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), - eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), any(), any()); + doReturn(emailCursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + any(), + any(), + eq(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"), + any(), + any()); BluetoothMapbMessageMime mime = new BluetoothMapbMessageMime(); mContent.extractMmsAddresses(TEST_ID, mime); @@ -1603,21 +2048,45 @@ public class BluetoothMapContentTest { @Test public void extractMmsParts() { - MatrixCursor cursor = new MatrixCursor( - new String[] {BaseColumns._ID, Telephony.Mms.Part.CONTENT_TYPE, - Telephony.Mms.Part.NAME, Telephony.Mms.Part.CHARSET, - Telephony.Mms.Part.FILENAME, Telephony.Mms.Part.TEXT, - Telephony.Mms.Part._DATA, Telephony.Mms.Part.CONTENT_ID, - Telephony.Mms.Part.CONTENT_LOCATION, - Telephony.Mms.Part.CONTENT_DISPOSITION}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), - eq(Uri.parse(Telephony.Mms.CONTENT_URI + "/" + TEST_ID + "/part")), any(), - eq(Telephony.Mms.Part.MSG_ID + "=" + TEST_ID), any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BaseColumns._ID, + Telephony.Mms.Part.CONTENT_TYPE, + Telephony.Mms.Part.NAME, + Telephony.Mms.Part.CHARSET, + Telephony.Mms.Part.FILENAME, + Telephony.Mms.Part.TEXT, + Telephony.Mms.Part._DATA, + Telephony.Mms.Part.CONTENT_ID, + Telephony.Mms.Part.CONTENT_LOCATION, + Telephony.Mms.Part.CONTENT_DISPOSITION + }); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery( + any(), + eq(Uri.parse(Telephony.Mms.CONTENT_URI + "/" + TEST_ID + "/part")), + any(), + eq(Telephony.Mms.Part.MSG_ID + "=" + TEST_ID), + any(), + any()); String filename = "test_filename"; String location = "test_content_location"; String disposition = "test_content_disposition"; - cursor.addRow(new Object[] {TEST_ID, TEST_ATTACHMENT_MIME_TYPE, TEST_NAME, "test_charset", - filename, TEST_TEXT, 1, TEST_ID_STRING, location, disposition}); + cursor.addRow( + new Object[] { + TEST_ID, + TEST_ATTACHMENT_MIME_TYPE, + TEST_NAME, + "test_charset", + filename, + TEST_TEXT, + 1, + TEST_ID_STRING, + location, + disposition + }); BluetoothMapbMessageMime mime = new BluetoothMapbMessageMime(); mime.setIncludeAttachments(false); @@ -1632,4 +2101,4 @@ public class BluetoothMapContentTest { assertThat(part.mCharsetName).isEqualTo("utf-8"); assertThat(part.mFileName).isEqualTo(filename); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java index 68d0e0d92e8..229a3a5643a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java @@ -56,23 +56,29 @@ public class BluetoothMapConvoContactElementTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private MapContact mMapContact; + @Mock private MapContact mMapContact; @Test public void constructorWithArguments() { BluetoothMapConvoContactElement contactElement = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); assertThat(contactElement.getContactId()).isEqualTo(TEST_UCI); assertThat(contactElement.getName()).isEqualTo(TEST_NAME); assertThat(contactElement.getDisplayName()).isEqualTo(TEST_DISPLAY_NAME); assertThat(contactElement.getPresenceStatus()).isEqualTo(TEST_PRESENCE_STATUS); assertThat(contactElement.getPresenceAvailability()).isEqualTo(TEST_PRESENCE_AVAILABILITY); - assertThat(contactElement.getLastActivityString()).isEqualTo( - format.format(TEST_LAST_ACTIVITY)); + assertThat(contactElement.getLastActivityString()) + .isEqualTo(format.format(TEST_LAST_ACTIVITY)); assertThat(contactElement.getChatState()).isEqualTo(TEST_CHAT_STATE); assertThat(contactElement.getPriority()).isEqualTo(TEST_PRIORITY); assertThat(contactElement.getBtUid()).isEqualTo(TEST_BT_UID); @@ -109,8 +115,8 @@ public class BluetoothMapConvoContactElementTest { assertThat(contactElement.getDisplayName()).isEqualTo(TEST_DISPLAY_NAME); assertThat(contactElement.getPresenceStatus()).isEqualTo(TEST_PRESENCE_STATUS); assertThat(contactElement.getPresenceAvailability()).isEqualTo(TEST_PRESENCE_AVAILABILITY); - assertThat(contactElement.getLastActivityString()).isEqualTo( - format.format(TEST_LAST_ACTIVITY)); + assertThat(contactElement.getLastActivityString()) + .isEqualTo(format.format(TEST_LAST_ACTIVITY)); assertThat(contactElement.getChatState()).isEqualTo(TEST_CHAT_STATE); assertThat(contactElement.getPriority()).isEqualTo(TEST_PRIORITY); assertThat(contactElement.getBtUid()).isEqualTo(TEST_BT_UID); @@ -118,10 +124,17 @@ public class BluetoothMapConvoContactElementTest { @Test public void encodeToXml_thenDecodeToInstance_returnsCorrectly() throws Exception { - BluetoothMapConvoContactElement contactElement = new - BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + BluetoothMapConvoContactElement contactElement = + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); final XmlSerializer serializer = Xml.newSerializer(); final StringWriter writer = new StringWriter(); @@ -146,10 +159,10 @@ public class BluetoothMapConvoContactElementTest { assertThat(contactElementFromXml.getName()).isEqualTo(TEST_NAME); assertThat(contactElementFromXml.getDisplayName()).isEqualTo(TEST_DISPLAY_NAME); assertThat(contactElementFromXml.getPresenceStatus()).isEqualTo(TEST_PRESENCE_STATUS); - assertThat(contactElementFromXml.getPresenceAvailability()).isEqualTo( - TEST_PRESENCE_AVAILABILITY); - assertThat(contactElementFromXml.getLastActivityString()).isEqualTo( - format.format(TEST_LAST_ACTIVITY)); + assertThat(contactElementFromXml.getPresenceAvailability()) + .isEqualTo(TEST_PRESENCE_AVAILABILITY); + assertThat(contactElementFromXml.getLastActivityString()) + .isEqualTo(format.format(TEST_LAST_ACTIVITY)); assertThat(contactElementFromXml.getChatState()).isEqualTo(TEST_CHAT_STATE); assertThat(contactElementFromXml.getPriority()).isEqualTo(TEST_PRIORITY); assertThat(contactElementFromXml.getBtUid()).isEqualTo(TEST_BT_UID); @@ -158,14 +171,28 @@ public class BluetoothMapConvoContactElementTest { @Test public void equalsWithSameValues_returnsTrue() { BluetoothMapConvoContactElement contactElement = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); BluetoothMapConvoContactElement contactElementEqual = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); assertThat(contactElement).isEqualTo(contactElementEqual); } @@ -173,14 +200,28 @@ public class BluetoothMapConvoContactElementTest { @Test public void equalsWithDifferentPriority_returnsFalse() { BluetoothMapConvoContactElement contactElement = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); BluetoothMapConvoContactElement contactElementWithDifferentPriority = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, /*priority=*/0, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + /* priority= */ 0, + TEST_BT_UID); assertThat(contactElement).isNotEqualTo(contactElementWithDifferentPriority); } @@ -188,14 +229,28 @@ public class BluetoothMapConvoContactElementTest { @Test public void compareTo_withSameValues_returnsZero() { BluetoothMapConvoContactElement contactElement = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); BluetoothMapConvoContactElement contactElementSameLastActivity = - new BluetoothMapConvoContactElement(TEST_UCI, TEST_NAME, TEST_DISPLAY_NAME, - TEST_PRESENCE_STATUS, TEST_PRESENCE_AVAILABILITY, TEST_LAST_ACTIVITY, - TEST_CHAT_STATE, TEST_PRIORITY, TEST_BT_UID); + new BluetoothMapConvoContactElement( + TEST_UCI, + TEST_NAME, + TEST_DISPLAY_NAME, + TEST_PRESENCE_STATUS, + TEST_PRESENCE_AVAILABILITY, + TEST_LAST_ACTIVITY, + TEST_CHAT_STATE, + TEST_PRIORITY, + TEST_BT_UID); assertThat(contactElement.compareTo(contactElementSameLastActivity)).isEqualTo(0); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java index 9e971a5ba6e..87739756e67 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java @@ -52,17 +52,31 @@ public class BluetoothMapConvoListingElementTest { private static final String TEST_SMS_MMS_CONTACTS = "test_sms_mms_contacts"; private final BluetoothMapConvoContactElement TEST_CONTACT_ELEMENT_ONE = - new BluetoothMapConvoContactElement("test_uci_one", "test_name_one", - "test_display_name_one", "test_presence_status_one", 2, TEST_LAST_ACTIVITY, 2, - 1, "1111"); + new BluetoothMapConvoContactElement( + "test_uci_one", + "test_name_one", + "test_display_name_one", + "test_presence_status_one", + 2, + TEST_LAST_ACTIVITY, + 2, + 1, + "1111"); private final BluetoothMapConvoContactElement TEST_CONTACT_ELEMENT_TWO = - new BluetoothMapConvoContactElement("test_uci_two", "test_name_two", - "test_display_name_two", "test_presence_status_two", 1, TEST_LAST_ACTIVITY, 1, - 2, "1112"); - - private final List TEST_CONTACTS = new ArrayList<>( - Arrays.asList(TEST_CONTACT_ELEMENT_ONE, TEST_CONTACT_ELEMENT_TWO)); + new BluetoothMapConvoContactElement( + "test_uci_two", + "test_name_two", + "test_display_name_two", + "test_presence_status_two", + 1, + TEST_LAST_ACTIVITY, + 1, + 2, + "1112"); + + private final List TEST_CONTACTS = + new ArrayList<>(Arrays.asList(TEST_CONTACT_ELEMENT_ONE, TEST_CONTACT_ELEMENT_TWO)); private final SignedLongLong signedLongLong = new SignedLongLong(TEST_ID, 0); @@ -95,8 +109,8 @@ public class BluetoothMapConvoListingElementTest { assertThat(mListingElement.getRead()).isEqualTo("READ"); assertThat(mListingElement.getReadBool()).isEqualTo(TEST_READ); assertThat(mListingElement.getConvoId()).isEqualTo(signedLongLong.toHexString()); - assertThat(mListingElement.getCpConvoId()).isEqualTo( - signedLongLong.getLeastSignificantBits()); + assertThat(mListingElement.getCpConvoId()) + .isEqualTo(signedLongLong.getLeastSignificantBits()); assertThat(mListingElement.getFullSummary()).isEqualTo(TEST_SUMMARY); assertThat(mListingElement.getSmsMmsContacts()).isEqualTo(TEST_SMS_MMS_CONTACTS); } @@ -168,8 +182,7 @@ public class BluetoothMapConvoListingElementTest { @Test public void equalsWithDifferentRead_returnsFalse() { - BluetoothMapConvoListingElement - listingElement = new BluetoothMapConvoListingElement(); + BluetoothMapConvoListingElement listingElement = new BluetoothMapConvoListingElement(); BluetoothMapConvoListingElement listingElementWithDifferentRead = new BluetoothMapConvoListingElement(); @@ -180,8 +193,7 @@ public class BluetoothMapConvoListingElementTest { @Test public void compareToWithSameValues_returnsZero() { - BluetoothMapConvoListingElement - listingElement = new BluetoothMapConvoListingElement(); + BluetoothMapConvoListingElement listingElement = new BluetoothMapConvoListingElement(); listingElement.setLastActivity(TEST_LAST_ACTIVITY); BluetoothMapConvoListingElement listingElementSameLastActivity = @@ -190,4 +202,4 @@ public class BluetoothMapConvoListingElementTest { assertThat(listingElement.compareTo(listingElementSameLastActivity)).isEqualTo(0); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java index 432506b35c9..f2ae388baf8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java @@ -91,8 +91,8 @@ public class BluetoothMapConvoListingTest { public void sort() { // BluetoothMapConvoListingElements are sorted according to their mLastActivity values mListing.sort(); - assertThat(mListing.getList().get(0).getLastActivity()).isEqualTo( - TEST_LAST_ACTIVITY_LATEST); + assertThat(mListing.getList().get(0).getLastActivity()) + .isEqualTo(TEST_LAST_ACTIVITY_LATEST); } @Test @@ -171,9 +171,9 @@ public class BluetoothMapConvoListingTest { BluetoothMapConvoListing listing = new BluetoothMapConvoListing(); listing.appendFromXml(listingStream); assertThat(listing.getList().size()).isEqualTo(2); - assertThat(listing.getList().get(0).getConvoId()).isEqualTo( - signedLongLongIdOne.toHexString()); - assertThat(listing.getList().get(1).getConvoId()).isEqualTo( - signedLongLongIdTwo.toHexString()); + assertThat(listing.getList().get(0).getConvoId()) + .isEqualTo(signedLongLongIdOne.toHexString()); + assertThat(listing.getList().get(1).getConvoId()) + .isEqualTo(signedLongLongIdTwo.toHexString()); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapFolderElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapFolderElementTest.java index d6f7ff9d8b2..0ba98aef33d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapFolderElementTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapFolderElementTest.java @@ -55,7 +55,6 @@ public class BluetoothMapFolderElementTest { private BluetoothMapFolderElement mParentFolderElement; private BluetoothMapFolderElement mTestFolderElement; - @Before public void setUp() throws Exception { mRootFolderElement.setFolderId(TEST_ROOT_FOLDER_ID); @@ -73,7 +72,6 @@ public class BluetoothMapFolderElementTest { mTestFolderElement.setHasImContent(TEST_HAS_IM_CONTENT); } - @Test public void getters() { assertThat(mTestFolderElement.shouldIgnore()).isEqualTo(TEST_IGNORE); @@ -85,8 +83,8 @@ public class BluetoothMapFolderElementTest { @Test public void getFullPath() { - assertThat(mTestFolderElement.getFullPath()).isEqualTo( - String.format("%s/%s", TEST_PARENT_FOLDER_NAME, TEST_FOLDER_NAME)); + assertThat(mTestFolderElement.getFullPath()) + .isEqualTo(String.format("%s/%s", TEST_PARENT_FOLDER_NAME, TEST_FOLDER_NAME)); } @Test @@ -100,12 +98,12 @@ public class BluetoothMapFolderElementTest { mTestFolderElement.addImFolder(TEST_IM_FOLDER_NAME, TEST_IM_FOLDER_ID); mTestFolderElement.addEmailFolder(TEST_EMAIL_FOLDER_NAME, TEST_EMAIL_FOLDER_ID); - assertThat(mTestFolderElement.getSubFolder(TEST_SMS_MMS_FOLDER_NAME).getName()).isEqualTo( - TEST_SMS_MMS_FOLDER_NAME); - assertThat(mTestFolderElement.getSubFolder(TEST_IM_FOLDER_NAME).getName()).isEqualTo( - TEST_IM_FOLDER_NAME); - assertThat(mTestFolderElement.getSubFolder(TEST_EMAIL_FOLDER_NAME).getName()).isEqualTo( - TEST_EMAIL_FOLDER_NAME); + assertThat(mTestFolderElement.getSubFolder(TEST_SMS_MMS_FOLDER_NAME).getName()) + .isEqualTo(TEST_SMS_MMS_FOLDER_NAME); + assertThat(mTestFolderElement.getSubFolder(TEST_IM_FOLDER_NAME).getName()) + .isEqualTo(TEST_IM_FOLDER_NAME); + assertThat(mTestFolderElement.getSubFolder(TEST_EMAIL_FOLDER_NAME).getName()) + .isEqualTo(TEST_EMAIL_FOLDER_NAME); mTestFolderElement.addFolder(TEST_SMS_MMS_FOLDER_NAME); assertThat(mTestFolderElement.getSubFolderCount()).isEqualTo(3); @@ -114,24 +112,26 @@ public class BluetoothMapFolderElementTest { @Test public void getFolderById() { assertThat(mTestFolderElement.getFolderById(TEST_FOLDER_ID)).isEqualTo(mTestFolderElement); - assertThat(mRootFolderElement.getFolderById(TEST_ROOT_FOLDER_ID)).isEqualTo( - mRootFolderElement); + assertThat(mRootFolderElement.getFolderById(TEST_ROOT_FOLDER_ID)) + .isEqualTo(mRootFolderElement); assertThat(BluetoothMapFolderElement.getFolderById(TEST_FOLDER_ID, null)).isNull(); - assertThat(BluetoothMapFolderElement.getFolderById(TEST_PLACEHOLDER_ID, - mTestFolderElement)).isNull(); + assertThat(BluetoothMapFolderElement.getFolderById(TEST_PLACEHOLDER_ID, mTestFolderElement)) + .isNull(); } @Test public void getFolderByName() { mRootFolderElement.addFolder(TEST_TELECOM_FOLDER_NAME); mRootFolderElement.getSubFolder(TEST_TELECOM_FOLDER_NAME).addFolder(TEST_MSG_FOLDER_NAME); - BluetoothMapFolderElement placeholderFolderElement = mRootFolderElement.getSubFolder( - TEST_TELECOM_FOLDER_NAME).getSubFolder(TEST_MSG_FOLDER_NAME).addFolder( - TEST_PLACEHOLDER_FOLDER_NAME); + BluetoothMapFolderElement placeholderFolderElement = + mRootFolderElement + .getSubFolder(TEST_TELECOM_FOLDER_NAME) + .getSubFolder(TEST_MSG_FOLDER_NAME) + .addFolder(TEST_PLACEHOLDER_FOLDER_NAME); assertThat(mRootFolderElement.getFolderByName(TEST_PLACEHOLDER_FOLDER_NAME)).isNull(); placeholderFolderElement.setFolderId(TEST_PLACEHOLDER_ID); - assertThat(mRootFolderElement.getFolderByName(TEST_PLACEHOLDER_FOLDER_NAME)).isEqualTo( - placeholderFolderElement); + assertThat(mRootFolderElement.getFolderByName(TEST_PLACEHOLDER_FOLDER_NAME)) + .isEqualTo(placeholderFolderElement); } @Test @@ -161,11 +161,10 @@ public class BluetoothMapFolderElementTest { mTestFolderElement.addSmsMmsFolder(TEST_SMS_MMS_FOLDER_NAME); folderElementWithDifferentSubFoldersSize.addSmsMmsFolder(TEST_SMS_MMS_FOLDER_NAME); - folderElementWithDifferentSubFoldersSize.addImFolder(TEST_IM_FOLDER_NAME, - TEST_IM_FOLDER_ID); - assertThat( - mTestFolderElement.compareTo(folderElementWithDifferentSubFoldersSize)).isEqualTo( - -1); + folderElementWithDifferentSubFoldersSize.addImFolder( + TEST_IM_FOLDER_NAME, TEST_IM_FOLDER_ID); + assertThat(mTestFolderElement.compareTo(folderElementWithDifferentSubFoldersSize)) + .isEqualTo(-1); } @Test @@ -175,10 +174,10 @@ public class BluetoothMapFolderElementTest { mTestFolderElement.addSmsMmsFolder(TEST_SMS_MMS_FOLDER_NAME); folderElementWithDifferentSubFoldersTree.addSmsMmsFolder(TEST_SMS_MMS_FOLDER_NAME); - folderElementWithDifferentSubFoldersTree.getSubFolder(TEST_SMS_MMS_FOLDER_NAME).addFolder( - TEST_PLACEHOLDER_FOLDER_NAME); - assertThat( - mTestFolderElement.compareTo(folderElementWithDifferentSubFoldersTree)).isEqualTo( - -1); + folderElementWithDifferentSubFoldersTree + .getSubFolder(TEST_SMS_MMS_FOLDER_NAME) + .addFolder(TEST_PLACEHOLDER_FOLDER_NAME); + assertThat(mTestFolderElement.compareTo(folderElementWithDifferentSubFoldersTree)) + .isEqualTo(-1); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java index b985cd3a4a3..19dda41311a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java @@ -51,25 +51,37 @@ public class BluetoothMapMasInstanceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private Context mContext; - @Mock - private BluetoothMapService mMapService; + @Mock private Context mContext; + @Mock private BluetoothMapService mMapService; @Before public void setUp() { - mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, - TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); + mAccountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); } @Test public void toString_returnsInfo() { - BluetoothMapMasInstance instance = new BluetoothMapMasInstance(mMapService, mContext, - mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); + BluetoothMapMasInstance instance = + new BluetoothMapMasInstance( + mMapService, mContext, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); - String expected = "MasId: " + TEST_MAS_ID + " Uri:" + mAccountItem.mBase_uri + " SMS/MMS:" - + TEST_ENABLE_SMS_MMS; + String expected = + "MasId: " + + TEST_MAS_ID + + " Uri:" + + mAccountItem.mBase_uri + + " SMS/MMS:" + + TEST_ENABLE_SMS_MMS; assertThat(instance.toString()).isEqualTo(expected); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java index 77cb343ca98..81fa5b5122a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java @@ -101,15 +101,15 @@ public class BluetoothMapMessageListingElementTest { assertThat(mMessageListingElement.getHandle()).isEqualTo(TEST_CP_HANDLE); assertThat(mMessageListingElement.getSubject()).isEqualTo(TEST_SUBJECT); assertThat(mMessageListingElement.getDateTime()).isEqualTo(TEST_DATE_TIME); - assertThat(mMessageListingElement.getDateTimeString()).isEqualTo( - format.format(TEST_DATE_TIME)); + assertThat(mMessageListingElement.getDateTimeString()) + .isEqualTo(format.format(TEST_DATE_TIME)); assertThat(mMessageListingElement.getSenderName()).isEqualTo(TEST_SENDER_NAME); assertThat(mMessageListingElement.getSenderAddressing()).isEqualTo(TEST_SENDER_ADDRESSING); - assertThat(mMessageListingElement.getReplyToAddressing()).isEqualTo( - TEST_REPLY_TO_ADDRESSING); + assertThat(mMessageListingElement.getReplyToAddressing()) + .isEqualTo(TEST_REPLY_TO_ADDRESSING); assertThat(mMessageListingElement.getRecipientName()).isEqualTo(TEST_RECIPIENT_NAME); - assertThat(mMessageListingElement.getRecipientAddressing()).isEqualTo( - TEST_RECIPIENT_ADDRESSING); + assertThat(mMessageListingElement.getRecipientAddressing()) + .isEqualTo(TEST_RECIPIENT_ADDRESSING); assertThat(mMessageListingElement.getType()).isEqualTo(TEST_TYPE); assertThat(mMessageListingElement.getSize()).isEqualTo(TEST_SIZE); assertThat(mMessageListingElement.getText()).isEqualTo(TEST_TEXT); @@ -123,8 +123,8 @@ public class BluetoothMapMessageListingElementTest { assertThat(mMessageListingElement.getProtect()).isEqualTo(TEST_PROTECT); assertThat(mMessageListingElement.getFolderType()).isEqualTo(TEST_FOLDER_TYPE); assertThat(mMessageListingElement.getThreadName()).isEqualTo(TEST_THREAD_NAME); - assertThat(mMessageListingElement.getAttachmentMimeTypes()).isEqualTo( - TEST_ATTACHMENT_MIME_TYPES); + assertThat(mMessageListingElement.getAttachmentMimeTypes()) + .isEqualTo(TEST_ATTACHMENT_MIME_TYPES); assertThat(mMessageListingElement.getCursorIndex()).isEqualTo(TEST_CURSOR_INDEX); } @@ -155,14 +155,14 @@ public class BluetoothMapMessageListingElementTest { String attributeName = parser.getAttributeName(i).trim(); String attributeValue = parser.getAttributeValue(i); if (attributeName.equalsIgnoreCase("handle")) { - assertThat(attributeValue).isEqualTo( - BluetoothMapUtils.getMapHandle(TEST_CP_HANDLE, TEST_TYPE)); + assertThat(attributeValue) + .isEqualTo(BluetoothMapUtils.getMapHandle(TEST_CP_HANDLE, TEST_TYPE)); } else if (attributeName.equalsIgnoreCase("datetime")) { - assertThat(attributeValue).isEqualTo( - BluetoothMapUtils.getDateTimeString(TEST_DATE_TIME)); + assertThat(attributeValue) + .isEqualTo(BluetoothMapUtils.getDateTimeString(TEST_DATE_TIME)); } else if (attributeName.equalsIgnoreCase("sender_name")) { - assertThat(attributeValue).isEqualTo( - BluetoothMapUtils.stripInvalidChars(TEST_SENDER_NAME)); + assertThat(attributeValue) + .isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_SENDER_NAME)); } else if (attributeName.equalsIgnoreCase("sender_addressing")) { assertThat(attributeValue).isEqualTo(TEST_SENDER_ADDRESSING); } else if (attributeName.equalsIgnoreCase("replyto_addressing")) { @@ -194,8 +194,8 @@ public class BluetoothMapMessageListingElementTest { } else if (attributeName.equalsIgnoreCase("protected")) { assertThat(attributeValue).isEqualTo(TEST_PROTECT); } else if (attributeName.equalsIgnoreCase("conversation_id")) { - assertThat(attributeValue).isEqualTo( - BluetoothMapUtils.getMapConvoHandle(TEST_THREAD_ID, TEST_TYPE)); + assertThat(attributeValue) + .isEqualTo(BluetoothMapUtils.getMapConvoHandle(TEST_THREAD_ID, TEST_TYPE)); } else if (attributeName.equalsIgnoreCase("conversation_name")) { assertThat(attributeValue).isEqualTo(TEST_THREAD_NAME); } else if (attributeName.equalsIgnoreCase("folder_type")) { @@ -229,4 +229,4 @@ public class BluetoothMapMessageListingElementTest { elementWithEqualDateTime.setDateTime(TEST_DATE_TIME); assertThat(mMessageListingElement.compareTo(elementWithEqualDateTime)).isEqualTo(0); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java index 51fdb486dd2..7b1a121d2e9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java @@ -126,8 +126,8 @@ public class BluetoothMapMessageListingTest { assertThat(listingToAppend.getList().size()).isEqualTo(2); - final InputStream listingStream = new ByteArrayInputStream( - listingToAppend.encode(false, TEST_VERSION)); + final InputStream listingStream = + new ByteArrayInputStream(listingToAppend.encode(false, TEST_VERSION)); BluetoothMapMessageListing listing = new BluetoothMapMessageListing(); appendFromXml(listingStream, listing); @@ -188,8 +188,10 @@ public class BluetoothMapMessageListingTest { String attributeName = parser.getAttributeName(i).trim(); String attributeValue = parser.getAttributeValue(i); if (attributeName.equalsIgnoreCase("datetime")) { - newElement.setDateTime(LocalDateTime.parse(attributeValue, formatter).toInstant( - ZoneOffset.ofTotalSeconds(0)).toEpochMilli()); + newElement.setDateTime( + LocalDateTime.parse(attributeValue, formatter) + .toInstant(ZoneOffset.ofTotalSeconds(0)) + .toEpochMilli()); } else if (attributeName.equalsIgnoreCase("read")) { newElement.setRead(true, true); } @@ -197,4 +199,4 @@ public class BluetoothMapMessageListingTest { parser.nextTag(); return newElement; } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java index 40503a775f4..19dae89d5d0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java @@ -71,57 +71,76 @@ public class BluetoothMapObexServerTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private Context mContext; - @Mock - private BluetoothMapService mMapService; - @Mock - private ContentProviderClient mProviderClient; - @Mock - private BluetoothMapContentObserver mObserver; - @Spy - private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); + @Mock private Context mContext; + @Mock private BluetoothMapService mMapService; + @Mock private ContentProviderClient mProviderClient; + @Mock private BluetoothMapContentObserver mObserver; + @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); @Before public void setUp() throws Exception { BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy); - doReturn(mProviderClient).when( - mMapMethodProxy).contentResolverAcquireUnstableContentProviderClient(any(), any()); - mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, - TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); - mMasInstance = new BluetoothMapMasInstance(mMapService, mContext, - mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); + doReturn(mProviderClient) + .when(mMapMethodProxy) + .contentResolverAcquireUnstableContentProviderClient(any(), any()); + mAccountItem = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + TEST_TYPE, + TEST_UCI, + TEST_UCI_PREFIX); + mMasInstance = + new BluetoothMapMasInstance( + mMapService, mContext, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); mParams = new BluetoothMapAppParams(); - mObexServer = new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance, - mAccountItem, TEST_ENABLE_SMS_MMS); + mObexServer = + new BluetoothMapObexServer( + null, mContext, mObserver, mMasInstance, mAccountItem, TEST_ENABLE_SMS_MMS); } @Test public void setOwnerStatus_withAccountTypeEmail() throws Exception { doReturn(null).when(mProviderClient).query(any(), any(), any(), any(), any()); - BluetoothMapAccountItem accountItemWithTypeEmail = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - BluetoothMapUtils.TYPE.EMAIL, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver, - mMasInstance, accountItemWithTypeEmail, TEST_ENABLE_SMS_MMS); - - assertThat(obexServer.setOwnerStatus(mParams)).isEqualTo( - ResponseCodes.OBEX_HTTP_UNAVAILABLE); + BluetoothMapAccountItem accountItemWithTypeEmail = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + BluetoothMapUtils.TYPE.EMAIL, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapObexServer obexServer = + new BluetoothMapObexServer( + null, + mContext, + mObserver, + mMasInstance, + accountItemWithTypeEmail, + TEST_ENABLE_SMS_MMS); + + assertThat(obexServer.setOwnerStatus(mParams)) + .isEqualTo(ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withAppParamsInvalid() throws Exception { BluetoothMapAppParams params = mock(BluetoothMapAppParams.class); - when(params.getPresenceAvailability()).thenReturn( - BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(params.getPresenceAvailability()) + .thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getPresenceStatus()).thenReturn(null); - when(params.getLastActivity()).thenReturn( - (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); + when(params.getLastActivity()) + .thenReturn((long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getChatState()).thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getChatStateConvoIdString()).thenReturn(null); - assertThat(mObexServer.setOwnerStatus(params)).isEqualTo( - ResponseCodes.OBEX_HTTP_PRECON_FAILED); + assertThat(mObexServer.setOwnerStatus(params)) + .isEqualTo(ResponseCodes.OBEX_HTTP_PRECON_FAILED); } @Test @@ -130,8 +149,7 @@ public class BluetoothMapObexServerTest { Bundle bundle = new Bundle(); when(mProviderClient.call(any(), any(), any())).thenReturn(bundle); - assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( - ResponseCodes.OBEX_HTTP_OK); + assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo(ResponseCodes.OBEX_HTTP_OK); } @Test @@ -139,8 +157,8 @@ public class BluetoothMapObexServerTest { setUpBluetoothMapAppParams(mParams); when(mProviderClient.call(any(), any(), any())).thenReturn(null); - assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( - ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED); + assertThat(mObexServer.setOwnerStatus(mParams)) + .isEqualTo(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED); } @Test @@ -148,8 +166,8 @@ public class BluetoothMapObexServerTest { setUpBluetoothMapAppParams(mParams); doThrow(RemoteException.class).when(mProviderClient).call(any(), any(), any()); - assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( - ResponseCodes.OBEX_HTTP_UNAVAILABLE); + assertThat(mObexServer.setOwnerStatus(mParams)) + .isEqualTo(ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test @@ -157,8 +175,8 @@ public class BluetoothMapObexServerTest { setUpBluetoothMapAppParams(mParams); doThrow(NullPointerException.class).when(mProviderClient).call(any(), any(), any()); - assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( - ResponseCodes.OBEX_HTTP_UNAVAILABLE); + assertThat(mObexServer.setOwnerStatus(mParams)) + .isEqualTo(ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test @@ -166,23 +184,32 @@ public class BluetoothMapObexServerTest { setUpBluetoothMapAppParams(mParams); doThrow(IllegalArgumentException.class).when(mProviderClient).call(any(), any(), any()); - assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( - ResponseCodes.OBEX_HTTP_UNAVAILABLE); + assertThat(mObexServer.setOwnerStatus(mParams)) + .isEqualTo(ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void addEmailFolders() throws Exception { - MatrixCursor cursor = new MatrixCursor(new String[]{BluetoothMapContract.FolderColumns.NAME, - BluetoothMapContract.FolderColumns._ID}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.FolderColumns.NAME, + BluetoothMapContract.FolderColumns._ID + }); long parentId = 1; long childId = 2; - cursor.addRow(new Object[]{"test_name", childId}); + cursor.addRow(new Object[] {"test_name", childId}); cursor.moveToFirst(); BluetoothMapFolderElement parentFolder = new BluetoothMapFolderElement("parent", null); parentFolder.setFolderId(parentId); - doReturn(cursor).when(mProviderClient).query(any(), any(), - eq(BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + " = " + parentId), any(), - any()); + doReturn(cursor) + .when(mProviderClient) + .query( + any(), + any(), + eq(BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + " = " + parentId), + any(), + any()); mObexServer.addEmailFolders(parentFolder); @@ -191,8 +218,8 @@ public class BluetoothMapObexServerTest { @Test public void setMsgTypeFilterParams_withAccountNull_andOverwriteTrue() throws Exception { - BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver, - mMasInstance, null, false); + BluetoothMapObexServer obexServer = + new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance, null, false); obexServer.setMsgTypeFilterParams(mParams, true); @@ -207,24 +234,51 @@ public class BluetoothMapObexServerTest { @Test public void setMsgTypeFilterParams_withInvalidFilterMessageType() throws Exception { - BluetoothMapAccountItem accountItemWithTypeEmail = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - BluetoothMapUtils.TYPE.EMAIL, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver, - mMasInstance, accountItemWithTypeEmail, TEST_ENABLE_SMS_MMS); + BluetoothMapAccountItem accountItemWithTypeEmail = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + BluetoothMapUtils.TYPE.EMAIL, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapObexServer obexServer = + new BluetoothMapObexServer( + null, + mContext, + mObserver, + mMasInstance, + accountItemWithTypeEmail, + TEST_ENABLE_SMS_MMS); // Passing mParams without any previous settings pass invalid filter message type - assertThrows(IllegalArgumentException.class, + assertThrows( + IllegalArgumentException.class, () -> obexServer.setMsgTypeFilterParams(mParams, false)); } @Test public void setMsgTypeFilterParams_withValidFilterMessageType() throws Exception { - BluetoothMapAccountItem accountItemWithTypeIm = BluetoothMapAccountItem.create(TEST_ID, - TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, - BluetoothMapUtils.TYPE.IM, TEST_UCI, TEST_UCI_PREFIX); - BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver, - mMasInstance, accountItemWithTypeIm, TEST_ENABLE_SMS_MMS); + BluetoothMapAccountItem accountItemWithTypeIm = + BluetoothMapAccountItem.create( + TEST_ID, + TEST_NAME, + TEST_PACKAGE_NAME, + TEST_PROVIDER_AUTHORITY, + TEST_DRAWABLE, + BluetoothMapUtils.TYPE.IM, + TEST_UCI, + TEST_UCI_PREFIX); + BluetoothMapObexServer obexServer = + new BluetoothMapObexServer( + null, + mContext, + mObserver, + mMasInstance, + accountItemWithTypeIm, + TEST_ENABLE_SMS_MMS); int expectedMask = 1; mParams.setFilterMessageType(expectedMask); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java index 64408e89f95..55dbf1a9bf0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java @@ -40,8 +40,7 @@ public class BluetoothMapServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private BluetoothMapService mService; + @Mock private BluetoothMapService mService; BluetoothDevice mRemoteDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java index 009d79d494a..a78264d67c5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java @@ -100,8 +100,10 @@ public class BluetoothMapServiceTest { public void getDevicesMatchingConnectionStates_whenNoDeviceIsConnected_returnsEmptyList() { when(mAdapterService.getBondedDevices()).thenReturn(new BluetoothDevice[] {mRemoteDevice}); - assertThat(mService.getDevicesMatchingConnectionStates( - new int[] {BluetoothProfile.STATE_CONNECTED})).isEmpty(); + assertThat( + mService.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED})) + .isEmpty(); } @Test @@ -118,8 +120,8 @@ public class BluetoothMapServiceTest { mService.sendConnectCancelMessage(); - verify(handler, timeout(1_000)).messageArrived( - eq(MSG_MAS_CONNECT_CANCEL), anyInt(), anyInt(), any()); + verify(handler, timeout(1_000)) + .messageArrived(eq(MSG_MAS_CONNECT_CANCEL), anyInt(), anyInt(), any()); } @Test @@ -129,8 +131,7 @@ public class BluetoothMapServiceTest { mService.sendConnectTimeoutMessage(); - verify(handler, timeout(1_000)).messageArrived( - eq(USER_TIMEOUT), anyInt(), anyInt(), any()); + verify(handler, timeout(1_000)).messageArrived(eq(USER_TIMEOUT), anyInt(), anyInt(), any()); } @Test @@ -141,8 +142,8 @@ public class BluetoothMapServiceTest { mService.updateMasInstances(action); - verify(handler, timeout(1_000)).messageArrived( - eq(UPDATE_MAS_INSTANCES), eq(action), anyInt(), any()); + verify(handler, timeout(1_000)) + .messageArrived(eq(UPDATE_MAS_INSTANCES), eq(action), anyInt(), any()); } public static class TestableHandler extends Handler { diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java index f57f1bd0b32..940b59f9a8b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java @@ -92,14 +92,17 @@ public class BluetoothMapSettingsTest { } private void enableActivity(boolean enable) { - int enabledState = enable ? COMPONENT_ENABLED_STATE_ENABLED - : COMPONENT_ENABLED_STATE_DEFAULT; + int enabledState = + enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT; - mTargetContext.getPackageManager().setApplicationEnabledSetting( - mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); + mTargetContext + .getPackageManager() + .setApplicationEnabledSetting( + mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); ComponentName activityName = new ComponentName(mTargetContext, BluetoothMapSettings.class); - mTargetContext.getPackageManager().setComponentEnabledSetting( - activityName, enabledState, DONT_KILL_APP); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java index ab6f9cf4694..c85bb8b5b70 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java @@ -61,22 +61,21 @@ public class BluetoothMapSmsPduTest { private SmsManager mSmsManager = SmsManager.getDefault(); @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private Context mTargetContext; - @Mock - private TelephonyManager mTelephonyManager; + @Mock private Context mTargetContext; + @Mock private TelephonyManager mTelephonyManager; @Before public void setUp() throws Exception { - when(mTargetContext.getSystemServiceName(TelephonyManager.class)).thenReturn( - "TELEPHONY_SERVICE"); + when(mTargetContext.getSystemServiceName(TelephonyManager.class)) + .thenReturn("TELEPHONY_SERVICE"); when(mTargetContext.getSystemService("TELEPHONY_SERVICE")).thenReturn(mTelephonyManager); int[] ted = SmsMessage.calculateLength((CharSequence) TEST_TEXT, false); TEST_ENCODING = ted[3]; TEST_LANGUAGE_TABLE = ted[4]; - TEST_DATA = SmsMessage.getSubmitPdu(null, TEST_DESTINATION_ADDRESS, TEST_TEXT, - false).encodedMessage; + TEST_DATA = + SmsMessage.getSubmitPdu(null, TEST_DESTINATION_ADDRESS, TEST_TEXT, false) + .encodedMessage; } @Test @@ -108,8 +107,9 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); - ArrayList pdus = BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, - TEST_TEXT_WITH_TWO_SMS_PARTS, null); + ArrayList pdus = + BluetoothMapSmsPdu.getSubmitPdus( + mTargetContext, TEST_TEXT_WITH_TWO_SMS_PARTS, null); assertThat(pdus.size()).isEqualTo(2); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_GSM); @@ -122,8 +122,8 @@ public class BluetoothMapSmsPduTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_NATIVE); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_NATIVE); assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageSms.class); BluetoothMapbMessageSms messageSmsParsed = (BluetoothMapbMessageSms) messageParsed; @@ -149,8 +149,8 @@ public class BluetoothMapSmsPduTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_NATIVE); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_NATIVE); assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageSms.class); } @@ -161,8 +161,9 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); - ArrayList pdus = BluetoothMapSmsPdu.getDeliverPdus(mTargetContext, TEST_TEXT, - TEST_DESTINATION_ADDRESS, TEST_DATE); + ArrayList pdus = + BluetoothMapSmsPdu.getDeliverPdus( + mTargetContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); assertThat(pdus.size()).isEqualTo(1); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_GSM); @@ -176,8 +177,11 @@ public class BluetoothMapSmsPduTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - assertThrows(IllegalArgumentException.class, () -> BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_NATIVE)); + assertThrows( + IllegalArgumentException.class, + () -> + BluetoothMapbMessage.parse( + inputStream, BluetoothMapAppParams.CHARSET_NATIVE)); } @Test @@ -186,8 +190,9 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA); - ArrayList pdus = BluetoothMapSmsPdu.getDeliverPdus(mTargetContext, TEST_TEXT, - TEST_DESTINATION_ADDRESS, TEST_DATE); + ArrayList pdus = + BluetoothMapSmsPdu.getDeliverPdus( + mTargetContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); assertThat(pdus.size()).isEqualTo(1); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_CDMA); @@ -201,50 +206,66 @@ public class BluetoothMapSmsPduTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - assertThrows(IllegalArgumentException.class, () -> BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_NATIVE)); + assertThrows( + IllegalArgumentException.class, + () -> + BluetoothMapbMessage.parse( + inputStream, BluetoothMapAppParams.CHARSET_NATIVE)); } @Test public void getEncodingString() { - SmsPdu smsPduGsm7bitWithLanguageTableZero = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_7BIT, - BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); + SmsPdu smsPduGsm7bitWithLanguageTableZero = + new SmsPdu(TEST_DATA, SmsMessage.ENCODING_7BIT, BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); assertThat(smsPduGsm7bitWithLanguageTableZero.getEncodingString()).isEqualTo("G-7BIT"); - SmsPdu smsPduGsm7bitWithLanguageTableOne = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_7BIT, - BluetoothMapSmsPdu.SMS_TYPE_GSM, 1); + SmsPdu smsPduGsm7bitWithLanguageTableOne = + new SmsPdu(TEST_DATA, SmsMessage.ENCODING_7BIT, BluetoothMapSmsPdu.SMS_TYPE_GSM, 1); assertThat(smsPduGsm7bitWithLanguageTableOne.getEncodingString()).isEqualTo("G-7BITEXT"); - SmsPdu smsPduGsm8bit = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_8BIT, - BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); + SmsPdu smsPduGsm8bit = + new SmsPdu(TEST_DATA, SmsMessage.ENCODING_8BIT, BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); assertThat(smsPduGsm8bit.getEncodingString()).isEqualTo("G-8BIT"); - SmsPdu smsPduGsm16bit = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_16BIT, - BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); + SmsPdu smsPduGsm16bit = + new SmsPdu( + TEST_DATA, SmsMessage.ENCODING_16BIT, BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); assertThat(smsPduGsm16bit.getEncodingString()).isEqualTo("G-16BIT"); - SmsPdu smsPduGsmUnknown = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_UNKNOWN, - BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); + SmsPdu smsPduGsmUnknown = + new SmsPdu( + TEST_DATA, SmsMessage.ENCODING_UNKNOWN, BluetoothMapSmsPdu.SMS_TYPE_GSM, 0); assertThat(smsPduGsmUnknown.getEncodingString()).isEqualTo(""); - SmsPdu smsPduCdma7bit = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_7BIT, - BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); + SmsPdu smsPduCdma7bit = + new SmsPdu( + TEST_DATA, SmsMessage.ENCODING_7BIT, BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); assertThat(smsPduCdma7bit.getEncodingString()).isEqualTo("C-7ASCII"); - SmsPdu smsPduCdma8bit = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_8BIT, - BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); + SmsPdu smsPduCdma8bit = + new SmsPdu( + TEST_DATA, SmsMessage.ENCODING_8BIT, BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); assertThat(smsPduCdma8bit.getEncodingString()).isEqualTo("C-8BIT"); - SmsPdu smsPduCdma16bit = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_16BIT, - BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); + SmsPdu smsPduCdma16bit = + new SmsPdu( + TEST_DATA, SmsMessage.ENCODING_16BIT, BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); assertThat(smsPduCdma16bit.getEncodingString()).isEqualTo("C-UNICODE"); - SmsPdu smsPduCdmaKsc5601 = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_KSC5601, - BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); + SmsPdu smsPduCdmaKsc5601 = + new SmsPdu( + TEST_DATA, + SmsMessage.ENCODING_KSC5601, + BluetoothMapSmsPdu.SMS_TYPE_CDMA, + 0); assertThat(smsPduCdmaKsc5601.getEncodingString()).isEqualTo("C-KOREAN"); - SmsPdu smsPduCdmaUnknown = new SmsPdu(TEST_DATA, SmsMessage.ENCODING_UNKNOWN, - BluetoothMapSmsPdu.SMS_TYPE_CDMA, 0); + SmsPdu smsPduCdmaUnknown = + new SmsPdu( + TEST_DATA, + SmsMessage.ENCODING_UNKNOWN, + BluetoothMapSmsPdu.SMS_TYPE_CDMA, + 0); assertThat(smsPduCdmaUnknown.getEncodingString()).isEqualTo(""); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java index cf1fb755775..7bc752db8ab 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java @@ -57,8 +57,9 @@ public class BluetoothMapUtilsTest { @Test public void printCursor_doesNotCrash() { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.PresenceColumns.LAST_ONLINE, "Name"}); + MatrixCursor cursor = + new MatrixCursor( + new String[] {BluetoothMapContract.PresenceColumns.LAST_ONLINE, "Name"}); cursor.addRow(new Object[] {345345226L, "test_name"}); cursor.moveToFirst(); @@ -67,8 +68,10 @@ public class BluetoothMapUtilsTest { @Test public void stripEncoding_quotedPrintable() { - assertThat(BluetoothMapUtils.stripEncoding("=?UTF-8?Q?" + QUOTED_PRINTABLE_ENCODED_TEXT - + "?=")).isEqualTo(TEXT); + assertThat( + BluetoothMapUtils.stripEncoding( + "=?UTF-8?Q?" + QUOTED_PRINTABLE_ENCODED_TEXT + "?=")) + .isEqualTo(TEXT); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java index e2a5cb4ffe6..2dab97af354 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java @@ -52,8 +52,8 @@ public class BluetoothMapbMessageEmailTest { byte[] encodedMessageEmail = messageEmailToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageEmail); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_UTF8); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_UTF8); assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageEmail.class); BluetoothMapbMessageEmail messageEmailParsed = (BluetoothMapbMessageEmail) messageParsed; assertThat(messageEmailParsed.getEmailBody()).isEqualTo(TEST_EMAIL_BODY); @@ -69,10 +69,10 @@ public class BluetoothMapbMessageEmailTest { byte[] encodedMessageEmail = messageEmailToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageEmail); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_UTF8); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_UTF8); assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageEmail.class); BluetoothMapbMessageEmail messageEmailParsed = (BluetoothMapbMessageEmail) messageParsed; assertThat(messageEmailParsed.getEmailBody()).isEqualTo(""); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageMimeTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageMimeTest.java index ac2d9804a6a..8e88a123ea3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageMimeTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageMimeTest.java @@ -45,22 +45,23 @@ public class BluetoothMapbMessageMimeTest { private static final boolean TEST_TEXT_ONLY = true; private static final boolean TEST_INCLUDE_ATTACHMENTS = true; - private final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", - Locale.US); + private final SimpleDateFormat format = + new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US); private final Date date = new Date(TEST_DATE); - private final ArrayList TEST_FROM = new ArrayList<>( - Arrays.asList(new Rfc822Token("from_name", "from_address", null))); - private final ArrayList TEST_SENDER = new ArrayList<>( - Arrays.asList(new Rfc822Token("sender_name", "sender_address", null))); - private static final ArrayList TEST_TO = new ArrayList<>( - Arrays.asList(new Rfc822Token("to_name", "to_address", null))); - private static final ArrayList TEST_CC = new ArrayList<>( - Arrays.asList(new Rfc822Token("cc_name", "cc_address", null))); - private final ArrayList TEST_BCC = new ArrayList<>( - Arrays.asList(new Rfc822Token("bcc_name", "bcc_address", null))); - private final ArrayList TEST_REPLY_TO = new ArrayList<>( - Arrays.asList(new Rfc822Token("reply_to_name", "reply_to_address", null))); + private final ArrayList TEST_FROM = + new ArrayList<>(Arrays.asList(new Rfc822Token("from_name", "from_address", null))); + private final ArrayList TEST_SENDER = + new ArrayList<>(Arrays.asList(new Rfc822Token("sender_name", "sender_address", null))); + private static final ArrayList TEST_TO = + new ArrayList<>(Arrays.asList(new Rfc822Token("to_name", "to_address", null))); + private static final ArrayList TEST_CC = + new ArrayList<>(Arrays.asList(new Rfc822Token("cc_name", "cc_address", null))); + private final ArrayList TEST_BCC = + new ArrayList<>(Arrays.asList(new Rfc822Token("bcc_name", "bcc_address", null))); + private final ArrayList TEST_REPLY_TO = + new ArrayList<>( + Arrays.asList(new Rfc822Token("reply_to_name", "reply_to_address", null))); private BluetoothMapbMessageMime mMime; @@ -113,7 +114,7 @@ public class BluetoothMapbMessageMimeTest { @Test public void testUpdateCharset() { - mMime.getMimeParts().get(0).mContentType = TEST_CONTENT_TYPE/*="text/plain*/; + mMime.getMimeParts().get(0).mContentType = TEST_CONTENT_TYPE /*="text/plain*/; mMime.updateCharset(); assertThat(mMime.mCharset).isEqualTo("UTF-8"); } @@ -133,8 +134,8 @@ public class BluetoothMapbMessageMimeTest { final String nameToAdd = "name_to_add"; final String addressToAdd = "address_to_add"; mime.addSender(nameToAdd, addressToAdd); - assertThat(mime.getSender().get(0)).isEqualTo( - new Rfc822Token(nameToAdd, addressToAdd, null)); + assertThat(mime.getSender().get(0)) + .isEqualTo(new Rfc822Token(nameToAdd, addressToAdd, null)); } @Test @@ -170,8 +171,8 @@ public class BluetoothMapbMessageMimeTest { final String nameToAdd = "name_to_add"; final String addressToAdd = "address_to_add"; mime.addReplyTo(nameToAdd, addressToAdd); - assertThat(mime.getReplyTo().get(0)).isEqualTo( - new Rfc822Token(nameToAdd, addressToAdd, null)); + assertThat(mime.getReplyTo().get(0)) + .isEqualTo(new Rfc822Token(nameToAdd, addressToAdd, null)); } @Test @@ -187,30 +188,30 @@ public class BluetoothMapbMessageMimeTest { assertThat(mimeToCreateByParsing.getMessageId()).isEqualTo(TEST_MESSAGE_ID); assertThat(mimeToCreateByParsing.getContentType()).isEqualTo(TEST_CONTENT_TYPE); - assertThat(mimeToCreateByParsing.getFrom().get(0).getName()).isEqualTo( - TEST_FROM.get(0).getName()); - assertThat(mimeToCreateByParsing.getFrom().get(0).getAddress()).isEqualTo( - TEST_FROM.get(0).getAddress()); - - assertThat(mimeToCreateByParsing.getTo().get(0).getName()).isEqualTo( - TEST_TO.get(0).getName()); - assertThat(mimeToCreateByParsing.getTo().get(0).getAddress()).isEqualTo( - TEST_TO.get(0).getAddress()); - - assertThat(mimeToCreateByParsing.getCc().get(0).getName()).isEqualTo( - TEST_CC.get(0).getName()); - assertThat(mimeToCreateByParsing.getCc().get(0).getAddress()).isEqualTo( - TEST_CC.get(0).getAddress()); - - assertThat(mimeToCreateByParsing.getBcc().get(0).getName()).isEqualTo( - TEST_BCC.get(0).getName()); - assertThat(mimeToCreateByParsing.getBcc().get(0).getAddress()).isEqualTo( - TEST_BCC.get(0).getAddress()); - - assertThat(mimeToCreateByParsing.getReplyTo().get(0).getName()).isEqualTo( - TEST_REPLY_TO.get(0).getName()); - assertThat(mimeToCreateByParsing.getReplyTo().get(0).getAddress()).isEqualTo( - TEST_REPLY_TO.get(0).getAddress()); + assertThat(mimeToCreateByParsing.getFrom().get(0).getName()) + .isEqualTo(TEST_FROM.get(0).getName()); + assertThat(mimeToCreateByParsing.getFrom().get(0).getAddress()) + .isEqualTo(TEST_FROM.get(0).getAddress()); + + assertThat(mimeToCreateByParsing.getTo().get(0).getName()) + .isEqualTo(TEST_TO.get(0).getName()); + assertThat(mimeToCreateByParsing.getTo().get(0).getAddress()) + .isEqualTo(TEST_TO.get(0).getAddress()); + + assertThat(mimeToCreateByParsing.getCc().get(0).getName()) + .isEqualTo(TEST_CC.get(0).getName()); + assertThat(mimeToCreateByParsing.getCc().get(0).getAddress()) + .isEqualTo(TEST_CC.get(0).getAddress()); + + assertThat(mimeToCreateByParsing.getBcc().get(0).getName()) + .isEqualTo(TEST_BCC.get(0).getName()); + assertThat(mimeToCreateByParsing.getBcc().get(0).getAddress()) + .isEqualTo(TEST_BCC.get(0).getAddress()); + + assertThat(mimeToCreateByParsing.getReplyTo().get(0).getName()) + .isEqualTo(TEST_REPLY_TO.get(0).getName()); + assertThat(mimeToCreateByParsing.getReplyTo().get(0).getAddress()) + .isEqualTo(TEST_REPLY_TO.get(0).getAddress()); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java index 7a9efe8fa0b..e1e8c20cc12 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java @@ -52,8 +52,8 @@ public class BluetoothMapbMessageSmsTest { // Do not run test if sms is not supported Assume.assumeTrue(mSmsManager.isImsSmsSupported()); mTargetContext = InstrumentationRegistry.getTargetContext(); - TEST_SMS_BODY_PDUS = BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, TEST_MESSAGE, - TEST_ADDRESS); + TEST_SMS_BODY_PDUS = + BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, TEST_MESSAGE, TEST_ADDRESS); } @Test @@ -84,8 +84,8 @@ public class BluetoothMapbMessageSmsTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_NATIVE); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_NATIVE); assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageSms.class); BluetoothMapbMessageSms messageSmsParsed = (BluetoothMapbMessageSms) messageParsed; assertThat(messageSmsParsed.getSmsBody()).isEqualTo(TEST_MESSAGE); @@ -101,10 +101,10 @@ public class BluetoothMapbMessageSmsTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, - BluetoothMapAppParams.CHARSET_UTF8); + BluetoothMapbMessage messageParsed = + BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_UTF8); assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageSms.class); BluetoothMapbMessageSms messageSmsParsed = (BluetoothMapbMessageSms) messageParsed; assertThat(messageSmsParsed.getSmsBody()).isEqualTo(""); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java index 2bc0e1a5358..299e2d4f46e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java @@ -43,18 +43,18 @@ public class BluetoothMapbMessageTest { private static final String TEST_FORMATTED_NAME = "test_formatted_name"; private static final String TEST_FIRST_PHONE_NUMBER = "111-1111-1111"; private static final String[] TEST_PHONE_NUMBERS = - new String[]{TEST_FIRST_PHONE_NUMBER, "222-2222-2222"}; + new String[] {TEST_FIRST_PHONE_NUMBER, "222-2222-2222"}; private static final String TEST_FIRST_EMAIL = "testFirst@email.com"; private static final String[] TEST_EMAIL_ADDRESSES = - new String[]{TEST_FIRST_EMAIL, "testSecond@email.com"}; + new String[] {TEST_FIRST_EMAIL, "testSecond@email.com"}; private static final String TEST_FIRST_BT_UCI = "test_first_bt_uci"; private static final String[] TEST_BT_UCIS = - new String[]{TEST_FIRST_BT_UCI, "test_second_bt_uci"}; + new String[] {TEST_FIRST_BT_UCI, "test_second_bt_uci"}; private static final String TEST_FIRST_BT_UID = "1111"; - private static final String[] TEST_BT_UIDS = new String[]{TEST_FIRST_BT_UID, "1112"}; + private static final String[] TEST_BT_UIDS = new String[] {TEST_FIRST_BT_UID, "1112"}; - private static final VCard TEST_VCARD = new VCard(TEST_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES); + private static final VCard TEST_VCARD = + new VCard(TEST_NAME, TEST_PHONE_NUMBERS, TEST_EMAIL_ADDRESSES); @Test public void settersAndGetters() { @@ -85,8 +85,8 @@ public class BluetoothMapbMessageTest { BluetoothMapbMessage messageMime = new BluetoothMapbMessageMime(); messageMime.addOriginator(TEST_NAME, TEST_PHONE_NUMBERS, TEST_EMAIL_ADDRESSES); assertThat(messageMime.getOriginators().get(0).getName()).isEqualTo(TEST_NAME); - assertThat(messageMime.getOriginators().get(0).getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(messageMime.getOriginators().get(0).getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(messageMime.getOriginators().get(0).getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); } @@ -100,22 +100,27 @@ public class BluetoothMapbMessageTest { @Test public void addOriginator_forVCardVersionThree() { BluetoothMapbMessage messageMime = new BluetoothMapbMessageMime(); - messageMime.addOriginator(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_BT_UIDS, TEST_BT_UCIS); + messageMime.addOriginator( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_BT_UIDS, + TEST_BT_UCIS); assertThat(messageMime.getOriginators().get(0).getName()).isEqualTo(TEST_NAME); - assertThat(messageMime.getOriginators().get(0).getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(messageMime.getOriginators().get(0).getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(messageMime.getOriginators().get(0).getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); - assertThat(messageMime.getOriginators().get(0).getFirstBtUci()).isEqualTo( - TEST_FIRST_BT_UCI); + assertThat(messageMime.getOriginators().get(0).getFirstBtUci()) + .isEqualTo(TEST_FIRST_BT_UCI); } @Test public void addOriginator_forVCardVersionThree_withOnlyBtUcisAndBtUids() { BluetoothMapbMessage messageMime = new BluetoothMapbMessageMime(); messageMime.addOriginator(TEST_BT_UCIS, TEST_BT_UIDS); - assertThat(messageMime.getOriginators().get(0).getFirstBtUci()).isEqualTo( - TEST_FIRST_BT_UCI); + assertThat(messageMime.getOriginators().get(0).getFirstBtUci()) + .isEqualTo(TEST_FIRST_BT_UCI); } @Test @@ -123,19 +128,24 @@ public class BluetoothMapbMessageTest { BluetoothMapbMessage messageMime = new BluetoothMapbMessageMime(); messageMime.addRecipient(TEST_NAME, TEST_PHONE_NUMBERS, TEST_EMAIL_ADDRESSES); assertThat(messageMime.getRecipients().get(0).getName()).isEqualTo(TEST_NAME); - assertThat(messageMime.getRecipients().get(0).getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(messageMime.getRecipients().get(0).getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(messageMime.getRecipients().get(0).getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); } @Test public void addRecipient_forVCardVersionThree() { BluetoothMapbMessage messageMime = new BluetoothMapbMessageMime(); - messageMime.addRecipient(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_BT_UIDS, TEST_BT_UCIS); + messageMime.addRecipient( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_BT_UIDS, + TEST_BT_UCIS); assertThat(messageMime.getRecipients().get(0).getName()).isEqualTo(TEST_NAME); - assertThat(messageMime.getRecipients().get(0).getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(messageMime.getRecipients().get(0).getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(messageMime.getRecipients().get(0).getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); assertThat(messageMime.getRecipients().get(0).getFirstBtUci()).isEqualTo(TEST_FIRST_BT_UCI); } @@ -155,21 +165,31 @@ public class BluetoothMapbMessageTest { messageMimeToEncode.setType(TEST_TYPE); messageMimeToEncode.setCompleteFolder(TEST_FOLDER); messageMimeToEncode.setEncoding(TEST_ENCODING); - messageMimeToEncode.addOriginator(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_BT_UIDS, TEST_BT_UCIS); - messageMimeToEncode.addRecipient(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_BT_UIDS, TEST_BT_UCIS); + messageMimeToEncode.addOriginator( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_BT_UIDS, + TEST_BT_UCIS); + messageMimeToEncode.addRecipient( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_BT_UIDS, + TEST_BT_UCIS); byte[] encodedMessageMime = messageMimeToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageMime); BluetoothMapbMessage messageMimeParsed = BluetoothMapbMessage.parse(inputStream, 1); assertThat(messageMimeParsed.mAppParamCharset).isEqualTo(1); - assertThat(messageMimeParsed.getVersionString()).isEqualTo( - "VERSION:" + TEST_VERSION_STRING); + assertThat(messageMimeParsed.getVersionString()) + .isEqualTo("VERSION:" + TEST_VERSION_STRING); assertThat(messageMimeParsed.getType()).isEqualTo(TEST_TYPE); assertThat(messageMimeParsed.getFolder()).isEqualTo(TEST_FOLDER); assertThat(messageMimeParsed.getRecipients().size()).isEqualTo(1); assertThat(messageMimeParsed.getOriginators().size()).isEqualTo(1); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java index 8f108f57d21..a44bd9cfda4 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java @@ -37,55 +37,66 @@ public class BluetoothMapbMessageVCardTest { private static final String TEST_FORMATTED_NAME = "test_formatted_name"; private static final String TEST_FIRST_PHONE_NUMBER = "111-1111-1111"; private static final String[] TEST_PHONE_NUMBERS = - new String[]{TEST_FIRST_PHONE_NUMBER, "222-2222-2222"}; + new String[] {TEST_FIRST_PHONE_NUMBER, "222-2222-2222"}; private static final String TEST_FIRST_EMAIL = "testFirst@email.com"; private static final String[] TEST_EMAIL_ADDRESSES = - new String[]{TEST_FIRST_EMAIL, "testSecond@email.com"}; + new String[] {TEST_FIRST_EMAIL, "testSecond@email.com"}; private static final String TEST_FIRST_BT_UCI = "test_first_bt_uci"; private static final String[] TEST_BT_UCIS = - new String[]{TEST_FIRST_BT_UCI, "test_second_bt_uci"}; + new String[] {TEST_FIRST_BT_UCI, "test_second_bt_uci"}; private static final String TEST_FIRST_BT_UID = "1111"; - private static final String[] TEST_BT_UIDS = new String[]{TEST_FIRST_BT_UID, "1112"}; + private static final String[] TEST_BT_UIDS = new String[] {TEST_FIRST_BT_UID, "1112"}; private static final int TEST_ENV_LEVEL = 1; @Test public void constructor_forVersionTwoPointOne() { VCard vcard = new VCard(TEST_NAME, TEST_PHONE_NUMBERS, TEST_EMAIL_ADDRESSES); assertThat(vcard.getName()).isEqualTo(TEST_NAME); - assertThat(vcard.getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(vcard.getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(vcard.getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); } @Test public void constructor_forVersionTwoPointOne_withEnvLevel() { - VCard vcard = new VCard(TEST_NAME, TEST_PHONE_NUMBERS, TEST_EMAIL_ADDRESSES, - TEST_ENV_LEVEL); + VCard vcard = + new VCard(TEST_NAME, TEST_PHONE_NUMBERS, TEST_EMAIL_ADDRESSES, TEST_ENV_LEVEL); assertThat(vcard.getName()).isEqualTo(TEST_NAME); - assertThat(vcard.getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(vcard.getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(vcard.getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); assertThat(vcard.getEnvLevel()).isEqualTo(TEST_ENV_LEVEL); } @Test public void constructor_forVersionThree() { - VCard vcard = new VCard(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_ENV_LEVEL); + VCard vcard = + new VCard( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_ENV_LEVEL); assertThat(vcard.getName()).isEqualTo(TEST_NAME); - assertThat(vcard.getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(vcard.getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(vcard.getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); assertThat(vcard.getEnvLevel()).isEqualTo(TEST_ENV_LEVEL); } @Test public void constructor_forVersionThree_withUcis() { - VCard vcard = new VCard(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_BT_UIDS, TEST_BT_UCIS); + VCard vcard = + new VCard( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_BT_UIDS, + TEST_BT_UCIS); assertThat(vcard.getName()).isEqualTo(TEST_NAME); - assertThat(vcard.getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(vcard.getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(vcard.getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); assertThat(vcard.getFirstBtUci()).isEqualTo(TEST_FIRST_BT_UCI); } @@ -102,8 +113,14 @@ public class BluetoothMapbMessageVCardTest { @Test public void encodeToStringBuilder_thenParseBackToVCard_returnsCorrectly() { - VCard vcardOriginal = new VCard(TEST_NAME, TEST_FORMATTED_NAME, TEST_PHONE_NUMBERS, - TEST_EMAIL_ADDRESSES, TEST_BT_UIDS, TEST_BT_UCIS); + VCard vcardOriginal = + new VCard( + TEST_NAME, + TEST_FORMATTED_NAME, + TEST_PHONE_NUMBERS, + TEST_EMAIL_ADDRESSES, + TEST_BT_UIDS, + TEST_BT_UCIS); StringBuilder stringBuilder = new StringBuilder(); vcardOriginal.encode(stringBuilder); InputStream inputStream = new ByteArrayInputStream(stringBuilder.toString().getBytes()); @@ -111,9 +128,9 @@ public class BluetoothMapbMessageVCardTest { VCard vcardParsed = VCard.parseVcard(new BMsgReader(inputStream), TEST_ENV_LEVEL); assertThat(vcardParsed.getName()).isEqualTo(TEST_NAME); - assertThat(vcardParsed.getFirstPhoneNumber()).isEqualTo( - PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); + assertThat(vcardParsed.getFirstPhoneNumber()) + .isEqualTo(PhoneNumberUtils.stripSeparators(TEST_FIRST_PHONE_NUMBER)); assertThat(vcardParsed.getFirstEmail()).isEqualTo(TEST_FIRST_EMAIL); assertThat(vcardParsed.getEnvLevel()).isEqualTo(TEST_ENV_LEVEL); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java index 8703e8e12a4..7be1a37d48c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java @@ -36,18 +36,21 @@ public class ConvoContactInfoTest { public void setConvoColumns() { BluetoothMapContentObserver.ConvoContactInfo info = new BluetoothMapContentObserver.ConvoContactInfo(); - MatrixCursor cursor = new MatrixCursor( - new String[]{BluetoothMapContract.ConvoContactColumns.CONVO_ID, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY, - BluetoothMapContract.ConvoContactColumns.LAST_ONLINE}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConvoContactColumns.CONVO_ID, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY, + BluetoothMapContract.ConvoContactColumns.LAST_ONLINE + }); info.setConvoColunms(cursor); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java index 12bb4386c2b..4ba945ead9e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java @@ -68,9 +68,8 @@ public class EventTest { } Context mockContext = mock(Context.class); MockContentResolver mockResolver = new MockContentResolver(); - BluetoothMapContentObserverTest.ExceptionTestProvider - mockProvider = new BluetoothMapContentObserverTest.ExceptionTestProvider( - mockContext); + BluetoothMapContentObserverTest.ExceptionTestProvider mockProvider = + new BluetoothMapContentObserverTest.ExceptionTestProvider(mockContext); mockResolver.addProvider("sms", mockProvider); TelephonyManager mockTelephony = mock(TelephonyManager.class); @@ -90,8 +89,8 @@ public class EventTest { @Test public void constructor() { - BluetoothMapContentObserver.Event event = mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, - TEST_FOLDER, TEST_TYPE); + BluetoothMapContentObserver.Event event = + mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, TEST_FOLDER, TEST_TYPE); assertThat(event.eventType).isEqualTo(TEST_EVENT_TYPE); assertThat(event.handle).isEqualTo(TEST_HANDLE); @@ -100,8 +99,8 @@ public class EventTest { @Test public void constructor_withNullOldFolder() { - BluetoothMapContentObserver.Event event = mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, - TEST_FOLDER, null, TEST_TYPE); + BluetoothMapContentObserver.Event event = + mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, TEST_FOLDER, null, TEST_TYPE); assertThat(event.eventType).isEqualTo(TEST_EVENT_TYPE); assertThat(event.handle).isEqualTo(TEST_HANDLE); @@ -111,8 +110,9 @@ public class EventTest { @Test public void constructor_withNonNullOldFolder() { - BluetoothMapContentObserver.Event event = mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, - TEST_FOLDER, TEST_OLD_FOLDER, TEST_TYPE); + BluetoothMapContentObserver.Event event = + mObserver + .new Event(TEST_EVENT_TYPE, TEST_HANDLE, TEST_FOLDER, TEST_OLD_FOLDER, TEST_TYPE); assertThat(event.eventType).isEqualTo(TEST_EVENT_TYPE); assertThat(event.handle).isEqualTo(TEST_HANDLE); @@ -122,44 +122,73 @@ public class EventTest { @Test public void constructor_forExtendedEventTypeOnePointOne() { - BluetoothMapContentObserver.Event event = mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, - TEST_FOLDER, TEST_TYPE, TEST_DATETIME, TEST_SUBJECT, TEST_SENDER_NAME, - TEST_PRIORITY); + BluetoothMapContentObserver.Event event = + mObserver + .new Event( + TEST_EVENT_TYPE, + TEST_HANDLE, + TEST_FOLDER, + TEST_TYPE, + TEST_DATETIME, + TEST_SUBJECT, + TEST_SENDER_NAME, + TEST_PRIORITY); assertThat(event.eventType).isEqualTo(TEST_EVENT_TYPE); assertThat(event.handle).isEqualTo(TEST_HANDLE); assertThat(event.msgType).isEqualTo(TEST_TYPE); assertThat(event.datetime).isEqualTo(TEST_DATETIME); assertThat(event.subject).isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_SUBJECT)); - assertThat(event.senderName).isEqualTo( - BluetoothMapUtils.stripInvalidChars(TEST_SENDER_NAME)); + assertThat(event.senderName) + .isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_SENDER_NAME)); assertThat(event.priority).isEqualTo(TEST_PRIORITY); } @Test public void constructor_forExtendedEventTypeOnePointTwo_withMessageEvents() { - BluetoothMapContentObserver.Event event = mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, - TEST_FOLDER, TEST_TYPE, TEST_DATETIME, TEST_SUBJECT, TEST_SENDER_NAME, - TEST_PRIORITY, TEST_CONVERSATION_ID, TEST_CONVERSATION_NAME); + BluetoothMapContentObserver.Event event = + mObserver + .new Event( + TEST_EVENT_TYPE, + TEST_HANDLE, + TEST_FOLDER, + TEST_TYPE, + TEST_DATETIME, + TEST_SUBJECT, + TEST_SENDER_NAME, + TEST_PRIORITY, + TEST_CONVERSATION_ID, + TEST_CONVERSATION_NAME); assertThat(event.eventType).isEqualTo(TEST_EVENT_TYPE); assertThat(event.handle).isEqualTo(TEST_HANDLE); assertThat(event.msgType).isEqualTo(TEST_TYPE); assertThat(event.datetime).isEqualTo(TEST_DATETIME); assertThat(event.subject).isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_SUBJECT)); - assertThat(event.senderName).isEqualTo( - BluetoothMapUtils.stripInvalidChars(TEST_SENDER_NAME)); + assertThat(event.senderName) + .isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_SENDER_NAME)); assertThat(event.priority).isEqualTo(TEST_PRIORITY); assertThat(event.conversationID).isEqualTo(TEST_CONVERSATION_ID); - assertThat(event.conversationName).isEqualTo( - BluetoothMapUtils.stripInvalidChars(TEST_CONVERSATION_NAME)); + assertThat(event.conversationName) + .isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_CONVERSATION_NAME)); } @Test public void constructor_forExtendedEventTypeOnePointTwo_withConversationEvents() { - BluetoothMapContentObserver.Event event = mObserver.new Event(TEST_EVENT_TYPE, TEST_UCI, - TEST_TYPE, TEST_NAME, TEST_PRIORITY, TEST_LAST_ACTIVITY, TEST_CONVERSATION_ID, - TEST_CONVERSATION_NAME, TEST_PRESENCE_STATE, TEST_PRESENCE_STATUS, TEST_CHAT_STATE); + BluetoothMapContentObserver.Event event = + mObserver + .new Event( + TEST_EVENT_TYPE, + TEST_UCI, + TEST_TYPE, + TEST_NAME, + TEST_PRIORITY, + TEST_LAST_ACTIVITY, + TEST_CONVERSATION_ID, + TEST_CONVERSATION_NAME, + TEST_PRESENCE_STATE, + TEST_PRESENCE_STATUS, + TEST_CHAT_STATE); assertThat(event.eventType).isEqualTo(TEST_EVENT_TYPE); assertThat(event.uci).isEqualTo(TEST_UCI); @@ -168,11 +197,11 @@ public class EventTest { assertThat(event.priority).isEqualTo(TEST_PRIORITY); assertThat(event.datetime).isEqualTo(TEST_LAST_ACTIVITY); assertThat(event.conversationID).isEqualTo(TEST_CONVERSATION_ID); - assertThat(event.conversationName).isEqualTo( - BluetoothMapUtils.stripInvalidChars(TEST_CONVERSATION_NAME)); + assertThat(event.conversationName) + .isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_CONVERSATION_NAME)); assertThat(event.presenceState).isEqualTo(TEST_PRESENCE_STATE); - assertThat(event.presenceStatus).isEqualTo( - BluetoothMapUtils.stripInvalidChars(TEST_PRESENCE_STATUS)); + assertThat(event.presenceStatus) + .isEqualTo(BluetoothMapUtils.stripInvalidChars(TEST_PRESENCE_STATUS)); assertThat(event.chatState).isEqualTo(TEST_CHAT_STATE); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java index 3c1a0c0c50e..bb713ae35c5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java @@ -44,22 +44,25 @@ public class FilterInfoTest { @Test public void setMessageColumns() { - MatrixCursor cursor = new MatrixCursor(new String[] { - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.MESSAGE_SIZE, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.TO_LIST, - BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT, - BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, - BluetoothMapContract.MessageColumns.FLAG_PROTECTED, - BluetoothMapContract.MessageColumns.RECEPTION_STATE, - BluetoothMapContract.MessageColumns.DEVILERY_STATE, - BluetoothMapContract.MessageColumns.THREAD_ID}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.MESSAGE_SIZE, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.TO_LIST, + BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT, + BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, + BluetoothMapContract.MessageColumns.FLAG_PROTECTED, + BluetoothMapContract.MessageColumns.RECEPTION_STATE, + BluetoothMapContract.MessageColumns.DEVILERY_STATE, + BluetoothMapContract.MessageColumns.THREAD_ID + }); mFilterInfo.setMessageColumns(cursor); @@ -82,10 +85,13 @@ public class FilterInfoTest { @Test public void setEmailMessageColumns() { - MatrixCursor cursor = new MatrixCursor( - new String[] {BluetoothMapContract.MessageColumns.CC_LIST, - BluetoothMapContract.MessageColumns.BCC_LIST, - BluetoothMapContract.MessageColumns.REPLY_TO_LIST}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.CC_LIST, + BluetoothMapContract.MessageColumns.BCC_LIST, + BluetoothMapContract.MessageColumns.REPLY_TO_LIST + }); mFilterInfo.setEmailMessageColumns(cursor); @@ -96,10 +102,13 @@ public class FilterInfoTest { @Test public void setImMessageColumns() { - MatrixCursor cursor = new MatrixCursor( - new String[] {BluetoothMapContract.MessageColumns.THREAD_NAME, - BluetoothMapContract.MessageColumns.ATTACHMENT_MINE_TYPES, - BluetoothMapContract.MessageColumns.BODY}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.MessageColumns.THREAD_NAME, + BluetoothMapContract.MessageColumns.ATTACHMENT_MINE_TYPES, + BluetoothMapContract.MessageColumns.BODY + }); mFilterInfo.setImMessageColumns(cursor); @@ -110,13 +119,16 @@ public class FilterInfoTest { @Test public void setEmailImConvoColumns() { - MatrixCursor cursor = new MatrixCursor( - new String[] {BluetoothMapContract.ConversationColumns.THREAD_ID, - BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY, - BluetoothMapContract.ConversationColumns.THREAD_NAME, - BluetoothMapContract.ConversationColumns.READ_STATUS, - BluetoothMapContract.ConversationColumns.VERSION_COUNTER, - BluetoothMapContract.ConversationColumns.SUMMARY}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConversationColumns.THREAD_ID, + BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY, + BluetoothMapContract.ConversationColumns.THREAD_NAME, + BluetoothMapContract.ConversationColumns.READ_STATUS, + BluetoothMapContract.ConversationColumns.VERSION_COUNTER, + BluetoothMapContract.ConversationColumns.SUMMARY + }); mFilterInfo.setEmailImConvoColumns(cursor); @@ -130,16 +142,19 @@ public class FilterInfoTest { @Test public void setEmailImConvoContactColumns() { - MatrixCursor cursor = new MatrixCursor( - new String[] {BluetoothMapContract.ConvoContactColumns.X_BT_UID, - BluetoothMapContract.ConvoContactColumns.CHAT_STATE, - BluetoothMapContract.ConvoContactColumns.UCI, - BluetoothMapContract.ConvoContactColumns.NICKNAME, - BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, - BluetoothMapContract.ConvoContactColumns.NAME, - BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, - BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, - BluetoothMapContract.ConvoContactColumns.PRIORITY}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothMapContract.ConvoContactColumns.X_BT_UID, + BluetoothMapContract.ConvoContactColumns.CHAT_STATE, + BluetoothMapContract.ConvoContactColumns.UCI, + BluetoothMapContract.ConvoContactColumns.NICKNAME, + BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE, + BluetoothMapContract.ConvoContactColumns.NAME, + BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE, + BluetoothMapContract.ConvoContactColumns.STATUS_TEXT, + BluetoothMapContract.ConvoContactColumns.PRIORITY + }); mFilterInfo.setEmailImConvoContactColumns(cursor); @@ -156,8 +171,17 @@ public class FilterInfoTest { @Test public void setSmsColumns() { - MatrixCursor cursor = new MatrixCursor(new String[]{BaseColumns._ID, Sms.TYPE, Sms.READ, - Sms.BODY, Sms.ADDRESS, Sms.DATE, Sms.THREAD_ID}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BaseColumns._ID, + Sms.TYPE, + Sms.READ, + Sms.BODY, + Sms.ADDRESS, + Sms.DATE, + Sms.THREAD_ID + }); mFilterInfo.setSmsColumns(cursor); @@ -173,9 +197,18 @@ public class FilterInfoTest { @Test public void setMmsColumns() { - MatrixCursor cursor = new MatrixCursor( - new String[] {BaseColumns._ID, Mms.MESSAGE_BOX, Mms.READ, Mms.MESSAGE_SIZE, - Mms.TEXT_ONLY, Mms.DATE, Mms.SUBJECT, Mms.THREAD_ID}); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BaseColumns._ID, + Mms.MESSAGE_BOX, + Mms.READ, + Mms.MESSAGE_SIZE, + Mms.TEXT_ONLY, + Mms.DATE, + Mms.SUBJECT, + Mms.THREAD_ID + }); mFilterInfo.setMmsColumns(cursor); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java index 9195ead8051..ce5ef8f05f5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java @@ -52,8 +52,8 @@ public class MapContactTest { public void getXBtUidString_withNonZeroId() { MapContact contact = MapContact.create(TEST_NON_ZERO_ID, TEST_NAME); - assertThat(contact.getXBtUidString()).isEqualTo( - BluetoothMapUtils.getLongLongAsString(TEST_NON_ZERO_ID, 0)); + assertThat(contact.getXBtUidString()) + .isEqualTo(BluetoothMapUtils.getLongLongAsString(TEST_NON_ZERO_ID, 0)); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java index 9e68fa69737..b47d0c465b3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java @@ -33,8 +33,8 @@ public class MsgTest { @Test public void constructor() { - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); assertThat(msg.id).isEqualTo(TEST_ID); assertThat(msg.folderId).isEqualTo(TEST_FOLDER_ID); @@ -43,8 +43,8 @@ public class MsgTest { @Test public void hashCode_returnsExpectedResult() { - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); int expected = 31 + (int) (TEST_ID ^ (TEST_ID >>> 32)); assertThat(msg.hashCode()).isEqualTo(expected); @@ -52,24 +52,24 @@ public class MsgTest { @Test public void equals_withSameInstance() { - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); assertThat(msg.equals(msg)).isTrue(); } @Test public void equals_withNull() { - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); assertThat(msg).isNotNull(); } @Test public void equals_withDifferentClass() { - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); String msgOfDifferentClass = "msg_of_different_class"; assertThat(msg).isNotEqualTo(msgOfDifferentClass); @@ -79,20 +79,20 @@ public class MsgTest { public void equals_withDifferentId() { long idOne = 1; long idTwo = 2; - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(idOne, - TEST_FOLDER_ID, TEST_READ_FLAG); - BluetoothMapContentObserver.Msg msgWithDifferentId = new BluetoothMapContentObserver.Msg( - idTwo, TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(idOne, TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msgWithDifferentId = + new BluetoothMapContentObserver.Msg(idTwo, TEST_FOLDER_ID, TEST_READ_FLAG); assertThat(msg).isNotEqualTo(msgWithDifferentId); } @Test public void equals_withEqualInstance() { - BluetoothMapContentObserver.Msg msg = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); - BluetoothMapContentObserver.Msg msgWithSameId = new BluetoothMapContentObserver.Msg(TEST_ID, - TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msg = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); + BluetoothMapContentObserver.Msg msgWithSameId = + new BluetoothMapContentObserver.Msg(TEST_ID, TEST_FOLDER_ID, TEST_READ_FLAG); assertThat(msg).isEqualTo(msgWithSameId); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java index 38f9ca46b20..b929fa65bcf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java @@ -50,10 +50,8 @@ public class SmsMmsContactsTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private ContentResolver mResolver; - @Spy - private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); + @Mock private ContentResolver mResolver; + @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); private SmsMmsContacts mContacts; @@ -70,30 +68,33 @@ public class SmsMmsContactsTest { @Test public void getPhoneNumberUncached_withNonEmptyCursor() { - MatrixCursor cursor = new MatrixCursor(new String[]{"COL_ARRR_ID", "COL_ADDR_ADDR"}); - cursor.addRow(new Object[]{null, TEST_PHONE_NUMBER}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - - assertThat(SmsMmsContacts.getPhoneNumberUncached(mResolver, TEST_ID)).isEqualTo( - TEST_PHONE_NUMBER); + MatrixCursor cursor = new MatrixCursor(new String[] {"COL_ARRR_ID", "COL_ADDR_ADDR"}); + cursor.addRow(new Object[] {null, TEST_PHONE_NUMBER}); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + + assertThat(SmsMmsContacts.getPhoneNumberUncached(mResolver, TEST_ID)) + .isEqualTo(TEST_PHONE_NUMBER); } @Test public void getPhoneNumberUncached_withEmptyCursor() { - MatrixCursor cursor = new MatrixCursor(new String[]{}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = new MatrixCursor(new String[] {}); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); assertThat(SmsMmsContacts.getPhoneNumberUncached(mResolver, TEST_ID)).isNull(); } @Test public void fillPhoneCache() { - MatrixCursor cursor = new MatrixCursor(new String[]{"COL_ADDR_ID", "COL_ADDR_ADDR"}); - cursor.addRow(new Object[]{TEST_ID, TEST_PHONE_NUMBER}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = new MatrixCursor(new String[] {"COL_ADDR_ID", "COL_ADDR_ADDR"}); + cursor.addRow(new Object[] {TEST_ID, TEST_PHONE_NUMBER}); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContacts.fillPhoneCache(mResolver); @@ -102,15 +103,17 @@ public class SmsMmsContactsTest { @Test public void fillPhoneCache_withNonNullPhoneNumbers() { - MatrixCursor cursor = new MatrixCursor(new String[]{"COL_ADDR_ID", "COL_ADDR_ADDR"}); - cursor.addRow(new Object[]{TEST_ID, TEST_PHONE_NUMBER}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = new MatrixCursor(new String[] {"COL_ADDR_ID", "COL_ADDR_ADDR"}); + cursor.addRow(new Object[] {TEST_ID, TEST_PHONE_NUMBER}); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContacts.fillPhoneCache(mResolver); assertThat(mContacts.getPhoneNumber(mResolver, TEST_ID)).isEqualTo(TEST_PHONE_NUMBER); - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); mContacts.fillPhoneCache(mResolver); assertThat(mContacts.getPhoneNumber(mResolver, TEST_ID)).isNull(); @@ -118,10 +121,11 @@ public class SmsMmsContactsTest { @Test public void clearCache() { - MatrixCursor cursor = new MatrixCursor(new String[]{"COL_ADDR_ID", "COL_ADDR_ADDR"}); - cursor.addRow(new Object[]{TEST_ID, TEST_PHONE_NUMBER}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = new MatrixCursor(new String[] {"COL_ADDR_ID", "COL_ADDR_ADDR"}); + cursor.addRow(new Object[] {TEST_ID, TEST_PHONE_NUMBER}); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); MapContact contact = MapContact.create(TEST_ID, TEST_PHONE); mContacts.mNames.put(TEST_PHONE, contact); @@ -129,37 +133,47 @@ public class SmsMmsContactsTest { assertThat(mContacts.getPhoneNumber(mResolver, TEST_ID)).isEqualTo(TEST_PHONE_NUMBER); mContacts.clearCache(); - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); assertThat(mContacts.mNames).isEmpty(); assertThat(mContacts.getPhoneNumber(mResolver, TEST_ID)).isEqualTo(null); } @Test public void getContactNameFromPhone_withNonNullCursor() { - MatrixCursor cursor = new MatrixCursor(new String[]{"COL_CONTACT_ID", "COL_CONTACT_NAME"}); - cursor.addRow(new Object[]{TEST_ID, TEST_NAME}); - doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + MatrixCursor cursor = new MatrixCursor(new String[] {"COL_CONTACT_ID", "COL_CONTACT_NAME"}); + cursor.addRow(new Object[] {TEST_ID, TEST_NAME}); + doReturn(cursor) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); MapContact expected = MapContact.create(TEST_ID, TEST_NAME); - assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, - TEST_CONTACT_NAME_FILTER).toString()).isEqualTo(expected.toString()); + assertThat( + mContacts + .getContactNameFromPhone( + TEST_PHONE, mResolver, TEST_CONTACT_NAME_FILTER) + .toString()) + .isEqualTo(expected.toString()); } @Test public void getContactNameFromPhone_withNullCursor() { - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); - - assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, - TEST_CONTACT_NAME_FILTER)).isNull(); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); + + assertThat( + mContacts.getContactNameFromPhone( + TEST_PHONE, mResolver, TEST_CONTACT_NAME_FILTER)) + .isNull(); } @Test public void getContactNameFromPhone_withNoParameterForContactNameFilter() { - doReturn(null).when(mMapMethodProxy).contentResolverQuery(any(), any(), any(), any(), - any(), any()); + doReturn(null) + .when(mMapMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver)).isNull(); } @@ -170,8 +184,10 @@ public class SmsMmsContactsTest { MapContact contact = MapContact.create(zeroId, TEST_PHONE); mContacts.mNames.put(TEST_PHONE, contact); - assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, - TEST_CONTACT_NAME_FILTER)).isNull(); + assertThat( + mContacts.getContactNameFromPhone( + TEST_PHONE, mResolver, TEST_CONTACT_NAME_FILTER)) + .isNull(); } @Test @@ -179,8 +195,8 @@ public class SmsMmsContactsTest { MapContact contact = MapContact.create(TEST_ID, TEST_PHONE); mContacts.mNames.put(TEST_PHONE, contact); - assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, null)).isEqualTo( - contact); + assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, null)) + .isEqualTo(contact); } @Test @@ -189,7 +205,7 @@ public class SmsMmsContactsTest { mContacts.mNames.put(TEST_PHONE, contact); String nonMatchingFilter = "non_matching_filter"; - assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, - nonMatchingFilter)).isNull(); + assertThat(mContacts.getContactNameFromPhone(TEST_PHONE, mResolver, nonMatchingFilter)) + .isNull(); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java index 0a34f886e62..c808bca43b9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java @@ -35,8 +35,8 @@ public class BluetoothMapContractTest { @Test public void testBuildAccountUri() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + BluetoothMapContract.TABLE_ACCOUNT; + final String expectedUriString = + "content://" + TEST_AUTHORITY + "/" + BluetoothMapContract.TABLE_ACCOUNT; Uri result = BluetoothMapContract.buildAccountUri(TEST_AUTHORITY); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -44,8 +44,13 @@ public class BluetoothMapContractTest { @Test public void testBuildAccountUriWithId() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + BluetoothMapContract.TABLE_ACCOUNT + "/" + ACCOUNT_ID; + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + BluetoothMapContract.TABLE_ACCOUNT + + "/" + + ACCOUNT_ID; Uri result = BluetoothMapContract.buildAccountUriwithId(TEST_AUTHORITY, ACCOUNT_ID); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -53,8 +58,8 @@ public class BluetoothMapContractTest { @Test public void testBuildMessageUri() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + BluetoothMapContract.TABLE_MESSAGE; + final String expectedUriString = + "content://" + TEST_AUTHORITY + "/" + BluetoothMapContract.TABLE_MESSAGE; Uri result = BluetoothMapContract.buildMessageUri(TEST_AUTHORITY); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -62,8 +67,13 @@ public class BluetoothMapContractTest { @Test public void testBuildMessageUri_withAccountId() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + ACCOUNT_ID + "/" + BluetoothMapContract.TABLE_MESSAGE; + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + ACCOUNT_ID + + "/" + + BluetoothMapContract.TABLE_MESSAGE; Uri result = BluetoothMapContract.buildMessageUri(TEST_AUTHORITY, ACCOUNT_ID); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -71,18 +81,30 @@ public class BluetoothMapContractTest { @Test public void testBuildMessageUriWithId() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + ACCOUNT_ID + "/" + BluetoothMapContract.TABLE_MESSAGE + "/" + MESSAGE_ID; - - Uri result = BluetoothMapContract.buildMessageUriWithId( - TEST_AUTHORITY, ACCOUNT_ID, MESSAGE_ID); + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + ACCOUNT_ID + + "/" + + BluetoothMapContract.TABLE_MESSAGE + + "/" + + MESSAGE_ID; + + Uri result = + BluetoothMapContract.buildMessageUriWithId(TEST_AUTHORITY, ACCOUNT_ID, MESSAGE_ID); assertThat(result.toString()).isEqualTo(expectedUriString); } @Test public void testBuildFolderUri() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + ACCOUNT_ID + "/" + BluetoothMapContract.TABLE_FOLDER; + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + ACCOUNT_ID + + "/" + + BluetoothMapContract.TABLE_FOLDER; Uri result = BluetoothMapContract.buildFolderUri(TEST_AUTHORITY, ACCOUNT_ID); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -90,8 +112,13 @@ public class BluetoothMapContractTest { @Test public void testBuildConversationUri() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + ACCOUNT_ID + "/" + BluetoothMapContract.TABLE_CONVERSATION; + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + ACCOUNT_ID + + "/" + + BluetoothMapContract.TABLE_CONVERSATION; Uri result = BluetoothMapContract.buildConversationUri(TEST_AUTHORITY, ACCOUNT_ID); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -99,8 +126,8 @@ public class BluetoothMapContractTest { @Test public void testBuildConvoContactsUri() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + BluetoothMapContract.TABLE_CONVOCONTACT; + final String expectedUriString = + "content://" + TEST_AUTHORITY + "/" + BluetoothMapContract.TABLE_CONVOCONTACT; Uri result = BluetoothMapContract.buildConvoContactsUri(TEST_AUTHORITY); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -108,8 +135,13 @@ public class BluetoothMapContractTest { @Test public void testBuildConvoContactsUri_withAccountId() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + ACCOUNT_ID + "/" + BluetoothMapContract.TABLE_CONVOCONTACT; + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + ACCOUNT_ID + + "/" + + BluetoothMapContract.TABLE_CONVOCONTACT; Uri result = BluetoothMapContract.buildConvoContactsUri(TEST_AUTHORITY, ACCOUNT_ID); assertThat(result.toString()).isEqualTo(expectedUriString); @@ -117,11 +149,19 @@ public class BluetoothMapContractTest { @Test public void testBuildConvoContactsUriWithId() { - final String expectedUriString = "content://" + TEST_AUTHORITY + "/" - + ACCOUNT_ID + "/" + BluetoothMapContract.TABLE_CONVOCONTACT + "/" + CONTACT_ID; - - Uri result = BluetoothMapContract.buildConvoContactsUriWithId( - TEST_AUTHORITY, ACCOUNT_ID, CONTACT_ID); + final String expectedUriString = + "content://" + + TEST_AUTHORITY + + "/" + + ACCOUNT_ID + + "/" + + BluetoothMapContract.TABLE_CONVOCONTACT + + "/" + + CONTACT_ID; + + Uri result = + BluetoothMapContract.buildConvoContactsUriWithId( + TEST_AUTHORITY, ACCOUNT_ID, CONTACT_ID); assertThat(result.toString()).isEqualTo(expectedUriString); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java index c109dcceb49..a31d416d1e1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java @@ -59,8 +59,7 @@ public class BluetoothMapEmailProviderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Spy - private BluetoothMapEmailProvider mProvider = new TestBluetoothMapEmailProvider(); + @Spy private BluetoothMapEmailProvider mProvider = new TestBluetoothMapEmailProvider(); @Before public void setUp() throws Exception { @@ -73,8 +72,7 @@ public class BluetoothMapEmailProviderTest { providerInfo.authority = AUTHORITY; providerInfo.exported = false; - assertThrows(SecurityException.class, - () -> mProvider.attachInfo(mContext, providerInfo)); + assertThrows(SecurityException.class, () -> mProvider.attachInfo(mContext, providerInfo)); } @Test @@ -84,8 +82,7 @@ public class BluetoothMapEmailProviderTest { providerInfo.exported = true; providerInfo.writePermission = "some.random.permission"; - assertThrows(SecurityException.class, - () -> mProvider.attachInfo(mContext, providerInfo)); + assertThrows(SecurityException.class, () -> mProvider.attachInfo(mContext, providerInfo)); } @Test @@ -105,7 +102,7 @@ public class BluetoothMapEmailProviderTest { @Test public void getType() throws Exception { try { - mProvider.getType(/*uri=*/ null); + mProvider.getType(/* uri= */ null); } catch (Exception e) { assertWithMessage("Exception should not happen.").fail(); } @@ -113,38 +110,46 @@ public class BluetoothMapEmailProviderTest { @Test public void delete_whenTableNameIsWrong() throws Exception { - Uri uriWithWrongTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath("some_random_table_name") - .appendPath(MESSAGE_ID) - .build(); + Uri uriWithWrongTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath("some_random_table_name") + .appendPath(MESSAGE_ID) + .build(); // No rows are impacted. - assertThat(mProvider.delete(uriWithWrongTable, /*where=*/null, /*selectionArgs=*/null)) + assertThat( + mProvider.delete( + uriWithWrongTable, /* where= */ null, /* selectionArgs= */ null)) .isEqualTo(0); } @Test public void delete_success() throws Exception { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .appendPath(MESSAGE_ID) - .build(); - - mProvider.delete(messageUri, /*where=*/null, /*selectionArgs=*/null); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .appendPath(MESSAGE_ID) + .build(); + + mProvider.delete(messageUri, /* where= */ null, /* selectionArgs= */ null); verify(mProvider).deleteMessage(ACCOUNT_ID, MESSAGE_ID); } @Test public void insert_whenFolderIdIsNull() throws Exception { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); // ContentValues doses not have folder ID. ContentValues values = new ContentValues(); @@ -153,11 +158,13 @@ public class BluetoothMapEmailProviderTest { @Test public void insert_whenTableNameIsWrong() throws Exception { - Uri uriWithWrongTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath("some_random_table_name") - .build(); + Uri uriWithWrongTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath("some_random_table_name") + .build(); ContentValues values = new ContentValues(); values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, Long.parseLong(FOLDER_ID)); @@ -166,11 +173,13 @@ public class BluetoothMapEmailProviderTest { @Test public void insert_success() throws Exception { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); ContentValues values = new ContentValues(); values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, Long.parseLong(FOLDER_ID)); @@ -187,13 +196,19 @@ public class BluetoothMapEmailProviderTest { providerInfo.writePermission = android.Manifest.permission.BLUETOOTH_MAP; mProvider.attachInfo(mContext, providerInfo); - Uri accountUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(BluetoothMapContract.TABLE_ACCOUNT) - .build(); - - mProvider.query(accountUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); + Uri accountUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(BluetoothMapContract.TABLE_ACCOUNT) + .build(); + + mProvider.query( + accountUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); verify(mProvider).queryAccount(any(), any(), any(), any()); } @@ -205,14 +220,20 @@ public class BluetoothMapEmailProviderTest { providerInfo.writePermission = android.Manifest.permission.BLUETOOTH_MAP; mProvider.attachInfo(mContext, providerInfo); - Uri folderUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_FOLDER) - .build(); - - mProvider.query(folderUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); + Uri folderUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_FOLDER) + .build(); + + mProvider.query( + folderUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); verify(mProvider).queryFolder(eq(ACCOUNT_ID), any(), any(), any(), any()); } @@ -224,82 +245,109 @@ public class BluetoothMapEmailProviderTest { providerInfo.writePermission = android.Manifest.permission.BLUETOOTH_MAP; mProvider.attachInfo(mContext, providerInfo); - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); - - mProvider.query(messageUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); + + mProvider.query( + messageUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); verify(mProvider).queryMessage(eq(ACCOUNT_ID), any(), any(), any(), any()); } @Test public void update_whenTableIsNull() { - Uri uriWithoutTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .build(); + Uri uriWithoutTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .build(); ContentValues values = new ContentValues(); - assertThrows(IllegalArgumentException.class, - () -> mProvider.update(uriWithoutTable, values, /*selection=*/ null, - /*selectionArgs=*/ null)); + assertThrows( + IllegalArgumentException.class, + () -> + mProvider.update( + uriWithoutTable, + values, + /* selection= */ null, + /* selectionArgs= */ null)); } @Test public void update_whenSelectionIsNotNull() { - Uri uriWithTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_ACCOUNT) - .build(); + Uri uriWithTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_ACCOUNT) + .build(); ContentValues values = new ContentValues(); String nonNullSelection = "id = 1234"; - assertThrows(IllegalArgumentException.class, - () -> mProvider.update(uriWithTable, values, nonNullSelection, - /*selectionArgs=*/ null)); + assertThrows( + IllegalArgumentException.class, + () -> + mProvider.update( + uriWithTable, values, nonNullSelection, /* selectionArgs= */ null)); } @Test public void update_forAccountUri_success() { - Uri accountUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_ACCOUNT) - .build(); + Uri accountUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_ACCOUNT) + .build(); ContentValues values = new ContentValues(); final int flagValue = 1; values.put(BluetoothMapContract.AccountColumns._ID, ACCOUNT_ID); values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, flagValue); - mProvider.update(accountUri, values, /*selection=*/ null, /*selectionArgs=*/ null); + mProvider.update(accountUri, values, /* selection= */ null, /* selectionArgs= */ null); verify(mProvider).updateAccount(ACCOUNT_ID, flagValue); } @Test public void update_forFolderUri() { - Uri folderUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_FOLDER) - .build(); - - assertThat(mProvider.update( - folderUri, /*values=*/ null, /*selection=*/ null, /*selectionArgs=*/ null)) + Uri folderUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_FOLDER) + .build(); + + assertThat( + mProvider.update( + folderUri, + /* values= */ null, + /* selection= */ null, + /* selectionArgs= */ null)) .isEqualTo(0); } @Test public void update_forMessageUri_success() { - Uri accountUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); + Uri accountUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); ContentValues values = new ContentValues(); final boolean flagRead = true; @@ -307,15 +355,19 @@ public class BluetoothMapEmailProviderTest { values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, Long.parseLong(FOLDER_ID)); values.put(BluetoothMapContract.MessageColumns.FLAG_READ, flagRead); - mProvider.update(accountUri, values, /*selection=*/ null, /*selectionArgs=*/ null); - verify(mProvider).updateMessage( - ACCOUNT_ID, Long.parseLong(MESSAGE_ID), Long.parseLong(FOLDER_ID), flagRead); + mProvider.update(accountUri, values, /* selection= */ null, /* selectionArgs= */ null); + verify(mProvider) + .updateMessage( + ACCOUNT_ID, + Long.parseLong(MESSAGE_ID), + Long.parseLong(FOLDER_ID), + flagRead); } @Test public void call_whenMethodIsWrong() { String method = "some_random_method"; - assertThat(mProvider.call(method, /*arg=*/ null, /*extras=*/ null)).isNull(); + assertThat(mProvider.call(method, /* arg= */ null, /* extras= */ null)).isNull(); } @Test @@ -323,7 +375,9 @@ public class BluetoothMapEmailProviderTest { Bundle extras = new Bundle(); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, 12345); - assertThat(mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /*arg=*/ null, extras)) + assertThat( + mProvider.call( + BluetoothMapContract.METHOD_UPDATE_FOLDER, /* arg= */ null, extras)) .isNull(); } @@ -332,7 +386,9 @@ public class BluetoothMapEmailProviderTest { Bundle extras = new Bundle(); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_ACCOUNT_ID, 12345); - assertThat(mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /*arg=*/ null, extras)) + assertThat( + mProvider.call( + BluetoothMapContract.METHOD_UPDATE_FOLDER, /* arg= */ null, extras)) .isNull(); } @@ -342,7 +398,7 @@ public class BluetoothMapEmailProviderTest { extras.putLong(BluetoothMapContract.EXTRA_UPDATE_ACCOUNT_ID, Long.parseLong(ACCOUNT_ID)); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, Long.parseLong(FOLDER_ID)); - mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /*arg=*/ null, extras); + mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /* arg= */ null, extras); verify(mProvider).syncFolder(Long.parseLong(ACCOUNT_ID), Long.parseLong(FOLDER_ID)); } @@ -357,32 +413,39 @@ public class BluetoothMapEmailProviderTest { @Test public void getAccountId_whenNotEnoughPathSegments() { - Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .build(); - - assertThrows(IllegalArgumentException.class, - () -> BluetoothMapEmailProvider.getAccountId(uri)); + Uri uri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .build(); + + assertThrows( + IllegalArgumentException.class, () -> BluetoothMapEmailProvider.getAccountId(uri)); } @Test public void getAccountId_success() { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .appendPath(MESSAGE_ID) - .build(); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .appendPath(MESSAGE_ID) + .build(); assertThat(BluetoothMapEmailProvider.getAccountId(messageUri)).isEqualTo(ACCOUNT_ID); } public static class TestBluetoothMapEmailProvider extends BluetoothMapEmailProvider { @Override - protected void WriteMessageToStream(long accountId, long messageId, - boolean includeAttachment, boolean download, FileOutputStream out) - throws IOException { - } + protected void WriteMessageToStream( + long accountId, + long messageId, + boolean includeAttachment, + boolean download, + FileOutputStream out) + throws IOException {} @Override protected Uri getContentUri() { @@ -390,9 +453,8 @@ public class BluetoothMapEmailProviderTest { } @Override - protected void UpdateMimeMessageFromStream(FileInputStream input, long accountId, - long messageId) throws IOException { - } + protected void UpdateMimeMessageFromStream( + FileInputStream input, long accountId, long messageId) throws IOException {} @Override protected int deleteMessage(String accountId, String messageId) { @@ -405,20 +467,28 @@ public class BluetoothMapEmailProviderTest { } @Override - protected Cursor queryAccount(String[] projection, String selection, String[] selectionArgs, - String sortOrder) { + protected Cursor queryAccount( + String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override - protected Cursor queryFolder(String accountId, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { + protected Cursor queryFolder( + String accountId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder) { return null; } @Override - protected Cursor queryMessage(String accountId, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { + protected Cursor queryMessage( + String accountId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder) { return null; } @@ -428,8 +498,8 @@ public class BluetoothMapEmailProviderTest { } @Override - protected int updateMessage(String accountId, Long messageId, Long folderId, - Boolean flagRead) { + protected int updateMessage( + String accountId, Long messageId, Long folderId, Boolean flagRead) { return 0; } @@ -442,6 +512,6 @@ public class BluetoothMapEmailProviderTest { public boolean onCreate() { return true; } - }; - + } + ; } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java index cae58764919..f01fe54a968 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java @@ -70,8 +70,7 @@ public class BluetoothMapIMProviderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Spy - private BluetoothMapIMProvider mProvider = new TestBluetoothMapIMProvider(); + @Spy private BluetoothMapIMProvider mProvider = new TestBluetoothMapIMProvider(); @Before public void setUp() throws Exception { @@ -84,8 +83,7 @@ public class BluetoothMapIMProviderTest { providerInfo.authority = AUTHORITY; providerInfo.exported = false; - assertThrows(SecurityException.class, - () -> mProvider.attachInfo(mContext, providerInfo)); + assertThrows(SecurityException.class, () -> mProvider.attachInfo(mContext, providerInfo)); } @Test @@ -95,8 +93,7 @@ public class BluetoothMapIMProviderTest { providerInfo.exported = true; providerInfo.writePermission = "some.random.permission"; - assertThrows(SecurityException.class, - () -> mProvider.attachInfo(mContext, providerInfo)); + assertThrows(SecurityException.class, () -> mProvider.attachInfo(mContext, providerInfo)); } @Test @@ -116,7 +113,7 @@ public class BluetoothMapIMProviderTest { @Test public void getType() throws Exception { try { - mProvider.getType(/*uri=*/ null); + mProvider.getType(/* uri= */ null); } catch (Exception e) { assertWithMessage("Exception should not happen.").fail(); } @@ -124,38 +121,46 @@ public class BluetoothMapIMProviderTest { @Test public void delete_whenTableNameIsWrong() throws Exception { - Uri uriWithWrongTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath("some_random_table_name") - .appendPath(MESSAGE_ID) - .build(); + Uri uriWithWrongTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath("some_random_table_name") + .appendPath(MESSAGE_ID) + .build(); // No rows are impacted. - assertThat(mProvider.delete(uriWithWrongTable, /*where=*/null, /*selectionArgs=*/null)) + assertThat( + mProvider.delete( + uriWithWrongTable, /* where= */ null, /* selectionArgs= */ null)) .isEqualTo(0); } @Test public void delete_success() throws Exception { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .appendPath(MESSAGE_ID) - .build(); - - mProvider.delete(messageUri, /*where=*/null, /*selectionArgs=*/null); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .appendPath(MESSAGE_ID) + .build(); + + mProvider.delete(messageUri, /* where= */ null, /* selectionArgs= */ null); verify(mProvider).deleteMessage(ACCOUNT_ID, MESSAGE_ID); } @Test public void insert_whenTableNameIsWrong() throws Exception { - Uri uriWithWrongTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath("some_random_table_name") - .build(); + Uri uriWithWrongTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath("some_random_table_name") + .build(); ContentValues values = new ContentValues(); values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, Long.parseLong(FOLDER_ID)); @@ -164,11 +169,13 @@ public class BluetoothMapIMProviderTest { @Test public void insert_success() throws Exception { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); ContentValues values = new ContentValues(); values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, Long.parseLong(FOLDER_ID)); @@ -185,13 +192,19 @@ public class BluetoothMapIMProviderTest { providerInfo.writePermission = android.Manifest.permission.BLUETOOTH_MAP; mProvider.attachInfo(mContext, providerInfo); - Uri accountUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(BluetoothMapContract.TABLE_ACCOUNT) - .build(); - - mProvider.query(accountUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); + Uri accountUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(BluetoothMapContract.TABLE_ACCOUNT) + .build(); + + mProvider.query( + accountUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); verify(mProvider).queryAccount(any(), any(), any(), any()); } @@ -203,14 +216,20 @@ public class BluetoothMapIMProviderTest { providerInfo.writePermission = android.Manifest.permission.BLUETOOTH_MAP; mProvider.attachInfo(mContext, providerInfo); - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); - - mProvider.query(messageUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); + + mProvider.query( + messageUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); verify(mProvider).queryMessage(eq(ACCOUNT_ID), any(), any(), any(), any()); } @@ -228,26 +247,41 @@ public class BluetoothMapIMProviderTest { final long periodBegin = 10; final String searchString = "sample_search_query"; - Uri conversationUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_CONVERSATION) - .appendQueryParameter(BluetoothMapContract.FILTER_ORIGINATOR_SUBSTRING, - searchString) - .appendQueryParameter(BluetoothMapContract.FILTER_PERIOD_BEGIN, - Long.toString(periodBegin)) - .appendQueryParameter(BluetoothMapContract.FILTER_PERIOD_END, - Long.toString(periodEnd)) - .appendQueryParameter(BluetoothMapContract.FILTER_READ_STATUS, - Boolean.toString(read)) - .appendQueryParameter(BluetoothMapContract.FILTER_THREAD_ID, - Long.toString(threadId)) - .build(); - - mProvider.query(conversationUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); - verify(mProvider).queryConversation(eq(ACCOUNT_ID), eq(threadId), eq(read), eq(periodEnd), - eq(periodBegin), eq(searchString), any(), any()); + Uri conversationUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_CONVERSATION) + .appendQueryParameter( + BluetoothMapContract.FILTER_ORIGINATOR_SUBSTRING, searchString) + .appendQueryParameter( + BluetoothMapContract.FILTER_PERIOD_BEGIN, + Long.toString(periodBegin)) + .appendQueryParameter( + BluetoothMapContract.FILTER_PERIOD_END, Long.toString(periodEnd)) + .appendQueryParameter( + BluetoothMapContract.FILTER_READ_STATUS, Boolean.toString(read)) + .appendQueryParameter( + BluetoothMapContract.FILTER_THREAD_ID, Long.toString(threadId)) + .build(); + + mProvider.query( + conversationUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); + verify(mProvider) + .queryConversation( + eq(ACCOUNT_ID), + eq(threadId), + eq(read), + eq(periodEnd), + eq(periodBegin), + eq(searchString), + any(), + any()); } @Test @@ -258,108 +292,147 @@ public class BluetoothMapIMProviderTest { providerInfo.writePermission = android.Manifest.permission.BLUETOOTH_MAP; mProvider.attachInfo(mContext, providerInfo); - Uri convoContactUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_CONVOCONTACT) - .build(); - - mProvider.query(convoContactUri, /*projection=*/ null, /*selection=*/ null, - /*selectionArgs=*/ null, /*sortOrder=*/ null); + Uri convoContactUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_CONVOCONTACT) + .build(); + + mProvider.query( + convoContactUri, + /* projection= */ null, + /* selection= */ null, + /* selectionArgs= */ null, + /* sortOrder= */ null); verify(mProvider).queryConvoContact(eq(ACCOUNT_ID), any(), any(), any(), any(), any()); } @Test public void update_whenTableIsNull() { - Uri uriWithoutTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .build(); + Uri uriWithoutTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .build(); ContentValues values = new ContentValues(); - assertThrows(IllegalArgumentException.class, - () -> mProvider.update(uriWithoutTable, values, /*selection=*/ null, - /*selectionArgs=*/ null)); + assertThrows( + IllegalArgumentException.class, + () -> + mProvider.update( + uriWithoutTable, + values, + /* selection= */ null, + /* selectionArgs= */ null)); } @Test public void update_whenSelectionIsNotNull() { - Uri uriWithTable = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_ACCOUNT) - .build(); + Uri uriWithTable = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_ACCOUNT) + .build(); ContentValues values = new ContentValues(); String nonNullSelection = "id = 1234"; - assertThrows(IllegalArgumentException.class, - () -> mProvider.update(uriWithTable, values, nonNullSelection, - /*selectionArgs=*/ null)); + assertThrows( + IllegalArgumentException.class, + () -> + mProvider.update( + uriWithTable, values, nonNullSelection, /* selectionArgs= */ null)); } @Test public void update_forAccountUri_success() { - Uri accountUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_ACCOUNT) - .build(); + Uri accountUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_ACCOUNT) + .build(); ContentValues values = new ContentValues(); final int flagValue = 1; values.put(BluetoothMapContract.AccountColumns._ID, ACCOUNT_ID); values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, flagValue); - mProvider.update(accountUri, values, /*selection=*/ null, /*selectionArgs=*/ null); + mProvider.update(accountUri, values, /* selection= */ null, /* selectionArgs= */ null); verify(mProvider).updateAccount(ACCOUNT_ID, flagValue); } @Test public void update_forFolderUri() { - Uri folderUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_FOLDER) - .build(); - - assertThat(mProvider.update( - folderUri, /*values=*/ null, /*selection=*/ null, /*selectionArgs=*/ null)) + Uri folderUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_FOLDER) + .build(); + + assertThat( + mProvider.update( + folderUri, + /* values= */ null, + /* selection= */ null, + /* selectionArgs= */ null)) .isEqualTo(0); } @Test public void update_forConversationUri() { - Uri folderUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_CONVERSATION) - .build(); - - assertThat(mProvider.update( - folderUri, /*values=*/ null, /*selection=*/ null, /*selectionArgs=*/ null)) + Uri folderUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_CONVERSATION) + .build(); + + assertThat( + mProvider.update( + folderUri, + /* values= */ null, + /* selection= */ null, + /* selectionArgs= */ null)) .isEqualTo(0); } @Test public void update_forConvoContactUri() { - Uri folderUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_CONVOCONTACT) - .build(); - - assertThat(mProvider.update( - folderUri, /*values=*/ null, /*selection=*/ null, /*selectionArgs=*/ null)) + Uri folderUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_CONVOCONTACT) + .build(); + + assertThat( + mProvider.update( + folderUri, + /* values= */ null, + /* selection= */ null, + /* selectionArgs= */ null)) .isEqualTo(0); } @Test public void update_forMessageUri_success() { - Uri accountUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .build(); + Uri accountUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .build(); ContentValues values = new ContentValues(); final boolean flagRead = true; @@ -367,15 +440,19 @@ public class BluetoothMapIMProviderTest { values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, Long.parseLong(FOLDER_ID)); values.put(BluetoothMapContract.MessageColumns.FLAG_READ, flagRead); - mProvider.update(accountUri, values, /*selection=*/ null, /*selectionArgs=*/ null); - verify(mProvider).updateMessage( - ACCOUNT_ID, Long.parseLong(MESSAGE_ID), Long.parseLong(FOLDER_ID), flagRead); + mProvider.update(accountUri, values, /* selection= */ null, /* selectionArgs= */ null); + verify(mProvider) + .updateMessage( + ACCOUNT_ID, + Long.parseLong(MESSAGE_ID), + Long.parseLong(FOLDER_ID), + flagRead); } @Test public void call_whenMethodIsWrong() { String method = "some_random_method"; - assertThat(mProvider.call(method, /*arg=*/ null, /*extras=*/ null)).isNull(); + assertThat(mProvider.call(method, /* arg= */ null, /* extras= */ null)).isNull(); } @Test @@ -383,7 +460,9 @@ public class BluetoothMapIMProviderTest { Bundle extras = new Bundle(); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, 12345); - assertThat(mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /*arg=*/ null, extras)) + assertThat( + mProvider.call( + BluetoothMapContract.METHOD_UPDATE_FOLDER, /* arg= */ null, extras)) .isNull(); } @@ -392,7 +471,9 @@ public class BluetoothMapIMProviderTest { Bundle extras = new Bundle(); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_ACCOUNT_ID, 12345); - assertThat(mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /*arg=*/ null, extras)) + assertThat( + mProvider.call( + BluetoothMapContract.METHOD_UPDATE_FOLDER, /* arg= */ null, extras)) .isNull(); } @@ -402,7 +483,7 @@ public class BluetoothMapIMProviderTest { extras.putLong(BluetoothMapContract.EXTRA_UPDATE_ACCOUNT_ID, Long.parseLong(ACCOUNT_ID)); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, Long.parseLong(FOLDER_ID)); - mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /*arg=*/ null, extras); + mProvider.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, /* arg= */ null, extras); verify(mProvider).syncFolder(Long.parseLong(ACCOUNT_ID), Long.parseLong(FOLDER_ID)); } @@ -421,9 +502,9 @@ public class BluetoothMapIMProviderTest { extras.putInt(BluetoothMapContract.EXTRA_CHAT_STATE, chatState); extras.putString(BluetoothMapContract.EXTRA_CONVERSATION_ID, convoId); - mProvider.call(BluetoothMapContract.METHOD_SET_OWNER_STATUS, /*arg=*/ null, extras); - verify(mProvider).setOwnerStatus(presenceState, presenceStatus, lastActive, chatState, - convoId); + mProvider.call(BluetoothMapContract.METHOD_SET_OWNER_STATUS, /* arg= */ null, extras); + verify(mProvider) + .setOwnerStatus(presenceState, presenceStatus, lastActive, chatState, convoId); } @Test @@ -433,7 +514,7 @@ public class BluetoothMapIMProviderTest { Bundle extras = new Bundle(); extras.putBoolean(BluetoothMapContract.EXTRA_BLUETOOTH_STATE, state); - mProvider.call(BluetoothMapContract.METHOD_SET_BLUETOOTH_STATE, /*arg=*/ null, extras); + mProvider.call(BluetoothMapContract.METHOD_SET_BLUETOOTH_STATE, /* arg= */ null, extras); verify(mProvider).setBluetoothStatus(state); } @@ -448,22 +529,26 @@ public class BluetoothMapIMProviderTest { @Test public void getAccountId_whenNotEnoughPathSegments() { - Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .build(); + Uri uri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .build(); - assertThrows(IllegalArgumentException.class, - () -> BluetoothMapEmailProvider.getAccountId(uri)); + assertThrows( + IllegalArgumentException.class, () -> BluetoothMapEmailProvider.getAccountId(uri)); } @Test public void getAccountId_success() { - Uri messageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .appendPath(ACCOUNT_ID) - .appendPath(BluetoothMapContract.TABLE_MESSAGE) - .appendPath(MESSAGE_ID) - .build(); + Uri messageUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY) + .appendPath(ACCOUNT_ID) + .appendPath(BluetoothMapContract.TABLE_MESSAGE) + .appendPath(MESSAGE_ID) + .build(); assertThat(BluetoothMapEmailProvider.getAccountId(messageUri)).isEqualTo(ACCOUNT_ID); } @@ -508,7 +593,7 @@ public class BluetoothMapIMProviderTest { Uri expectedUri; expectedUri = BluetoothMapContract.buildConvoContactsUri(AUTHORITY); - mProvider.onContactChanged(null,null); + mProvider.onContactChanged(null, null); verify(resolver).notifyChange(expectedUri, null); Mockito.clearInvocations(resolver); @@ -519,8 +604,8 @@ public class BluetoothMapIMProviderTest { Mockito.clearInvocations(resolver); String contactId = "23623"; - expectedUri = BluetoothMapContract.buildConvoContactsUriWithId( - AUTHORITY, accountId, contactId); + expectedUri = + BluetoothMapContract.buildConvoContactsUriWithId(AUTHORITY, accountId, contactId); mProvider.onContactChanged(accountId, contactId); verify(resolver).notifyChange(expectedUri, null); } @@ -551,8 +636,7 @@ public class BluetoothMapIMProviderTest { Mockito.clearInvocations(resolver); String messageId = "23623"; - expectedUri = BluetoothMapContract.buildMessageUriWithId( - AUTHORITY, accountId, messageId); + expectedUri = BluetoothMapContract.buildMessageUriWithId(AUTHORITY, accountId, messageId); mProvider.onMessageChanged(accountId, messageId); verify(resolver).notifyChange(expectedUri, null); } @@ -581,10 +665,19 @@ public class BluetoothMapIMProviderTest { String convertedKey = "test_converted_key"; keyMap.put(key, convertedKey); - Object[] valuesToTest = new Object[] { - null, true, (byte) 0x01, new byte[] {0x01, 0x02}, - 0.01, 0.01f, 123, 12345L, (short) 10, "testString" - }; + Object[] valuesToTest = + new Object[] { + null, + true, + (byte) 0x01, + new byte[] {0x01, 0x02}, + 0.01, + 0.01f, + 123, + 12345L, + (short) 10, + "testString" + }; for (Object value : valuesToTest) { Log.d(TAG, "value=" + value); @@ -619,27 +712,42 @@ public class BluetoothMapIMProviderTest { } @Override - protected Cursor queryAccount(String[] projection, String selection, String[] selectionArgs, - String sortOrder) { + protected Cursor queryAccount( + String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override - protected Cursor queryMessage(String accountId, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { + protected Cursor queryMessage( + String accountId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder) { return null; } @Override - protected Cursor queryConversation(String accountId, Long threadId, Boolean read, - Long periodEnd, Long periodBegin, String searchString, String[] projection, + protected Cursor queryConversation( + String accountId, + Long threadId, + Boolean read, + Long periodEnd, + Long periodBegin, + String searchString, + String[] projection, String sortOrder) { return null; } @Override - protected Cursor queryConvoContact(String accountId, Long contactId, String[] projection, - String selection, String[] selectionArgs, String sortOrder) { + protected Cursor queryConvoContact( + String accountId, + Long contactId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder) { return null; } @@ -649,8 +757,8 @@ public class BluetoothMapIMProviderTest { } @Override - protected int updateMessage(String accountId, Long messageId, Long folderId, - Boolean flagRead) { + protected int updateMessage( + String accountId, Long messageId, Long folderId, Boolean flagRead) { return 0; } @@ -660,8 +768,12 @@ public class BluetoothMapIMProviderTest { } @Override - protected int setOwnerStatus(int presenceState, String presenceStatus, long lastActive, - int chatState, String convoId) { + protected int setOwnerStatus( + int presenceState, + String presenceStatus, + long lastActive, + int chatState, + String convoId) { return 0; } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java index c7d011ae3f0..2da0f14a2dc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java @@ -31,31 +31,31 @@ public class BmessageTest { private static final String TAG = BmessageTest.class.getSimpleName(); private static final String SIMPLE_MMS_MESSAGE = "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" - + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" - + "BEGIN:BBODY\r\nLENGTH:39\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" - + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:39\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" + + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; private static final String NO_END_MESSAGE = "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" - + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" - + "BEGIN:BBODY\r\nLENGTH:39\r\nBEGIN:MSG\r\nThis is a new msg\r\n"; + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:39\r\nBEGIN:MSG\r\nThis is a new msg\r\n"; private static final String WRONG_LENGTH_MESSAGE = "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" - + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" - + "BEGIN:BBODY\r\nLENGTH:200\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" - + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:200\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" + + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; private static final String NO_BODY_MESSAGE = "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" - + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" - + "BEGIN:BBODY\r\nLENGTH:\r\n"; + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:\r\n"; private static final String NEGATIVE_LENGTH_MESSAGE = "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" - + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" - + "BEGIN:BBODY\r\nLENGTH:-1\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" - + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:-1\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" + + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; @Test public void testNormalMessages() { diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java index 51ee03b870b..3c355e1ad1c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java @@ -102,8 +102,8 @@ public class EventReportTest { assertThat(report.getType()).isEqualTo(type); assertThat(report.getDateTime()).isEqualTo(dateTime); - assertThat(report.getTimestamp()).isEqualTo( - new ObexTime(dateTime).getInstant().toEpochMilli()); + assertThat(report.getTimestamp()) + .isEqualTo(new ObexTime(dateTime).getInstant().toEpochMilli()); assertThat(report.getHandle()).isEqualTo(handle); assertThat(report.getFolder()).isEqualTo(folder); assertThat(report.getOldFolder()).isEqualTo(oldFolder); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java index e731a2b2a38..48bbc7f9642 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java @@ -88,7 +88,6 @@ public class MapClientContentTest { private static final boolean MESSAGE_SEEN = true; private static final boolean MESSAGE_NOT_SEEN = false; - private VCardEntry mOriginator; private ArgumentCaptor mUriArgument = ArgumentCaptor.forClass(Uri.class); @@ -97,26 +96,19 @@ public class MapClientContentTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AdapterService mAdapterService; - @Mock - private DatabaseManager mDatabaseManager; - @Mock - private MapClientService mMockMapClientService; - @Mock - private Context mMockContext; - @Mock - private MapClientContent.Callbacks mCallbacks; + @Mock private AdapterService mAdapterService; + @Mock private DatabaseManager mDatabaseManager; + @Mock private MapClientService mMockMapClientService; + @Mock private Context mMockContext; + @Mock private MapClientContent.Callbacks mCallbacks; private MockContentResolver mMockContentResolver; private FakeContentProvider mMockSmsContentProvider; private FakeContentProvider mMockMmsContentProvider; private FakeContentProvider mMockThreadContentProvider; - @Mock - private SubscriptionManager mMockSubscriptionManager; - @Mock - private SubscriptionInfo mMockSubscription; + @Mock private SubscriptionManager mMockSubscriptionManager; + @Mock private SubscriptionInfo mMockSubscription; @Before public void setUp() throws Exception { @@ -144,49 +136,54 @@ public class MapClientContentTest { } @After - public void tearDown() throws Exception { - } + public void tearDown() throws Exception {} - /** - * Test that everything initializes correctly with an empty content provider - */ + /** Test that everything initializes correctly with an empty content provider */ @Test public void testCreateMapClientContent() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(0, mMockSmsContentProvider.mContentValues.size()); } - /** - * Test that a dirty database gets cleaned at startup. - */ + /** Test that a dirty database gets cleaned at startup. */ @Test public void testCleanDirtyDatabase() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockSmsContentProvider.mContentValues.size()); mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); Assert.assertEquals(0, mMockSmsContentProvider.mContentValues.size()); } - /** - * Test inserting 2 SMS messages and then clearing out the database. - */ + /** Test inserting 2 SMS messages and then clearing out the database. */ @Test public void testStoreTwoSMS() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockSmsContentProvider.mContentValues.size()); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); Assert.assertEquals(2, mMockSmsContentProvider.mContentValues.size()); Assert.assertEquals(0, mMockMmsContentProvider.mContentValues.size()); @@ -195,60 +192,66 @@ public class MapClientContentTest { Assert.assertEquals(0, mMockThreadContentProvider.mContentValues.size()); } - /** - * Test inserting 2 MMS messages and then clearing out the database. - */ + /** Test inserting 2 MMS messages and then clearing out the database. */ @Test public void testStoreTwoMMS() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockMmsContentProvider.mContentValues.size()); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); Assert.assertEquals(2, mMockMmsContentProvider.mContentValues.size()); mMapClientContent.cleanUp(); Assert.assertEquals(0, mMockMmsContentProvider.mContentValues.size()); } - /** - * Test that SMS and MMS messages end up in their respective databases. - */ + /** Test that SMS and MMS messages end up in their respective databases. */ @Test public void testStoreOneSMSOneMMS() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockMmsContentProvider.mContentValues.size()); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage2Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage2Handle, mTestMessage1Timestamp, MESSAGE_SEEN); Assert.assertEquals(2, mMockMmsContentProvider.mContentValues.size()); mMapClientContent.cleanUp(); Assert.assertEquals(0, mMockMmsContentProvider.mContentValues.size()); } - /** - * Test read status changed - */ + /** Test read status changed */ @Test public void testReadStatusChanged() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockMmsContentProvider.mContentValues.size()); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); Assert.assertEquals(2, mMockMmsContentProvider.mContentValues.size()); mMapClientContent.markRead(mTestMessage1Handle); @@ -260,102 +263,94 @@ public class MapClientContentTest { /** * Test read status changed in local provider * - * Insert a message, and notify the observer about a change - * The cursor is configured to return messages marked as read - * Verify that the local change is observed and propagated to the remote + *

Insert a message, and notify the observer about a change The cursor is configured to + * return messages marked as read Verify that the local change is observed and propagated to the + * remote */ @Test public void testLocalReadStatusChanged() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); Assert.assertEquals(1, mMockMmsContentProvider.mContentValues.size()); mMapClientContent.mContentObserver.onChange(false); - verify(mCallbacks).onMessageStatusChanged(eq(mTestMessage1Handle), - eq(BluetoothMapClient.READ)); + verify(mCallbacks) + .onMessageStatusChanged(eq(mTestMessage1Handle), eq(BluetoothMapClient.READ)); } - /** - * Test if seen status is set to true in database for SMS - */ - @Test - public void testStoreSmsMessageWithSeenTrue_smsWrittenWithSeenTrue() { + /** Test if seen status is set to true in database for SMS */ + @Test + public void testStoreSmsMessageWithSeenTrue_smsWrittenWithSeenTrue() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); assertThat(mMockSmsContentProvider.mContentValues.size()).isEqualTo(1); ContentValues storedSMS = (ContentValues) mMockSmsContentProvider.mContentValues.values().toArray()[0]; assertThat(storedSMS.get(Sms.SEEN)).isEqualTo(MESSAGE_SEEN); + } - } - - /** - * Test if seen status is set to false in database for SMS - */ - @Test - public void testStoreSmsMessageWithSeenFalse_smsWrittenWithSeenFalse() { + /** Test if seen status is set to false in database for SMS */ + @Test + public void testStoreSmsMessageWithSeenFalse_smsWrittenWithSeenFalse() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_NOT_SEEN); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_NOT_SEEN); assertThat(mMockSmsContentProvider.mContentValues.size()).isEqualTo(1); ContentValues storedSMS = (ContentValues) mMockSmsContentProvider.mContentValues.values().toArray()[0]; assertThat(storedSMS.get(Sms.SEEN)).isEqualTo(MESSAGE_NOT_SEEN); + } - } - - /** - * Test if seen status is set to true in database for MMS - */ - @Test - public void testStoreMmsMessageWithSeenTrue_mmsWrittenWithSeenTrue() { + /** Test if seen status is set to true in database for MMS */ + @Test + public void testStoreMmsMessageWithSeenTrue_mmsWrittenWithSeenTrue() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); assertThat(mMockMmsContentProvider.mContentValues.size()).isEqualTo(1); ContentValues storedMMS = (ContentValues) mMockMmsContentProvider.mContentValues.values().toArray()[0]; assertThat(storedMMS.get(Mms.SEEN)).isEqualTo(MESSAGE_SEEN); + } - } - - /** - * Test if seen status is set to false in database for MMS - */ - @Test - public void testStoreMmsMessageWithSeenFalse_mmsWrittenWithSeenFalse() { + /** Test if seen status is set to false in database for MMS */ + @Test + public void testStoreMmsMessageWithSeenFalse_mmsWrittenWithSeenFalse() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_NOT_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_NOT_SEEN); assertThat(mMockMmsContentProvider.mContentValues.size()).isEqualTo(1); ContentValues storedMMS = (ContentValues) mMockMmsContentProvider.mContentValues.values().toArray()[0]; assertThat(storedMMS.get(Mms.SEEN)).isEqualTo(MESSAGE_NOT_SEEN); - - } + } /** * Test remote message deleted * - * Add a message to the database Simulate the message getting - * deleted on the phone Verify that the message is deleted locally + *

Add a message to the database Simulate the message getting deleted on the phone Verify + * that the message is deleted locally */ @Test public void testMessageDeleted() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockSmsContentProvider.mContentValues.size()); // attempt to delete an invalid handle, nothing should be removed. mMapClientContent.deleteMessage(mTestMessage2Handle); @@ -369,32 +364,34 @@ public class MapClientContentTest { /** * Test read status changed in local provider * - * Insert a message, manually remove it and notify the observer about a change - * Verify that the local change is observed and propagated to the remote + *

Insert a message, manually remove it and notify the observer about a change Verify that + * the local change is observed and propagated to the remote */ @Test public void testLocalMessageDeleted() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); - verify(mMockSubscriptionManager).addSubscriptionInfoRecord(any(), any(), anyInt(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); + verify(mMockSubscriptionManager) + .addSubscriptionInfoRecord( + any(), + any(), + anyInt(), + eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); Assert.assertEquals(1, mMockSmsContentProvider.mContentValues.size()); mMockSmsContentProvider.mContentValues.clear(); mMapClientContent.mContentObserver.onChange(false); - verify(mCallbacks).onMessageStatusChanged(eq(mTestMessage1Handle), - eq(BluetoothMapClient.DELETED)); + verify(mCallbacks) + .onMessageStatusChanged(eq(mTestMessage1Handle), eq(BluetoothMapClient.DELETED)); } /** - * Preconditions: - * - Create new {@link MapClientContent}, own phone number not initialized yet. + * Preconditions: - Create new {@link MapClientContent}, own phone number not initialized yet. * - * Actions: - * - Invoke {@link MapClientContent#setRemoteDeviceOwnNumber} with a non-null number. + *

Actions: - Invoke {@link MapClientContent#setRemoteDeviceOwnNumber} with a non-null + * number. * - * Outcome: - * - {@link MapClientContent#mPhoneNumber} should now store the number. + *

Outcome: - {@link MapClientContent#mPhoneNumber} should now store the number. */ @Test public void testSetRemoteDeviceOwnNumber() { @@ -407,9 +404,7 @@ public class MapClientContentTest { assertThat(mMapClientContent.mPhoneNumber).isEqualTo(testNumber); } - /** - * Test to validate that some poorly formatted messages don't crash. - */ + /** Test to validate that some poorly formatted messages don't crash. */ @Test public void testStoreBadMessage() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); @@ -417,15 +412,15 @@ public class MapClientContentTest { mTestMessage1.setBodyContent("HelloWorld"); mTestMessage1.setType(Bmessage.Type.SMS_GSM); mTestMessage1.setFolder("telecom/msg/sent"); - mMapClientContent.storeMessage(mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage1, mTestMessage1Handle, mTestMessage1Timestamp, MESSAGE_SEEN); mTestMessage2 = new Bmessage(); mTestMessage2.setBodyContent("HelloWorld"); mTestMessage2.setType(Bmessage.Type.MMS); mTestMessage2.setFolder("telecom/msg/inbox"); - mMapClientContent.storeMessage(mTestMessage2, mTestMessage2Handle, mTestMessage1Timestamp, - MESSAGE_SEEN); + mMapClientContent.storeMessage( + mTestMessage2, mTestMessage2Handle, mTestMessage1Timestamp, MESSAGE_SEEN); } /** @@ -435,14 +430,13 @@ public class MapClientContentTest { @Test public void testCleanUpRemoteException() { mMapClientContent = new MapClientContent(mMockContext, mCallbacks, mTestDevice); - doThrow(java.lang.NullPointerException.class).when(mMockSubscriptionManager) + doThrow(java.lang.NullPointerException.class) + .when(mMockSubscriptionManager) .removeSubscriptionInfoRecord(any(), anyInt()); mMapClientContent.cleanUp(); } - /** - * Test to validate old subscriptions are removed at startup. - */ + /** Test to validate old subscriptions are removed at startup. */ @Test public void testCleanUpAtStartup() { MapClientContent.clearAllContent(mMockContext); @@ -451,17 +445,15 @@ public class MapClientContentTest { when(mMockSubscription.getSubscriptionType()) .thenReturn(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); MapClientContent.clearAllContent(mMockContext); - verify(mMockSubscriptionManager).removeSubscriptionInfoRecord(any(), - eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); + verify(mMockSubscriptionManager) + .removeSubscriptionInfoRecord( + any(), eq(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)); } - /** - * Test to validate that cleaning content does not crash when no subscription are available. - */ + /** Test to validate that cleaning content does not crash when no subscription are available. */ @Test public void testCleanUpWithNoSubscriptions() { - when(mMockSubscriptionManager.getActiveSubscriptionInfoList()) - .thenReturn(null); + when(mMockSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null); MapClientContent.clearAllContent(mMockContext); } @@ -547,6 +539,7 @@ public class MapClientContentTest { public class FakeContentProvider extends MockContentProvider { Map mContentValues = new HashMap<>(); + FakeContentProvider(Context context) { super(context); } @@ -567,7 +560,7 @@ public class MapClientContentTest { Log.i(TAG, "URI = " + uri); if (uri.equals(Mms.Inbox.CONTENT_URI)) uri = Mms.CONTENT_URI; Uri returnUri = Uri.withAppendedPath(uri, String.valueOf(mContentValues.size() + 1)); - //only store top level message parts + // only store top level message parts if (uri.equals(Sms.Inbox.CONTENT_URI) || uri.equals(Mms.CONTENT_URI)) { Log.i(TAG, "adding content" + values); mContentValues.put(returnUri, values); @@ -577,7 +570,11 @@ public class MapClientContentTest { } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { Cursor cursor = Mockito.mock(Cursor.class); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java index e9e4fb7014b..01c5d0c26bc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java @@ -15,7 +15,6 @@ */ package com.android.bluetooth.mapclient; - import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothAdapter; @@ -41,8 +40,7 @@ public class MapClientServiceBinderTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private MapClientService mService; + @Mock private MapClientService mService; BluetoothDevice mRemoteDevice; @@ -141,4 +139,4 @@ public class MapClientServiceBinderTest { public void cleanUp_doesNotCrash() { mBinder.cleanup(); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java index c24df8b84d3..b327a6b5f70 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java @@ -123,7 +123,8 @@ public class MapClientServiceTest { public void setConnectionPolicy() { int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN; when(mDatabaseManager.setProfileConnectionPolicy( - mRemoteDevice, BluetoothProfile.MAP_CLIENT, connectionPolicy)).thenReturn(true); + mRemoteDevice, BluetoothProfile.MAP_CLIENT, connectionPolicy)) + .thenReturn(true); assertThat(mService.setConnectionPolicy(mRemoteDevice, connectionPolicy)).isTrue(); } @@ -132,7 +133,8 @@ public class MapClientServiceTest { public void getConnectionPolicy() { int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED; when(mDatabaseManager.getProfileConnectionPolicy( - mRemoteDevice, BluetoothProfile.MAP_CLIENT)).thenReturn(connectionPolicy); + mRemoteDevice, BluetoothProfile.MAP_CLIENT)) + .thenReturn(connectionPolicy); assertThat(mService.getConnectionPolicy(mRemoteDevice)).isEqualTo(connectionPolicy); } @@ -141,7 +143,8 @@ public class MapClientServiceTest { public void connect_whenPolicyIsForbidden_returnsFalse() { int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; when(mDatabaseManager.getProfileConnectionPolicy( - mRemoteDevice, BluetoothProfile.MAP_CLIENT)).thenReturn(connectionPolicy); + mRemoteDevice, BluetoothProfile.MAP_CLIENT)) + .thenReturn(connectionPolicy); assertThat(mService.connect(mRemoteDevice)).isFalse(); } @@ -150,7 +153,8 @@ public class MapClientServiceTest { public void connect_whenPolicyIsAllowed_returnsTrue() { int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED; when(mDatabaseManager.getProfileConnectionPolicy( - mRemoteDevice, BluetoothProfile.MAP_CLIENT)).thenReturn(connectionPolicy); + mRemoteDevice, BluetoothProfile.MAP_CLIENT)) + .thenReturn(connectionPolicy); assertThat(mService.connect(mRemoteDevice)).isTrue(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java index 2c18e366ff5..d7145d1e588 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java @@ -16,7 +16,6 @@ package com.android.bluetooth.mapclient; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; @@ -118,8 +117,7 @@ public class MapClientStateMachineTest { private VCardEntry mOriginator; - @Rule - public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); private BluetoothAdapter mAdapter; private MceStateMachine mMceStateMachine = null; private BluetoothDevice mTestDevice; @@ -128,43 +126,31 @@ public class MapClientStateMachineTest { private ArgumentCaptor mIntentArgument = ArgumentCaptor.forClass(Intent.class); @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AdapterService mAdapterService; - @Mock - private DatabaseManager mDatabaseManager; - @Mock - private MapClientService mMockMapClientService; - @Mock - private MapClientContent mMockDatabase; + @Mock private AdapterService mAdapterService; + @Mock private DatabaseManager mDatabaseManager; + @Mock private MapClientService mMockMapClientService; + @Mock private MapClientContent mMockDatabase; private MockContentResolver mMockContentResolver; private MockSmsContentProvider mMockContentProvider; - @Mock - private TelephonyManager mMockTelephonyManager; + @Mock private TelephonyManager mMockTelephonyManager; - @Mock - private MasClient mMockMasClient; + @Mock private MasClient mMockMasClient; - @Mock - private RequestPushMessage mMockRequestPushMessage; + @Mock private RequestPushMessage mMockRequestPushMessage; - @Mock - private SubscriptionManager mMockSubscriptionManager; + @Mock private SubscriptionManager mMockSubscriptionManager; private static final String TEST_OWN_PHONE_NUMBER = "555-1234"; - @Mock - private RequestGetMessagesListingForOwnNumber mMockRequestOwnNumberCompletedWithNumber; - @Mock - private RequestGetMessagesListingForOwnNumber mMockRequestOwnNumberIncompleteSearch; - @Mock - private RequestGetMessage mMockRequestGetMessage; - @Mock - private RequestGetMessagesListing mMockRequestGetMessagesListing; + @Mock private RequestGetMessagesListingForOwnNumber mMockRequestOwnNumberCompletedWithNumber; + @Mock private RequestGetMessagesListingForOwnNumber mMockRequestOwnNumberIncompleteSearch; + @Mock private RequestGetMessage mMockRequestGetMessage; + @Mock private RequestGetMessagesListing mMockRequestGetMessagesListing; private static final Correspondence GET_FOLDER_NAME = Correspondence.transforming( - MapClientStateMachineTest::getFolderNameFromRequestGetMessagesListing, - "has folder name of"); + MapClientStateMachineTest::getFolderNameFromRequestGetMessagesListing, + "has folder name of"); private static final String ACTION_MESSAGE_SENT = "com.android.bluetooth.mapclient.MapClientStateMachineTest.action.MESSAGE_SENT"; @@ -229,8 +215,9 @@ public class MapClientStateMachineTest { mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); when(mMockMasClient.makeRequest(any(Request.class))).thenReturn(true); - mMceStateMachine = new MceStateMachine(mMockMapClientService, mTestDevice, mMockMasClient, - mMockDatabase); + mMceStateMachine = + new MceStateMachine( + mMockMapClientService, mTestDevice, mMockMasClient, mMockDatabase); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertNotNull(mMceStateMachine); if (Looper.myLooper() == null) { @@ -239,8 +226,8 @@ public class MapClientStateMachineTest { mHandler = new Handler(); when(mMockRequestOwnNumberCompletedWithNumber.isSearchCompleted()).thenReturn(true); - when(mMockRequestOwnNumberCompletedWithNumber.getOwnNumber()).thenReturn( - TEST_OWN_PHONE_NUMBER); + when(mMockRequestOwnNumberCompletedWithNumber.getOwnNumber()) + .thenReturn(TEST_OWN_PHONE_NUMBER); when(mMockRequestOwnNumberIncompleteSearch.isSearchCompleted()).thenReturn(false); when(mMockRequestOwnNumberIncompleteSearch.getOwnNumber()).thenReturn(null); @@ -249,8 +236,8 @@ public class MapClientStateMachineTest { when(mMockRequestGetMessage.getMessage()).thenReturn(mTestIncomingSmsBmessage); when(mMockRequestGetMessage.getHandle()).thenReturn(mTestMessageSmsHandle); - when(mMockMapClientService.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn( - mMockTelephonyManager); + when(mMockMapClientService.getSystemService(Context.TELEPHONY_SERVICE)) + .thenReturn(mMockTelephonyManager); when(mMockTelephonyManager.isSmsCapable()).thenReturn(false); // Set up receiver for 'Sent' and 'Delivered' PendingIntents @@ -274,9 +261,7 @@ public class MapClientStateMachineTest { mTargetContext.unregisterReceiver(mSentDeliveryReceiver); } - /** - * Test that default state is STATE_CONNECTING - */ + /** Test that default state is STATE_CONNECTING */ @Test public void testDefaultConnectingState() { Log.i(TAG, "in testDefaultConnectingState"); @@ -297,16 +282,15 @@ public class MapClientStateMachineTest { // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_DISCONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); } - /** - * Test transition from STATE_CONNECTING --> (receive MSG_MAS_CONNECTED) --> STATE_CONNECTED - */ + /** Test transition from STATE_CONNECTING --> (receive MSG_MAS_CONNECTED) --> STATE_CONNECTED */ @Test public void testStateTransitionFromConnectingToConnected() { Log.i(TAG, "in testStateTransitionFromConnectingToConnected"); @@ -318,10 +302,11 @@ public class MapClientStateMachineTest { // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_CONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); } @@ -340,25 +325,25 @@ public class MapClientStateMachineTest { // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_CONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_DISCONNECTED); mMceStateMachine.sendMessage(msg); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(4)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(4)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); } - /** - * Test receiving an empty event report - */ + /** Test receiving an empty event report */ @Test public void testReceiveEmptyEvent() { setupSdpRecordReceipt(); @@ -368,10 +353,11 @@ public class MapClientStateMachineTest { // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_CONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); // Send an empty notification event, verify the mMceStateMachine is still connected @@ -380,9 +366,7 @@ public class MapClientStateMachineTest { Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); } - /** - * Test set message status - */ + /** Test set message status */ @Test public void testSetMessageStatus() { setupSdpRecordReceipt(); @@ -392,48 +376,50 @@ public class MapClientStateMachineTest { // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_CONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); Assert.assertTrue( mMceStateMachine.setMessageStatus("123456789AB", BluetoothMapClient.READ)); } - /** - * Test disconnect - */ + /** Test disconnect */ @Test public void testDisconnect() { setupSdpRecordReceipt(); - doAnswer(invocation -> { - mMceStateMachine.sendMessage(MceStateMachine.MSG_MAS_DISCONNECTED); - return null; - }).when(mMockMasClient).shutdown(); + doAnswer( + invocation -> { + mMceStateMachine.sendMessage(MceStateMachine.MSG_MAS_DISCONNECTED); + return null; + }) + .when(mMockMasClient) + .shutdown(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_CONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); mMceStateMachine.disconnect(); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(4)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(4)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); } - /** - * Test disconnect timeout - */ + /** Test disconnect timeout */ @Test public void testDisconnectTimeout() { setupSdpRecordReceipt(); @@ -443,29 +429,30 @@ public class MapClientStateMachineTest { // Wait until the message is processed and a broadcast request is sent to // to MapClientService to change // state from STATE_CONNECTING to STATE_CONNECTED - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); mMceStateMachine.disconnect(); - verify(mMockMapClientService, - after(DISCONNECT_TIMEOUT / 2).times(3)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, after(DISCONNECT_TIMEOUT / 2).times(3)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, mMceStateMachine.getState()); - verify(mMockMapClientService, - timeout(DISCONNECT_TIMEOUT).times(4)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(DISCONNECT_TIMEOUT).times(4)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); } - /** - * Test sending a message to a phone - */ + /** Test sending a message to a phone */ @Test public void testSendSMSMessageToPhone() { setupSdpRecordReceipt(); @@ -483,9 +470,7 @@ public class MapClientStateMachineTest { .makeRequest(any(RequestPushMessage.class)); } - /** - * Test sending a message to an email - */ + /** Test sending a message to an email */ @Test public void testSendSMSMessageToEmail() { setupSdpRecordReceipt(); @@ -503,9 +488,7 @@ public class MapClientStateMachineTest { .makeRequest(any(RequestPushMessage.class)); } - /** - * Test message sent successfully - */ + /** Test message sent successfully */ @Test public void testSMSMessageSent() { setupSdpRecordReceipt(); @@ -518,40 +501,46 @@ public class MapClientStateMachineTest { new RequestPushMessage(FOLDER_SENT, mTestIncomingSmsBmessage, null, false, false); when(mMockRequestPushMessage.getMsgHandle()).thenReturn(mTestMessageSmsHandle); when(mMockRequestPushMessage.getBMsg()).thenReturn(mTestIncomingSmsBmessage); - Message msgSent = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestPushMessage); + Message msgSent = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestPushMessage); mMceStateMachine.sendMessage(msgSent); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); - verify(mMockDatabase, times(1)).storeMessage(eq(mTestIncomingSmsBmessage), - eq(mTestMessageSmsHandle), any(), eq(MESSAGE_SEEN)); + verify(mMockDatabase, times(1)) + .storeMessage( + eq(mTestIncomingSmsBmessage), + eq(mTestMessageSmsHandle), + any(), + eq(MESSAGE_SEEN)); } /** - * Preconditions: - * - In {@code STATE_CONNECTED}. - * - {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT} has been set. - * - Next stage of connection process has NOT begun, i.e.: - * - Request for Notification Registration not sent - * - Request for MessageListing of SENT folder not sent - * - Request for MessageListing of INBOX folder not sent + * Preconditions: - In {@code STATE_CONNECTED}. - {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT} has been + * set. - Next stage of connection process has NOT begun, i.e.: - Request for Notification + * Registration not sent - Request for MessageListing of SENT folder not sent - Request for + * MessageListing of INBOX folder not sent */ private void testGetOwnNumber_setup() { testStateTransitionFromConnectingToConnected(); - verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS).never()).makeRequest( - any(RequestSetNotificationRegistration.class)); + verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS).never()) + .makeRequest(any(RequestSetNotificationRegistration.class)); verify(mMockMasClient, never()).makeRequest(any(RequestGetMessagesListing.class)); - assertThat(mMceStateMachine.getHandler().hasMessages( - MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT)).isTrue(); + assertThat( + mMceStateMachine + .getHandler() + .hasMessages(MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT)) + .isTrue(); } /** * Assert whether the next stage of connection process has begun, i.e., whether the following - * {@link Request} are sent or not: - * - Request for Notification Registration, - * - Request for MessageListing of SENT folder (to start downloading), - * - Request for MessageListing of INBOX folder (to start downloading). + * {@link Request} are sent or not: - Request for Notification Registration, - Request for + * MessageListing of SENT folder (to start downloading), - Request for MessageListing of INBOX + * folder (to start downloading). */ private void testGetOwnNumber_assertNextStageStarted(boolean hasStarted) { if (hasStarted) { @@ -564,167 +553,187 @@ public class MapClientStateMachineTest { // {@link Request} subtypes; not all of them will be {@link // RequestGetMessagesListing}. List capturedRequests = requestCaptor.getAllValues(); - assertThat(capturedRequests).comparingElementsUsing(GET_FOLDER_NAME).contains( - MceStateMachine.FOLDER_INBOX); - assertThat(capturedRequests).comparingElementsUsing(GET_FOLDER_NAME).contains( - MceStateMachine.FOLDER_SENT); + assertThat(capturedRequests) + .comparingElementsUsing(GET_FOLDER_NAME) + .contains(MceStateMachine.FOLDER_INBOX); + assertThat(capturedRequests) + .comparingElementsUsing(GET_FOLDER_NAME) + .contains(MceStateMachine.FOLDER_SENT); } else { - verify(mMockMasClient, never()).makeRequest( - any(RequestSetNotificationRegistration.class)); + verify(mMockMasClient, never()) + .makeRequest(any(RequestSetNotificationRegistration.class)); verify(mMockMasClient, never()).makeRequest(any(RequestGetMessagesListing.class)); } } /** - * Preconditions: - * - See {@link testGetOwnNumber_setup}. + * Preconditions: - See {@link testGetOwnNumber_setup}. * - * Actions: - * - Send a {@code MSG_MAS_REQUEST_COMPLETED} with a {@link - * RequestGetMessagesListingForOwnNumber} object that has completed its search. + *

Actions: - Send a {@code MSG_MAS_REQUEST_COMPLETED} with a {@link + * RequestGetMessagesListingForOwnNumber} object that has completed its search. * - * Outcome: - * - {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT} has been cancelled. - * - Next stage of connection process has begun, i.e.: - * - Request for Notification Registration is made. - * - Request for MessageListing of SENT folder is made (to start downloading). - * - Request for MessageListing of INBOX folder is made (to start downloading). + *

Outcome: - {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT} has been cancelled. - Next stage of + * connection process has begun, i.e.: - Request for Notification Registration is made. - + * Request for MessageListing of SENT folder is made (to start downloading). - Request for + * MessageListing of INBOX folder is made (to start downloading). */ @Test public void testGetOwnNumberCompleted() { testGetOwnNumber_setup(); - Message requestCompletedMsg = Message.obtain(mHandler, - MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestOwnNumberCompletedWithNumber); + Message requestCompletedMsg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestOwnNumberCompletedWithNumber); mMceStateMachine.sendMessage(requestCompletedMsg); - verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS).never()).makeRequest( - eq(mMockRequestOwnNumberCompletedWithNumber)); - assertThat(mMceStateMachine.getHandler().hasMessages( - MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT)).isFalse(); + verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS).never()) + .makeRequest(eq(mMockRequestOwnNumberCompletedWithNumber)); + assertThat( + mMceStateMachine + .getHandler() + .hasMessages(MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT)) + .isFalse(); testGetOwnNumber_assertNextStageStarted(true); } /** - * Preconditions: - * - See {@link testGetOwnNumber_setup}. + * Preconditions: - See {@link testGetOwnNumber_setup}. * - * Actions: - * - Send a {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT}. + *

Actions: - Send a {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT}. * - * Outcome: - * - {@link MasClient#abortRequest} invoked on a {@link RequestGetMessagesListingForOwnNumber}. - * - Any existing {@code MSG_MAS_REQUEST_COMPLETED} (corresponding to a - * {@link RequestGetMessagesListingForOwnNumber}) has been dropped. - * - Next stage of connection process has begun, i.e.: - * - Request for Notification Registration is made. - * - Request for MessageListing of SENT folder is made (to start downloading). - * - Request for MessageListing of INBOX folder is made (to start downloading). + *

Outcome: - {@link MasClient#abortRequest} invoked on a {@link + * RequestGetMessagesListingForOwnNumber}. - Any existing {@code MSG_MAS_REQUEST_COMPLETED} + * (corresponding to a {@link RequestGetMessagesListingForOwnNumber}) has been dropped. - Next + * stage of connection process has begun, i.e.: - Request for Notification Registration is made. + * - Request for MessageListing of SENT folder is made (to start downloading). - Request for + * MessageListing of INBOX folder is made (to start downloading). */ @Test public void testGetOwnNumberTimedOut() { testGetOwnNumber_setup(); - Message timeoutMsg = Message.obtain(mHandler, - MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT, - mMockRequestOwnNumberIncompleteSearch); + Message timeoutMsg = + Message.obtain( + mHandler, + MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT, + mMockRequestOwnNumberIncompleteSearch); mMceStateMachine.sendMessage(timeoutMsg); - verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS)).abortRequest( - mMockRequestOwnNumberIncompleteSearch); - assertThat(mMceStateMachine.getHandler().hasMessages( - MceStateMachine.MSG_MAS_REQUEST_COMPLETED)).isFalse(); + verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS)) + .abortRequest(mMockRequestOwnNumberIncompleteSearch); + assertThat( + mMceStateMachine + .getHandler() + .hasMessages(MceStateMachine.MSG_MAS_REQUEST_COMPLETED)) + .isFalse(); testGetOwnNumber_assertNextStageStarted(true); } /** - * Preconditions: - * - See {@link testGetOwnNumber_setup}. + * Preconditions: - See {@link testGetOwnNumber_setup}. * - * Actions: - * - Send a {@code MSG_MAS_REQUEST_COMPLETED} with a {@link - * RequestGetMessagesListingForOwnNumber} object that has not completed its search. + *

Actions: - Send a {@code MSG_MAS_REQUEST_COMPLETED} with a {@link + * RequestGetMessagesListingForOwnNumber} object that has not completed its search. * - * Outcome: - * - {@link Request} made to continue searching for own number (using existing/same - * {@link Request}). - * - {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT} has not been cancelled. - * - Next stage of connection process has not begun, i.e.: - * - No Request for Notification Registration, - * - No Request for MessageListing of SENT folder is made (to start downloading), - * - No Request for MessageListing of INBOX folder is made (to start downloading). + *

Outcome: - {@link Request} made to continue searching for own number (using existing/same + * {@link Request}). - {@code MSG_SEARCH_OWN_NUMBER_TIMEOUT} has not been cancelled. - Next + * stage of connection process has not begun, i.e.: - No Request for Notification Registration, + * - No Request for MessageListing of SENT folder is made (to start downloading), - No Request + * for MessageListing of INBOX folder is made (to start downloading). */ @Test public void testGetOwnNumberIncomplete() { testGetOwnNumber_setup(); - Message requestIncompleteMsg = Message.obtain(mHandler, - MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestOwnNumberIncompleteSearch); + Message requestIncompleteMsg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestOwnNumberIncompleteSearch); mMceStateMachine.sendMessage(requestIncompleteMsg); - verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS)).makeRequest( - eq(mMockRequestOwnNumberIncompleteSearch)); - assertThat(mMceStateMachine.getHandler().hasMessages( - MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT)).isTrue(); + verify(mMockMasClient, after(ASYNC_CALL_TIMEOUT_MILLIS)) + .makeRequest(eq(mMockRequestOwnNumberIncompleteSearch)); + assertThat( + mMceStateMachine + .getHandler() + .hasMessages(MceStateMachine.MSG_SEARCH_OWN_NUMBER_TIMEOUT)) + .isTrue(); testGetOwnNumber_assertNextStageStarted(false); } - /** - * Test seen status set for new SMS - */ - @Test - public void testReceivedNewSms_messageStoredAsUnseen() { + /** Test seen status set for new SMS */ + @Test + public void testReceivedNewSms_messageStoredAsUnseen() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); - //verifying that state machine is in the Connected state - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + // verifying that state machine is in the Connected state + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); String dateTime = new ObexTime(Instant.now()).toString(); - EventReport event = createNewEventReport("NewMessage", dateTime, mTestMessageSmsHandle, - "telecom/msg/inbox", null, "SMS_GSM"); + EventReport event = + createNewEventReport( + "NewMessage", + dateTime, + mTestMessageSmsHandle, + "telecom/msg/inbox", + null, + "SMS_GSM"); mMceStateMachine.receiveEvent(event); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest - (any(RequestGetMessage.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessage.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessage); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessage); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockDatabase, times(1)).storeMessage(eq(mTestIncomingSmsBmessage), - eq(mTestMessageSmsHandle), any(), eq(MESSAGE_NOT_SEEN)); - } + verify(mMockDatabase, times(1)) + .storeMessage( + eq(mTestIncomingSmsBmessage), + eq(mTestMessageSmsHandle), + any(), + eq(MESSAGE_NOT_SEEN)); + } - /** - * Test seen status set for new MMS - */ - @Test - public void testReceivedNewMms_messageStoredAsUnseen() { + /** Test seen status set for new MMS */ + @Test + public void testReceivedNewMms_messageStoredAsUnseen() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); - //verifying that state machine is in the Connected state - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + // verifying that state machine is in the Connected state + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); String dateTime = new ObexTime(Instant.now()).toString(); - EventReport event = createNewEventReport("NewMessage", dateTime, mTestMessageMmsHandle, - "telecom/msg/inbox", null, "MMS"); + EventReport event = + createNewEventReport( + "NewMessage", + dateTime, + mTestMessageMmsHandle, + "telecom/msg/inbox", + null, + "MMS"); when(mMockRequestGetMessage.getMessage()).thenReturn(mTestIncomingMmsBmessage); when(mMockRequestGetMessage.getHandle()).thenReturn(mTestMessageMmsHandle); @@ -732,81 +741,91 @@ public class MapClientStateMachineTest { mMceStateMachine.receiveEvent(event); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest - (any(RequestGetMessage.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessage.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessage); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessage); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockDatabase, times(1)).storeMessage(eq(mTestIncomingMmsBmessage), - eq(mTestMessageMmsHandle), any(), eq(MESSAGE_NOT_SEEN)); - } + verify(mMockDatabase, times(1)) + .storeMessage( + eq(mTestIncomingMmsBmessage), + eq(mTestMessageMmsHandle), + any(), + eq(MESSAGE_NOT_SEEN)); + } - /** - * Test seen status set in database on initial download - */ - @Test - public void testDownloadExistingSms_messageStoredAsSeen() { + /** Test seen status set in database on initial download */ + @Test + public void testDownloadExistingSms_messageStoredAsSeen() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); - com.android.bluetooth.mapclient.Message testMessageListingSms = createNewMessage("SMS_GSM", - mTestMessageSmsHandle); + com.android.bluetooth.mapclient.Message testMessageListingSms = + createNewMessage("SMS_GSM", mTestMessageSmsHandle); ArrayList messageListSms = new ArrayList<>(); messageListSms.add(testMessageListingSms); when(mMockRequestGetMessagesListing.getList()).thenReturn(messageListSms); - msg = Message.obtain(mHandler, MceStateMachine.MSG_GET_MESSAGE_LISTING, - MceStateMachine.FOLDER_INBOX); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_GET_MESSAGE_LISTING, + MceStateMachine.FOLDER_INBOX); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest(any( - RequestGetMessagesListing.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessagesListing.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessagesListing); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessagesListing); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest(any( - RequestGetMessage.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessage.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessage); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessage); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockDatabase, times(1)).storeMessage(any(), any(), - any(), eq(MESSAGE_SEEN)); - } + verify(mMockDatabase, times(1)).storeMessage(any(), any(), any(), eq(MESSAGE_SEEN)); + } - /** - * Test seen status set in database on initial download - */ - @Test - public void testDownloadExistingMms_messageStoredAsSeen() { + /** Test seen status set in database on initial download */ + @Test + public void testDownloadExistingMms_messageStoredAsSeen() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); - com.android.bluetooth.mapclient.Message testMessageListingMms = createNewMessage("MMS", - mTestMessageMmsHandle); + com.android.bluetooth.mapclient.Message testMessageListingMms = + createNewMessage("MMS", mTestMessageMmsHandle); ArrayList messageListMms = new ArrayList<>(); messageListMms.add(testMessageListingMms); @@ -814,59 +833,69 @@ public class MapClientStateMachineTest { when(mMockRequestGetMessage.getHandle()).thenReturn(mTestMessageMmsHandle); when(mMockRequestGetMessagesListing.getList()).thenReturn(messageListMms); - msg = Message.obtain(mHandler, MceStateMachine.MSG_GET_MESSAGE_LISTING, - MceStateMachine.FOLDER_INBOX); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_GET_MESSAGE_LISTING, + MceStateMachine.FOLDER_INBOX); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest(any( - RequestGetMessagesListing.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessagesListing.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessagesListing); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessagesListing); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest(any( - RequestGetMessage.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessage.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessage); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessage); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockDatabase, times(1)).storeMessage(any(), any(), - any(), eq(MESSAGE_SEEN)); - } + verify(mMockDatabase, times(1)).storeMessage(any(), any(), any(), eq(MESSAGE_SEEN)); + } - /** - * Test receiving a new message notification. - */ + /** Test receiving a new message notification. */ @Test public void testReceiveNewMessageNotification() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); // Receive a new message notification. String dateTime = new ObexTime(Instant.now()).toString(); - EventReport event = createNewEventReport("NewMessage", dateTime, mTestMessageSmsHandle, - "telecom/msg/inbox", null, "SMS_GSM"); + EventReport event = + createNewEventReport( + "NewMessage", + dateTime, + mTestMessageSmsHandle, + "telecom/msg/inbox", + null, + "SMS_GSM"); Message notificationMessage = - Message.obtain(mHandler, MceStateMachine.MSG_NOTIFICATION, (Object)event); + Message.obtain(mHandler, MceStateMachine.MSG_NOTIFICATION, (Object) event); mMceStateMachine.getCurrentState().processMessage(notificationMessage); - verify(mMockMasClient, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) - .makeRequest(any(RequestGetMessage.class)); + verify(mMockMasClient, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .makeRequest(any(RequestGetMessage.class)); MceStateMachine.MessageMetadata messageMetadata = mMceStateMachine.mMessages.get(mTestMessageSmsHandle); @@ -882,42 +911,51 @@ public class MapClientStateMachineTest { Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); - //verifying that state machine is in the Connected state - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + // verifying that state machine is in the Connected state + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); String dateTime = new ObexTime(Instant.now()).toString(); - EventReport event = createNewEventReport("NewMessage", dateTime, mTestMessageSmsHandle, - "telecom/msg/inbox", null, "SMS_GSM"); + EventReport event = + createNewEventReport( + "NewMessage", + dateTime, + mTestMessageSmsHandle, + "telecom/msg/inbox", + null, + "SMS_GSM"); mMceStateMachine.receiveEvent(event); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMasClient, times(1)).makeRequest - (any(RequestGetMessage.class)); + verify(mMockMasClient, times(1)).makeRequest(any(RequestGetMessage.class)); - msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, - mMockRequestGetMessage); + msg = + Message.obtain( + mHandler, + MceStateMachine.MSG_MAS_REQUEST_COMPLETED, + mMockRequestGetMessage); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToBeIdle(mMceStateMachine.getHandler().getLooper()); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendBroadcast( - mIntentArgument.capture(), - eq(android.Manifest.permission.RECEIVE_SMS)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .sendBroadcast( + mIntentArgument.capture(), eq(android.Manifest.permission.RECEIVE_SMS)); Assert.assertNull(mIntentArgument.getValue().getPackage()); } @Test public void testSdpBusyWhileConnecting_sdpRetried() { // Perform first part of MAP connection logic. - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mMceStateMachine.getState()); // Send SDP Failed with status "busy" @@ -931,20 +969,22 @@ public class MapClientStateMachineTest { mMceStateMachine.sendMessage(msg); // Verify we move into the connected state - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); } @Test public void testSdpBusyWhileConnectingAndRetryResultsReceivedAfterTimeout_resultsIgnored() { // Perform first part of MAP connection logic. - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mMceStateMachine.getState()); // Send SDP Failed with status "busy" @@ -956,13 +996,13 @@ public class MapClientStateMachineTest { mMceStateMachine.sendMessage(msg); // Verify we move into the disconnecting state - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_DISCONNECTING); - // Send successful SDP record, then send MAS Client connected SdpMasRecord record = new SdpMasRecord(1, 1, 1, 1, 1, 1, "MasRecord"); mMceStateMachine.sendSdpResult(MceStateMachine.SDP_SUCCESS, record); @@ -974,52 +1014,53 @@ public class MapClientStateMachineTest { @Test public void testSdpFailedWithNoRecordWhileConnecting_deviceDisconnected() { // Perform first part of MAP connection logic. - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mMceStateMachine.getState()); // Send SDP process success with no record found mMceStateMachine.sendSdpResult(MceStateMachine.SDP_SUCCESS, null); // Verify we move into the disconnecting state - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_DISCONNECTING); } @Test public void testSdpOrganicFailure_deviceDisconnected() { // Perform first part of MAP connection logic. - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mMceStateMachine.getState()); // Send SDP Failed entirely mMceStateMachine.sendSdpResult(MceStateMachine.SDP_FAILED, null); - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_DISCONNECTING); } /** - * Preconditions: - * - In {@code STATE_CONNECTED}. + * Preconditions: - In {@code STATE_CONNECTED}. * - * Actions: - * - {@link #sendMapMessage} with 'Sent' {@link PendingIntents}. - * - {@link #receiveEvent} of type {@link SENDING_SUCCESS}. + *

Actions: - {@link #sendMapMessage} with 'Sent' {@link PendingIntents}. - {@link + * #receiveEvent} of type {@link SENDING_SUCCESS}. * - * Outcome: - * - SENT_STATUS Intent was broadcast with 'Success' result code. + *

Outcome: - SENT_STATUS Intent was broadcast with 'Success' result code. */ @Test public void testSendMapMessageSentPendingIntent_notifyStatusSuccess() { @@ -1032,15 +1073,12 @@ public class MapClientStateMachineTest { } /** - * Preconditions: - * - In {@code STATE_CONNECTED}. + * Preconditions: - In {@code STATE_CONNECTED}. * - * Actions: - * - {@link #sendMapMessage} with 'Delivery' {@link PendingIntents}. - * - {@link #receiveEvent} of type {@link DELIVERY_SUCCESS}. + *

Actions: - {@link #sendMapMessage} with 'Delivery' {@link PendingIntents}. - {@link + * #receiveEvent} of type {@link DELIVERY_SUCCESS}. * - * Outcome: - * - DELIVERY_STATUS Intent was broadcast with 'Success' result code. + *

Outcome: - DELIVERY_STATUS Intent was broadcast with 'Success' result code. */ @Test public void testSendMapMessageDeliveryPendingIntent_notifyStatusSuccess() { @@ -1053,16 +1091,13 @@ public class MapClientStateMachineTest { } /** - * Preconditions: - * - In {@code STATE_CONNECTED}. + * Preconditions: - In {@code STATE_CONNECTED}. * - * Actions: - * - {@link #sendMapMessage} with 'null' {@link PendingIntents}. - * - {@link #receiveEvent} of type {@link SENDING_SUCCESS}. - * - {@link #receiveEvent} of type {@link DELIVERY_SUCCESS}. + *

Actions: - {@link #sendMapMessage} with 'null' {@link PendingIntents}. - {@link + * #receiveEvent} of type {@link SENDING_SUCCESS}. - {@link #receiveEvent} of type {@link + * DELIVERY_SUCCESS}. * - * Outcome: - * - No Intent was broadcast. + *

Outcome: - No Intent was broadcast. */ @Test public void testSendMapMessageNullPendingIntent_noNotifyStatus() { @@ -1073,15 +1108,12 @@ public class MapClientStateMachineTest { } /** - * Preconditions: - * - In {@code STATE_CONNECTED}. + * Preconditions: - In {@code STATE_CONNECTED}. * - * Actions: - * - {@link #sendMapMessage} with 'Sent' {@link PendingIntents}. - * - {@link #receiveEvent} of type {@link SENDING_FAILURE}. + *

Actions: - {@link #sendMapMessage} with 'Sent' {@link PendingIntents}. - {@link + * #receiveEvent} of type {@link SENDING_FAILURE}. * - * Outcome: - * - SENT_STATUS Intent was broadcast with 'Failure' result code. + *

Outcome: - SENT_STATUS Intent was broadcast with 'Failure' result code. */ @Test public void testSendMapMessageSentPendingIntent_notifyStatusFailure() { @@ -1095,15 +1127,12 @@ public class MapClientStateMachineTest { } /** - * Preconditions: - * - In {@code STATE_CONNECTED}. + * Preconditions: - In {@code STATE_CONNECTED}. * - * Actions: - * - {@link #sendMapMessage} with 'Delivery' {@link PendingIntents}. - * - {@link #receiveEvent} of type {@link DELIVERY_FAILURE}. + *

Actions: - {@link #sendMapMessage} with 'Delivery' {@link PendingIntents}. - {@link + * #receiveEvent} of type {@link DELIVERY_FAILURE}. * - * Outcome: - * - DELIVERY_STATUS Intent was broadcast with 'Failure' result code. + *

Outcome: - DELIVERY_STATUS Intent was broadcast with 'Failure' result code. */ @Test public void testSendMapMessageDeliveryPendingIntent_notifyStatusFailure() { @@ -1117,8 +1146,8 @@ public class MapClientStateMachineTest { } /** - * @param action corresponding to the {@link PendingIntent} you want to create/register for - * when pushing a MAP message, e.g., for 'Sent' or 'Delivery' status. + * @param action corresponding to the {@link PendingIntent} you want to create/register for when + * pushing a MAP message, e.g., for 'Sent' or 'Delivery' status. * @param type the EventReport type of the new notification, e.g., 'Sent'/'Delivery' * 'Success'/'Failure'. */ @@ -1200,10 +1229,11 @@ public class MapClientStateMachineTest { private void setupSdpRecordReceipt() { // Perform first part of MAP connection logic. - verify(mMockMapClientService, - timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendBroadcastMultiplePermissions( - mIntentArgument.capture(), any(String[].class), - any(BroadcastOptions.class)); + verify(mMockMapClientService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .sendBroadcastMultiplePermissions( + mIntentArgument.capture(), + any(String[].class), + any(BroadcastOptions.class)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mMceStateMachine.getState()); // Setup receipt of SDP record @@ -1227,7 +1257,11 @@ public class MapClientStateMachineTest { } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { Cursor cursor = Mockito.mock(Cursor.class); @@ -1240,8 +1274,7 @@ public class MapClientStateMachineTest { } } - private static String getFolderNameFromRequestGetMessagesListing( - Request request) { + private static String getFolderNameFromRequestGetMessagesListing(Request request) { Log.d(TAG, "getFolderName, Request type=" + request); String folderName = null; if (request instanceof RequestGetMessagesListing) { @@ -1256,21 +1289,26 @@ public class MapClientStateMachineTest { } // create new Messages from given input - com.android.bluetooth.mapclient.Message createNewMessage(String mType, String mHandle){ + com.android.bluetooth.mapclient.Message createNewMessage(String mType, String mHandle) { HashMap attrs = new HashMap(); attrs.put("type", mType); attrs.put("handle", mHandle); attrs.put("datetime", "20230223T160000"); - com.android.bluetooth.mapclient.Message message = new com.android.bluetooth.mapclient. - Message(attrs); + com.android.bluetooth.mapclient.Message message = + new com.android.bluetooth.mapclient.Message(attrs); return message; } - EventReport createNewEventReport(String mType, String mDateTime, String mHandle, String mFolder, - String mOldFolder, String mMsgType){ + EventReport createNewEventReport( + String mType, + String mDateTime, + String mHandle, + String mFolder, + String mOldFolder, + String mMsgType) { HashMap attrs = new HashMap(); @@ -1284,10 +1322,9 @@ public class MapClientStateMachineTest { EventReport event = new EventReport(attrs); return event; - } - //create new Bmessages for testing + // create new Bmessages for testing void createTestMessages() { mOriginator = new VCardEntry(); VCardProperty property = new VCardProperty(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java index e36a25ab8de..04ed3e5d408 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java @@ -64,7 +64,6 @@ public class MapClientTest { @Mock private MnsService mMockMnsService; @Mock private DatabaseManager mDatabaseManager; - @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); @@ -108,9 +107,7 @@ public class MapClientTest { Assert.assertNotNull(MapClientService.getMapClientService()); } - /** - * Test connection of one device. - */ + /** Test connection of one device. */ @Test public void testConnect() { // make sure there is no statemachine already defined for this device @@ -134,9 +131,7 @@ public class MapClientTest { Assert.assertNull(mService.getInstanceMap().get(device)); } - /** - * Test that a PRIORITY_OFF device is not connected to - */ + /** Test that a PRIORITY_OFF device is not connected to */ @Test public void testConnectPriorityOffDevice() { // make sure there is no statemachine already defined for this device @@ -153,9 +148,7 @@ public class MapClientTest { Assert.assertNull(map.get(device)); } - /** - * Test connecting MAXIMUM_CONNECTED_DEVICES devices. - */ + /** Test connecting MAXIMUM_CONNECTED_DEVICES devices. */ @Test public void testConnectMaxDevices() { // Create bluetoothdevice & mock statemachine objects to be used in this test @@ -188,9 +181,7 @@ public class MapClientTest { Assert.assertFalse(mService.connect(last)); } - /** - * Test calling connect via Binder - */ + /** Test calling connect via Binder */ @Test public void testConnectViaBinder() { BluetoothDevice device = makeBluetoothDevice("11:11:11:11:11:11"); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java index a60c16e7946..1ed12863975 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java @@ -47,8 +47,7 @@ public class MnsObexServerTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - MceStateMachine mStateMachine; + @Mock MceStateMachine mStateMachine; MnsObexServer mServer; @@ -59,7 +58,7 @@ public class MnsObexServerTest { @Test public void onConnect_whenUuidIsWrong() { - byte[] wrongUuid = new byte[]{}; + byte[] wrongUuid = new byte[] {}; HeaderSet request = new HeaderSet(); request.setHeader(HeaderSet.TARGET, wrongUuid); HeaderSet reply = new HeaderSet(); @@ -115,14 +114,15 @@ public class MnsObexServerTest { xml.append(" old_folder=\"test_old_folder\"\n"); xml.append(" msg_type=\"MMS\"\n"); xml.append("/>\n"); - DataInputStream stream = new DataInputStream( - new ByteArrayInputStream(xml.toString().getBytes())); - - byte[] applicationParameter = new byte[] { - Request.OAP_TAGID_MAS_INSTANCE_ID, - 1, // length in byte - (byte) 55 - }; + DataInputStream stream = + new DataInputStream(new ByteArrayInputStream(xml.toString().getBytes())); + + byte[] applicationParameter = + new byte[] { + Request.OAP_TAGID_MAS_INSTANCE_ID, + 1, // length in byte + (byte) 55 + }; HeaderSet headerSet = new HeaderSet(); headerSet.setHeader(HeaderSet.TYPE, MnsObexServer.TYPE); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java index 5841064eda0..0d6760716f8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java @@ -74,26 +74,30 @@ public class ObexTimeTest { "Parsed instant must match expected", VALID_INSTANT_LOCAL_TZ, timestamp.getInstant()); - Assert.assertEquals("Parsed date must match expected", - VALID_DATE_LOCAL_TZ, timestamp.getTime()); + Assert.assertEquals( + "Parsed date must match expected", VALID_DATE_LOCAL_TZ, timestamp.getTime()); } @Test public void createWithValidDateTimeStringWithPosOffset_TimestampCorrect() { ObexTime timestamp = new ObexTime(VALID_TIME_STRING_WITH_OFFSET_POS); - Assert.assertEquals("Parsed instant must match expected", VALID_INSTANT_WITH_OFFSET_POS, + Assert.assertEquals( + "Parsed instant must match expected", + VALID_INSTANT_WITH_OFFSET_POS, timestamp.getInstant()); - Assert.assertEquals("Parsed date must match expected", - VALID_DATE_WITH_OFFSET_POS, timestamp.getTime()); + Assert.assertEquals( + "Parsed date must match expected", VALID_DATE_WITH_OFFSET_POS, timestamp.getTime()); } @Test public void createWithValidDateTimeStringWithNegOffset_TimestampCorrect() { ObexTime timestamp = new ObexTime(VALID_TIME_STRING_WITH_OFFSET_NEG); - Assert.assertEquals("Parsed instant must match expected", VALID_INSTANT_WITH_OFFSET_NEG, + Assert.assertEquals( + "Parsed instant must match expected", + VALID_INSTANT_WITH_OFFSET_NEG, timestamp.getInstant()); - Assert.assertEquals("Parsed date must match expected", - VALID_DATE_WITH_OFFSET_NEG, timestamp.getTime()); + Assert.assertEquals( + "Parsed date must match expected", VALID_DATE_WITH_OFFSET_NEG, timestamp.getTime()); } @Test @@ -103,16 +107,20 @@ public class ObexTimeTest { "ObexTime created with a date must return the expected instant", VALID_INSTANT_LOCAL_TZ, timestamp.getInstant()); - Assert.assertEquals("ObexTime created with a date must return the same date", - VALID_DATE_LOCAL_TZ, timestamp.getTime()); + Assert.assertEquals( + "ObexTime created with a date must return the same date", + VALID_DATE_LOCAL_TZ, + timestamp.getTime()); } @SuppressWarnings("JavaUtilDate") @Test public void createWithValidInstant_TimestampCorrect() { ObexTime timestamp = new ObexTime(VALID_INSTANT); - Assert.assertEquals("ObexTime created with a instant must return the same instant", - VALID_INSTANT, timestamp.getInstant()); + Assert.assertEquals( + "ObexTime created with a instant must return the same instant", + VALID_INSTANT, + timestamp.getInstant()); Assert.assertEquals( "ObexTime created with a instant must return the expected date", VALID_DATE, @@ -122,28 +130,34 @@ public class ObexTimeTest { @Test public void printValidTime_TimestampMatchesInput() { ObexTime timestamp = new ObexTime(VALID_TIME_STRING); - Assert.assertEquals("Timestamp as a string must match the input string", VALID_TIME_STRING, + Assert.assertEquals( + "Timestamp as a string must match the input string", + VALID_TIME_STRING, timestamp.toString()); } @Test public void createWithInvalidDelimiterString_TimestampIsNull() { ObexTime timestamp = new ObexTime(INVALID_TIME_STRING_BAD_DELIMITER); - Assert.assertEquals("Parsed timestamp was invalid and must result in a null object", null, + Assert.assertEquals( + "Parsed timestamp was invalid and must result in a null object", + null, timestamp.getTime()); } @Test public void createWithInvalidOffsetString_TimestampIsNull() { ObexTime timestamp = new ObexTime(INVALID_TIME_STRING_OFFSET_EXTRA_DIGITS); - Assert.assertEquals("Parsed timestamp was invalid and must result in a null object", null, + Assert.assertEquals( + "Parsed timestamp was invalid and must result in a null object", + null, timestamp.getTime()); } @Test public void printInvalidTime_ReturnsNull() { ObexTime timestamp = new ObexTime(INVALID_TIME_STRING_BAD_DELIMITER); - Assert.assertEquals("Invalid timestamps must return null for toString()", null, - timestamp.toString()); + Assert.assertEquals( + "Invalid timestamps must return null for toString()", null, timestamp.toString()); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java index c314d614cd0..0f94753e3ef 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java @@ -72,12 +72,15 @@ public class RequestGetMessagesListingForOwnNumberTest { * @param fillerElements - placeholder elements to fill up the folder. * @param targetElement - the element of interest that contains the info you want. * @param position - the index in the folder where {@code targetElement} is to be inserted. - * If {@code -1} or otherwise outside range, {@code folder} will not - * contain {@code targetElement}. + * If {@code -1} or otherwise outside range, {@code folder} will not contain {@code + * targetElement}. */ - public void createMessageFolder(String folder, int size, + public void createMessageFolder( + String folder, + int size, BluetoothMapMessageListingElement fillerElements, - BluetoothMapMessageListingElement targetElement, int position) { + BluetoothMapMessageListingElement targetElement, + int position) { List list = new ArrayList<>(); for (int i = 0; i < size; i++) { list.add(fillerElements); @@ -93,30 +96,41 @@ public class RequestGetMessagesListingForOwnNumberTest { } } - public InputStream getMessageListingAsInputStream(String folder, int offset, int maxCount, - byte msgTypeFilter) { + public InputStream getMessageListingAsInputStream( + String folder, int offset, int maxCount, byte msgTypeFilter) { List folderElements = mFolders.get(folder); BluetoothMapMessageListing requestedListing = new BluetoothMapMessageListing(); if (folderElements != null - && offset >= 0 && offset < LIST_START_OFFSET_UPPER_LIMIT - && maxCount >= 0 && maxCount < MAX_LIST_COUNT_UPPER_LIMIT) { + && offset >= 0 + && offset < LIST_START_OFFSET_UPPER_LIMIT + && maxCount >= 0 + && maxCount < MAX_LIST_COUNT_UPPER_LIMIT) { int msgCount = 0; - for (int i = offset; i < folderElements.size() && msgCount < maxCount; i++ ) { + for (int i = offset; i < folderElements.size() && msgCount < maxCount; i++) { BluetoothMapMessageListingElement element = folderElements.get(i); byte msgType = listingElementGetType(element); if ((msgTypeFilter & msgType) > 0) { requestedListing.add(element); msgCount += 1; } - Log.d(TAG, "getMessageListingAsInputStream: i=" + i + ", msgCount=" + msgCount - + ", msgType=" + msgType + ", msgTypeFilter=" + msgTypeFilter); + Log.d( + TAG, + "getMessageListingAsInputStream: i=" + + i + + ", msgCount=" + + msgCount + + ", msgType=" + + msgType + + ", msgTypeFilter=" + + msgTypeFilter); } } byte[] encodedListing = null; try { - encodedListing = requestedListing.encode(TEST_INCLUDE_THREAD_ID_ENCODE, - TEST_MSG_LISTING_OBJ_VERSION); + encodedListing = + requestedListing.encode( + TEST_INCLUDE_THREAD_ID_ENCODE, TEST_MSG_LISTING_OBJ_VERSION); } catch (Exception e) { assertWithMessage("Cannot encode MessageListing: " + e.getMessage()).fail(); } @@ -127,24 +141,22 @@ public class RequestGetMessagesListingForOwnNumberTest { } /** - * Map Client uses bytes to represent message types (e.g., MMS, SMS, Email) (c.f. - * {@link MessagesFilter}). However, Map Server (i.e., - * {@link BluetoothMapMessageListingElement}) uses enum to represent types (c.f., - * {@link BluetoothMapUtils}). Instead, we'll be abusing - * {@link BluetoothMapMessageListingElement#mAttachmentSize} to store Map Client's type, - * since it's otherwise unused in the tests. + * Map Client uses bytes to represent message types (e.g., MMS, SMS, Email) (c.f. {@link + * MessagesFilter}). However, Map Server (i.e., {@link BluetoothMapMessageListingElement}) uses + * enum to represent types (c.f., {@link BluetoothMapUtils}). Instead, we'll be abusing {@link + * BluetoothMapMessageListingElement#mAttachmentSize} to store Map Client's type, since it's + * otherwise unused in the tests. */ static void listingElementSetType(BluetoothMapMessageListingElement element, byte type) { element.setAttachmentSize(type); } /** - * Map Client uses bytes to represent message types (e.g., MMS, SMS, Email) (c.f. - * {@link MessagesFilter}). However, Map Server (i.e., - * {@link BluetoothMapMessageListingElement}) uses enum to represent types (c.f., - * {@link BluetoothMapUtils}). Instead, we'll be abusing - * {@link BluetoothMapMessageListingElement#mAttachmentSize} to store Map Client's type, - * since it's otherwise unused in the tests. + * Map Client uses bytes to represent message types (e.g., MMS, SMS, Email) (c.f. {@link + * MessagesFilter}). However, Map Server (i.e., {@link BluetoothMapMessageListingElement}) uses + * enum to represent types (c.f., {@link BluetoothMapUtils}). Instead, we'll be abusing {@link + * BluetoothMapMessageListingElement#mAttachmentSize} to store Map Client's type, since it's + * otherwise unused in the tests. */ static byte listingElementGetType(BluetoothMapMessageListingElement element) { return (byte) element.getAttachmentSize(); @@ -153,8 +165,7 @@ public class RequestGetMessagesListingForOwnNumberTest { @Before public void setUp() { // Override the MAX_LIST_COUNT upper limit to speed up tests - RequestGetMessagesListingForOwnNumber.sMaxListCountUpperLimit = - MAX_LIST_COUNT_UPPER_LIMIT; + RequestGetMessagesListingForOwnNumber.sMaxListCountUpperLimit = MAX_LIST_COUNT_UPPER_LIMIT; // Override the START_OFFSET upper limit to speed up tests RequestGetMessagesListingForOwnNumber.sListStartOffsetUpperLimit = LIST_START_OFFSET_UPPER_LIMIT; @@ -175,59 +186,74 @@ public class RequestGetMessagesListingForOwnNumberTest { listingElementSetType(mSMSWithoutOwnNumber, MessagesFilter.MESSAGE_TYPE_SMS_GSM); } - private String testGetOwnNumberBase(int sizeSentFolder, int sizeInboxFolder, - int positionSentFolder, int positionInboxFolder, + private String testGetOwnNumberBase( + int sizeSentFolder, + int sizeInboxFolder, + int positionSentFolder, + int positionInboxFolder, BluetoothMapMessageListingElement targetElement) { FakeMessageFoldersForListing folders = new FakeMessageFoldersForListing(); - folders.createMessageFolder(MceStateMachine.FOLDER_SENT, sizeSentFolder, - mSMSWithoutOwnNumber, targetElement, positionSentFolder); - folders.createMessageFolder(MceStateMachine.FOLDER_INBOX, sizeInboxFolder, - mSMSWithoutOwnNumber, targetElement, positionInboxFolder); + folders.createMessageFolder( + MceStateMachine.FOLDER_SENT, + sizeSentFolder, + mSMSWithoutOwnNumber, + targetElement, + positionSentFolder); + folders.createMessageFolder( + MceStateMachine.FOLDER_INBOX, + sizeInboxFolder, + mSMSWithoutOwnNumber, + targetElement, + positionInboxFolder); RequestGetMessagesListingForOwnNumber newRequest = new RequestGetMessagesListingForOwnNumber(); - for (int i = 0; !newRequest.isSearchCompleted() && i < MAX_ITERATIONS; i ++) { + for (int i = 0; !newRequest.isSearchCompleted() && i < MAX_ITERATIONS; i++) { String folderName = null; try { folderName = (String) newRequest.mHeaderSet.getHeader(HeaderSet.NAME); } catch (Exception e) { - assertWithMessage("Cannot obtain folder name from Request's HeaderSet: " - + e.getMessage()).fail(); + assertWithMessage( + "Cannot obtain folder name from Request's HeaderSet: " + + e.getMessage()) + .fail(); } ObexAppParameters oap = ObexAppParameters.fromHeaderSet(newRequest.mHeaderSet); byte filterMessageType = oap.getByte(Request.OAP_TAGID_FILTER_MESSAGE_TYPE); int maxListCount = (int) oap.getShort(Request.OAP_TAGID_MAX_LIST_COUNT); int startOffset = (int) oap.getShort(Request.OAP_TAGID_START_OFFSET); - Log.d(TAG, String.format("testBase: filter=%b, count=%b, offset=%b", - oap.exists(Request.OAP_TAGID_FILTER_MESSAGE_TYPE), - oap.exists(Request.OAP_TAGID_MAX_LIST_COUNT), - oap.exists(Request.OAP_TAGID_START_OFFSET))); - - Log.d(TAG, String.format( - "testBase: [i=%d] folder=%s, maxCount=%d, offset=%d, filterMessageType=%02X", - i, folderName, maxListCount, startOffset, filterMessageType)); + Log.d( + TAG, + String.format( + "testBase: filter=%b, count=%b, offset=%b", + oap.exists(Request.OAP_TAGID_FILTER_MESSAGE_TYPE), + oap.exists(Request.OAP_TAGID_MAX_LIST_COUNT), + oap.exists(Request.OAP_TAGID_START_OFFSET))); + + Log.d( + TAG, + String.format( + "testBase: [i=%d] folder=%s, maxCount=%d, offset=%d," + + " filterMessageType=%02X", + i, folderName, maxListCount, startOffset, filterMessageType)); newRequest.readResponse( - folders.getMessageListingAsInputStream(folderName, startOffset, maxListCount, - filterMessageType)); + folders.getMessageListingAsInputStream( + folderName, startOffset, maxListCount, filterMessageType)); } return newRequest.getOwnNumber(); } /** - * Preconditions: - * - SENT is empty. - * - INBOX is empty. + * Preconditions: - SENT is empty. - INBOX is empty. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is not found. + *

Outcome: - Own number is not found. */ @Test public void testEmpty_Empty_null() { @@ -237,24 +263,25 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = -1; BluetoothMapMessageListingElement targetElement = null; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isNull(); } /** - * Preconditions: - * - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - MMS with own number as sender is the first message in SENT folder. - * - INBOX is empty. + * Preconditions: - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - + * MMS with own number as sender is the first message in SENT folder. - INBOX is empty. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is found. + *

Outcome: - Own number is found. */ @Test public void testHalfFirst_Empty_found() { @@ -264,24 +291,25 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = -1; BluetoothMapMessageListingElement targetElement = mMMSWithOwnNumberAsSender; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isEqualTo(TEST_OWN_NUMBER); } /** - * Preconditions: - * - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - MMS with own number as sender is the last message in SENT folder. - * - INBOX is empty. + * Preconditions: - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - + * MMS with own number as sender is the last message in SENT folder. - INBOX is empty. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is found. + *

Outcome: - Own number is found. */ @Test public void testHalfLast_Empty_found() { @@ -291,24 +319,25 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = -1; BluetoothMapMessageListingElement targetElement = mMMSWithOwnNumberAsSender; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isEqualTo(TEST_OWN_NUMBER); } /** - * Preconditions: - * - SENT number of messages is equal to {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - MMS with own number as sender is the last message in SENT folder. - * - INBOX is empty. + * Preconditions: - SENT number of messages is equal to {@code LIST_START_OFFSET_UPPER_LIMIT}. - + * MMS with own number as sender is the last message in SENT folder. - INBOX is empty. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is found. + *

Outcome: - Own number is found. */ @Test public void testFullLast_Empty_found() { @@ -318,24 +347,26 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = -1; BluetoothMapMessageListingElement targetElement = mMMSWithOwnNumberAsSender; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isEqualTo(TEST_OWN_NUMBER); } /** - * Preconditions: - * - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - INBOX number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - SMS with own number as recipient is the first message in INBOX folder. + * Preconditions: - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - + * INBOX number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - SMS with own + * number as recipient is the first message in INBOX folder. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is found. + *

Outcome: - Own number is found. */ @Test public void testHalf_HalfFirst_found() { @@ -345,24 +376,26 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = 0; BluetoothMapMessageListingElement targetElement = mSMSWithOwnNumberAsRecipient; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isEqualTo(TEST_OWN_NUMBER); } /** - * Preconditions: - * - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - INBOX number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - SMS with own number as recipient is the last message in INBOX folder. + * Preconditions: - SENT number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - + * INBOX number of messages is half of {@code LIST_START_OFFSET_UPPER_LIMIT}. - SMS with own + * number as recipient is the last message in INBOX folder. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is found. + *

Outcome: - Own number is found. */ @Test public void testHalf_HalfLast_found() { @@ -372,24 +405,26 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = inboxFolderSize - 1; BluetoothMapMessageListingElement targetElement = mSMSWithOwnNumberAsRecipient; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isEqualTo(TEST_OWN_NUMBER); } /** - * Preconditions: - * - SENT number of messages is equal to {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - INBOX number of messages is equal to {@code LIST_START_OFFSET_UPPER_LIMIT}. - * - SMS with own number as recipient is the last message in INBOX folder. + * Preconditions: - SENT number of messages is equal to {@code LIST_START_OFFSET_UPPER_LIMIT}. - + * INBOX number of messages is equal to {@code LIST_START_OFFSET_UPPER_LIMIT}. - SMS with own + * number as recipient is the last message in INBOX folder. * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - Own number is found. + *

Outcome: - Own number is found. */ @Test public void testFull_FullLast_found() { @@ -399,25 +434,26 @@ public class RequestGetMessagesListingForOwnNumberTest { int inboxFolderPosition = inboxFolderSize - 1; BluetoothMapMessageListingElement targetElement = mSMSWithOwnNumberAsRecipient; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isEqualTo(TEST_OWN_NUMBER); } /** - * Preconditions: - * - SENT is empty. - * - INBOX contains a single message. - * - MMS with someone else's number as recipient in INBOX folder (e.g., group MMS case). + * Preconditions: - SENT is empty. - INBOX contains a single message. - MMS with someone else's + * number as recipient in INBOX folder (e.g., group MMS case). * - * Actions: - * - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly until the - * own number has been found or folder elements have been exhausted. + *

Actions: - Invoke {@link RequestGetMessagesListingForOwnNumber#readResponse} repeatedly + * until the own number has been found or folder elements have been exhausted. * - * Outcome: - * - No number is found, not even someone else's number, since MMS should be filtered out - * of INBOX. + *

Outcome: - No number is found, not even someone else's number, since MMS should be + * filtered out of INBOX. */ @Test public void testMMSinInbox_null() { @@ -429,8 +465,13 @@ public class RequestGetMessagesListingForOwnNumberTest { // is non-empty (i.e., would not get skipped if not filtered out by msg type). BluetoothMapMessageListingElement targetElement = mMMSWithOwnNumberAsSender; - String ownNumber = testGetOwnNumberBase(sentFolderSize, inboxFolderSize, - sentFolderPosition, inboxFolderPosition, targetElement); + String ownNumber = + testGetOwnNumberBase( + sentFolderSize, + inboxFolderSize, + sentFolderPosition, + inboxFolderPosition, + targetElement); assertThat(ownNumber).isNull(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestTest.java index 95599cd5799..a9b718d0c21 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestTest.java @@ -57,12 +57,11 @@ public class RequestTest { private static final String TYPE_SET_NOTIFICATION_REGISTRATION = "x-bt/MAP-NotificationRegistration"; - private static final String HANDLE = "0000001"; private static final Bmessage TEST_MESSAGE = BmessageParser.createBmessage(SIMPLE_MMS_MESSAGE); - private static final ArrayList TEST_FOLDER_LIST = new ArrayList( - Arrays.asList("folder1")); + private static final ArrayList TEST_FOLDER_LIST = + new ArrayList(Arrays.asList("folder1")); private static final ArrayList TEST_MESSAGE_LIST = new ArrayList(); private static final Date TEST_TIME = new Date(); private static final byte TEST_STATUS_INDICATOR = Request.STATUS_INDICATOR_READ; @@ -80,9 +79,14 @@ public class RequestTest { @Test public void testRequestGetMessagesListing() throws IOException { - RequestGetMessagesListing newRequest = new RequestGetMessagesListing( - TEST_FOLDER_LIST.get(0), /*parameters*/ 0, /*filter*/ null, /*subjectLength*/ 0, - /*maxListCount*/ 0, /*listStartOffset*/ 0); + RequestGetMessagesListing newRequest = + new RequestGetMessagesListing( + TEST_FOLDER_LIST.get(0), /*parameters*/ + 0, /*filter*/ + null, /*subjectLength*/ + 0, + /*maxListCount*/ 0, /*listStartOffset*/ + 0); assertThat(newRequest).isNotNull(); newRequest.execute(mFakeClientSession); @@ -94,8 +98,8 @@ public class RequestTest { @Test public void testRequestGetMessage() throws IOException { - RequestGetMessage newRequest = new RequestGetMessage(HANDLE, MasClient.CharsetType.UTF_8, - /*attachment*/ false); + RequestGetMessage newRequest = + new RequestGetMessage(HANDLE, MasClient.CharsetType.UTF_8, /*attachment*/ false); assertThat(newRequest).isNotNull(); assertThat(newRequest.getHandle()).isEqualTo(HANDLE); newRequest.execute(mFakeClientSession); @@ -107,8 +111,8 @@ public class RequestTest { @Test public void testRequestGetFolderListing() throws IOException { - RequestGetFolderListing newRequest = new RequestGetFolderListing(/*maxListCount*/ 255, - /*listStartOffset*/ 0); + RequestGetFolderListing newRequest = + new RequestGetFolderListing(/*maxListCount*/ 255, /*listStartOffset*/ 0); assertThat(newRequest).isNotNull(); newRequest.execute(mFakeClientSession); @@ -118,8 +122,13 @@ public class RequestTest { @Test public void testRequestPushMessage() throws IOException { - RequestPushMessage newRequest = new RequestPushMessage(TEST_FOLDER_LIST.get(0), - TEST_MESSAGE, /*charset*/ null, /*transparent*/ false, /*retry*/ false); + RequestPushMessage newRequest = + new RequestPushMessage( + TEST_FOLDER_LIST.get(0), + TEST_MESSAGE, /*charset*/ + null, /*transparent*/ + false, /*retry*/ + false); assertThat(newRequest).isNotNull(); assertThat(newRequest.getMsgHandle()).isEqualTo(null); newRequest.execute(mFakeClientSession); @@ -131,8 +140,8 @@ public class RequestTest { @Test public void testRequestSetMessageStatus() throws IOException { - RequestSetMessageStatus newRequest = new RequestSetMessageStatus(HANDLE, - StatusIndicator.READ, TEST_STATUS_VALUE); + RequestSetMessageStatus newRequest = + new RequestSetMessageStatus(HANDLE, StatusIndicator.READ, TEST_STATUS_VALUE); assertThat(newRequest).isNotNull(); assertThat(newRequest.getHandle()).isEqualTo(HANDLE); newRequest.execute(mFakeClientSession); @@ -144,8 +153,8 @@ public class RequestTest { @Test public void testRequestSetNotificationRegistration() throws IOException { - RequestSetNotificationRegistration newRequest = new RequestSetNotificationRegistration( - /*status*/ true); + RequestSetNotificationRegistration newRequest = + new RequestSetNotificationRegistration(/*status*/ true); assertThat(newRequest).isNotNull(); newRequest.execute(mFakeClientSession); @@ -197,8 +206,8 @@ public class RequestTest { case TYPE_GET_MESSAGE_LISTING: outAppParams.setNewMessage(1); outAppParams.setMseTime(TEST_TIME.getTime()); - replyHeaders.setHeader(HeaderSet.APPLICATION_PARAMETER, - outAppParams.encodeParams()); + replyHeaders.setHeader( + HeaderSet.APPLICATION_PARAMETER, outAppParams.encodeParams()); op.sendHeaders(replyHeaders); return ResponseCodes.OBEX_HTTP_OK; } @@ -249,7 +258,9 @@ public class RequestTest { } @Override - public int onSetPathValidator(final HeaderSet request, HeaderSet reply, + public int onSetPathValidator( + final HeaderSet request, + HeaderSet reply, final boolean backup, final boolean create) { try { diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java index ceb34661f28..849d3b73c02 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java @@ -50,12 +50,9 @@ public class McpServiceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private AdapterService mAdapterService; - @Mock - private MediaControlGattService mMockMcpService; - @Mock - private MediaControlProfile mMediaControlProfile; + @Mock private AdapterService mAdapterService; + @Mock private MediaControlGattService mMockMcpService; + @Mock private MediaControlProfile mMediaControlProfile; @Before public void setUp() throws Exception { @@ -108,8 +105,8 @@ public class McpServiceTest { mMcpService.setDeviceAuthorized(device1, false); verify(mMediaControlProfile).onDeviceAuthorizationSet(eq(device1)); - Assert.assertEquals(BluetoothDevice.ACCESS_REJECTED, - mMcpService.getDeviceAuthorization(device1)); + Assert.assertEquals( + BluetoothDevice.ACCESS_REJECTED, mMcpService.getDeviceAuthorization(device1)); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java index 5588f5ae956..af855c0023a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java @@ -91,7 +91,6 @@ public class MediaControlGattServiceTest { Looper.prepare(); } - TestUtils.setAdapterService(mAdapterService); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -103,8 +102,8 @@ public class MediaControlGattServiceTest { mMcpService.setServiceManagerForTesting(mMockMcpService); mMcpService.setLeAudioServiceForTesting(mMockLeAudioService); - when(mMockMcpService.getDeviceAuthorization(any(BluetoothDevice.class))).thenReturn( - BluetoothDevice.ACCESS_ALLOWED); + when(mMockMcpService.getDeviceAuthorization(any(BluetoothDevice.class))) + .thenReturn(BluetoothDevice.ACCESS_ALLOWED); } @After @@ -156,24 +155,36 @@ public class MediaControlGattServiceTest { } private BluetoothGattService initAllFeaturesGattService() { - long features = ServiceFeature.ALL_MANDATORY_SERVICE_FEATURES - | ServiceFeature.PLAYER_ICON_OBJ_ID | ServiceFeature.PLAYER_ICON_URL - | ServiceFeature.PLAYBACK_SPEED | ServiceFeature.SEEKING_SPEED - | ServiceFeature.CURRENT_TRACK_SEGMENT_OBJ_ID | ServiceFeature.CURRENT_TRACK_OBJ_ID - | ServiceFeature.NEXT_TRACK_OBJ_ID | ServiceFeature.CURRENT_GROUP_OBJ_ID - | ServiceFeature.PARENT_GROUP_OBJ_ID | ServiceFeature.PLAYING_ORDER - | ServiceFeature.PLAYING_ORDER_SUPPORTED | ServiceFeature.MEDIA_CONTROL_POINT - | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED - | ServiceFeature.SEARCH_RESULT_OBJ_ID | ServiceFeature.SEARCH_CONTROL_POINT - // Notifications - | ServiceFeature.PLAYER_NAME_NOTIFY | ServiceFeature.TRACK_TITLE_NOTIFY - | ServiceFeature.TRACK_DURATION_NOTIFY | ServiceFeature.TRACK_POSITION_NOTIFY - | ServiceFeature.PLAYBACK_SPEED_NOTIFY | ServiceFeature.SEEKING_SPEED_NOTIFY - | ServiceFeature.CURRENT_TRACK_OBJ_ID_NOTIFY - | ServiceFeature.NEXT_TRACK_OBJ_ID_NOTIFY - | ServiceFeature.CURRENT_GROUP_OBJ_ID_NOTIFY - | ServiceFeature.PARENT_GROUP_OBJ_ID_NOTIFY | ServiceFeature.PLAYING_ORDER_NOTIFY - | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY; + long features = + ServiceFeature.ALL_MANDATORY_SERVICE_FEATURES + | ServiceFeature.PLAYER_ICON_OBJ_ID + | ServiceFeature.PLAYER_ICON_URL + | ServiceFeature.PLAYBACK_SPEED + | ServiceFeature.SEEKING_SPEED + | ServiceFeature.CURRENT_TRACK_SEGMENT_OBJ_ID + | ServiceFeature.CURRENT_TRACK_OBJ_ID + | ServiceFeature.NEXT_TRACK_OBJ_ID + | ServiceFeature.CURRENT_GROUP_OBJ_ID + | ServiceFeature.PARENT_GROUP_OBJ_ID + | ServiceFeature.PLAYING_ORDER + | ServiceFeature.PLAYING_ORDER_SUPPORTED + | ServiceFeature.MEDIA_CONTROL_POINT + | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED + | ServiceFeature.SEARCH_RESULT_OBJ_ID + | ServiceFeature.SEARCH_CONTROL_POINT + // Notifications + | ServiceFeature.PLAYER_NAME_NOTIFY + | ServiceFeature.TRACK_TITLE_NOTIFY + | ServiceFeature.TRACK_DURATION_NOTIFY + | ServiceFeature.TRACK_POSITION_NOTIFY + | ServiceFeature.PLAYBACK_SPEED_NOTIFY + | ServiceFeature.SEEKING_SPEED_NOTIFY + | ServiceFeature.CURRENT_TRACK_OBJ_ID_NOTIFY + | ServiceFeature.NEXT_TRACK_OBJ_ID_NOTIFY + | ServiceFeature.CURRENT_GROUP_OBJ_ID_NOTIFY + | ServiceFeature.PARENT_GROUP_OBJ_ID_NOTIFY + | ServiceFeature.PLAYING_ORDER_NOTIFY + | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY; doReturn(features).when(mMockMcsCallbacks).onGetFeatureFlags(); Assert.assertTrue(mMcpService.init(UUID_GMCS)); @@ -188,8 +199,8 @@ public class MediaControlGattServiceTest { // called mMcpService.mServerCallback.onServiceAdded(BluetoothGatt.GATT_SUCCESS, service); verify(mMockMcsCallbacks) - .onServiceInstanceRegistered(any(ServiceStatus.class), any( - MediaControlGattServiceInterface.class)); + .onServiceInstanceRegistered( + any(ServiceStatus.class), any(MediaControlGattServiceInterface.class)); return service; } @@ -202,51 +213,62 @@ public class MediaControlGattServiceTest { BluetoothGattCharacteristic characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYER_NAME); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertEquals("", characteristic.getStringValue(0)); characteristic = service.getCharacteristic(MediaControlGattService.UUID_TRACK_TITLE); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertEquals("", characteristic.getStringValue(0)); characteristic = service.getCharacteristic(MediaControlGattService.UUID_TRACK_DURATION); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(0xFFFFFFFF, - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) + Assert.assertEquals( + 0xFFFFFFFF, + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) .intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_TRACK_POSITION); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(0xFFFFFFFF, - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) + Assert.assertEquals( + 0xFFFFFFFF, + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) .intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_MEDIA_STATE); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(MediaState.INACTIVE.getValue(), + Assert.assertEquals( + MediaState.INACTIVE.getValue(), characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0).intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_CONTENT_CONTROL_ID); Assert.assertNotNull(characteristic); Assert.assertEquals( characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ); - Assert.assertEquals(TEST_CCID, + Assert.assertEquals( + TEST_CCID, characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0).intValue()); // Check initial state of all optional characteristics @@ -269,20 +291,24 @@ public class MediaControlGattServiceTest { characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYBACK_SPEED); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(0, + Assert.assertEquals( + 0, characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT8, 0).intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_SEEKING_SPEED); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(0, + Assert.assertEquals( + 0, characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT8, 0).intValue()); characteristic = @@ -293,10 +319,11 @@ public class MediaControlGattServiceTest { characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ); Assert.assertTrue(characteristic.getValue().length == 0); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE @@ -305,62 +332,72 @@ public class MediaControlGattServiceTest { characteristic = service.getCharacteristic(MediaControlGattService.UUID_NEXT_TRACK_OBJ_ID); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertTrue(characteristic.getValue().length == 0); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertTrue(characteristic.getValue().length == 0); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_PARENT_GROUP_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_PARENT_GROUP_OBJ_ID); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertTrue(characteristic.getValue().length == 0); characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(PlayingOrder.SINGLE_ONCE.getValue(), + Assert.assertEquals( + PlayingOrder.SINGLE_ONCE.getValue(), characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0).intValue()); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_PLAYING_ORDER_SUPPORTED); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER_SUPPORTED); Assert.assertNotNull(characteristic); Assert.assertEquals( characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ); - Assert.assertEquals(SupportedPlayingOrder.SINGLE_ONCE, - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0) + Assert.assertEquals( + SupportedPlayingOrder.SINGLE_ONCE, + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0) .intValue()); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_MEDIA_CONTROL_POINT); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); + characteristic = + service.getCharacteristic( + MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertEquals( @@ -369,18 +406,20 @@ public class MediaControlGattServiceTest { .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) .intValue()); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_SEARCH_RESULT_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_SEARCH_RESULT_OBJ_ID); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); Assert.assertTrue(characteristic.getValue().length == 0); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_SEARCH_CONTROL_POINT); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_SEARCH_CONTROL_POINT); Assert.assertNotNull(characteristic); - Assert.assertEquals(characteristic.getProperties(), + Assert.assertEquals( + characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE); @@ -396,33 +435,40 @@ public class MediaControlGattServiceTest { String player_name = "TestPlayerName"; String icon_url = "www.testiconurl.com"; Long icon_obj_id = 7L; - Integer playing_order_supported = SupportedPlayingOrder.IN_ORDER_REPEAT - | SupportedPlayingOrder.SINGLE_ONCE | SupportedPlayingOrder.SINGLE_REPEAT - | SupportedPlayingOrder.IN_ORDER_ONCE | SupportedPlayingOrder.IN_ORDER_REPEAT - | SupportedPlayingOrder.OLDEST_ONCE | SupportedPlayingOrder.OLDEST_REPEAT - | SupportedPlayingOrder.NEWEST_ONCE | SupportedPlayingOrder.NEWEST_REPEAT - | SupportedPlayingOrder.SHUFFLE_ONCE | SupportedPlayingOrder.SHUFFLE_REPEAT; - Integer opcodes_supported = Request.SupportedOpcodes.NONE - | Request.SupportedOpcodes.PLAY - | Request.SupportedOpcodes.PAUSE - | Request.SupportedOpcodes.FAST_REWIND - | Request.SupportedOpcodes.FAST_FORWARD - | Request.SupportedOpcodes.STOP - | Request.SupportedOpcodes.MOVE_RELATIVE - | Request.SupportedOpcodes.PREVIOUS_SEGMENT - | Request.SupportedOpcodes.NEXT_SEGMENT - | Request.SupportedOpcodes.FIRST_SEGMENT - | Request.SupportedOpcodes.LAST_SEGMENT - | Request.SupportedOpcodes.GOTO_SEGMENT - | Request.SupportedOpcodes.PREVIOUS_TRACK - | Request.SupportedOpcodes.NEXT_TRACK - | Request.SupportedOpcodes.FIRST_TRACK - | Request.SupportedOpcodes.LAST_TRACK - | Request.SupportedOpcodes.GOTO_TRACK - | Request.SupportedOpcodes.PREVIOUS_GROUP - | Request.SupportedOpcodes.NEXT_GROUP - | Request.SupportedOpcodes.FIRST_GROUP - | Request.SupportedOpcodes.LAST_GROUP; + Integer playing_order_supported = + SupportedPlayingOrder.IN_ORDER_REPEAT + | SupportedPlayingOrder.SINGLE_ONCE + | SupportedPlayingOrder.SINGLE_REPEAT + | SupportedPlayingOrder.IN_ORDER_ONCE + | SupportedPlayingOrder.IN_ORDER_REPEAT + | SupportedPlayingOrder.OLDEST_ONCE + | SupportedPlayingOrder.OLDEST_REPEAT + | SupportedPlayingOrder.NEWEST_ONCE + | SupportedPlayingOrder.NEWEST_REPEAT + | SupportedPlayingOrder.SHUFFLE_ONCE + | SupportedPlayingOrder.SHUFFLE_REPEAT; + Integer opcodes_supported = + Request.SupportedOpcodes.NONE + | Request.SupportedOpcodes.PLAY + | Request.SupportedOpcodes.PAUSE + | Request.SupportedOpcodes.FAST_REWIND + | Request.SupportedOpcodes.FAST_FORWARD + | Request.SupportedOpcodes.STOP + | Request.SupportedOpcodes.MOVE_RELATIVE + | Request.SupportedOpcodes.PREVIOUS_SEGMENT + | Request.SupportedOpcodes.NEXT_SEGMENT + | Request.SupportedOpcodes.FIRST_SEGMENT + | Request.SupportedOpcodes.LAST_SEGMENT + | Request.SupportedOpcodes.GOTO_SEGMENT + | Request.SupportedOpcodes.PREVIOUS_TRACK + | Request.SupportedOpcodes.NEXT_TRACK + | Request.SupportedOpcodes.FIRST_TRACK + | Request.SupportedOpcodes.LAST_TRACK + | Request.SupportedOpcodes.GOTO_TRACK + | Request.SupportedOpcodes.PREVIOUS_GROUP + | Request.SupportedOpcodes.NEXT_GROUP + | Request.SupportedOpcodes.FIRST_GROUP + | Request.SupportedOpcodes.LAST_GROUP; String track_title = "Test Song"; long track_duration = 1000; MediaState playback_state = MediaState.SEEKING; @@ -450,14 +496,17 @@ public class MediaControlGattServiceTest { characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER); Assert.assertNotNull(characteristic); - Assert.assertEquals(playing_order.getValue(), + Assert.assertEquals( + playing_order.getValue(), characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0).intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_TRACK_POSITION); Assert.assertNotNull(characteristic); // Set value as ms, kept in characteristic as 0.01s - Assert.assertEquals(track_position / 10, - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) + Assert.assertEquals( + track_position / 10, + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) .intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYER_NAME); @@ -473,18 +522,23 @@ public class MediaControlGattServiceTest { Assert.assertEquals( icon_obj_id.longValue(), mMcpService.byteArray2ObjId(characteristic.getValue())); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_PLAYING_ORDER_SUPPORTED); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER_SUPPORTED); Assert.assertNotNull(characteristic); - Assert.assertEquals(playing_order_supported.intValue(), - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0) + Assert.assertEquals( + playing_order_supported.intValue(), + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0) .intValue()); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); + characteristic = + service.getCharacteristic( + MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); Assert.assertNotNull(characteristic); - Assert.assertEquals(opcodes_supported.intValue(), - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) + Assert.assertEquals( + opcodes_supported.intValue(), + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) .intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_TRACK_TITLE); @@ -494,13 +548,16 @@ public class MediaControlGattServiceTest { characteristic = service.getCharacteristic(MediaControlGattService.UUID_TRACK_DURATION); Assert.assertNotNull(characteristic); // Set value as ms, kept in characteristic as 0.01s - Assert.assertEquals(track_duration / 10, - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) + Assert.assertEquals( + track_duration / 10, + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0) .intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_MEDIA_STATE); Assert.assertNotNull(characteristic); - Assert.assertEquals(playback_state.getValue(), + Assert.assertEquals( + playback_state.getValue(), characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0).intValue()); characteristic = service.getCharacteristic(MediaControlGattService.UUID_SEEKING_SPEED); @@ -510,13 +567,23 @@ public class MediaControlGattServiceTest { private void verifyWriteObjIdsValid( BluetoothGattCharacteristic characteristic, long value, int id) { - mMcpService.mServerCallback.onCharacteristicWriteRequest(mCurrentDevice, 1, characteristic, - false, true, 0, mMcpService.objId2ByteArray(value)); + mMcpService.mServerCallback.onCharacteristicWriteRequest( + mCurrentDevice, + 1, + characteristic, + false, + true, + 0, + mMcpService.objId2ByteArray(value)); verify(mMockMcsCallbacks).onSetObjectIdRequest(eq(id), eq(value)); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), eq(BluetoothGatt.GATT_SUCCESS), eq(0), + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_SUCCESS), + eq(0), eq(mMcpService.objId2ByteArray(value))); } @@ -544,7 +611,11 @@ public class MediaControlGattServiceTest { verify(mMockMcsCallbacks).onTrackPositionSetRequest(eq(track_position * 10L)); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), eq(BluetoothGatt.GATT_SUCCESS), eq(0), + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_SUCCESS), + eq(0), eq(bb.array())); characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYBACK_SPEED); @@ -559,24 +630,28 @@ public class MediaControlGattServiceTest { .onPlaybackSpeedSetRequest(eq((float) Math.pow(2, playback_speed / 64))); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), eq(BluetoothGatt.GATT_SUCCESS), eq(0), + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_SUCCESS), + eq(0), eq(bb.array())); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); verifyWriteObjIdsValid( characteristic, current_track_obj_id, ObjectIds.CURRENT_TRACK_OBJ_ID); characteristic = service.getCharacteristic(MediaControlGattService.UUID_NEXT_TRACK_OBJ_ID); verifyWriteObjIdsValid(characteristic, next_track_obj_id, ObjectIds.NEXT_TRACK_OBJ_ID); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); verifyWriteObjIdsValid( characteristic, current_group_obj_id, ObjectIds.CURRENT_GROUP_OBJ_ID); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_PLAYING_ORDER_SUPPORTED); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER_SUPPORTED); characteristic.setValue( playing_order_supported, BluetoothGattCharacteristic.FORMAT_UINT16, 0); characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER); @@ -589,19 +664,27 @@ public class MediaControlGattServiceTest { verify(mMockMcsCallbacks).onPlayingOrderSetRequest(eq(playing_order.getValue())); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), eq(BluetoothGatt.GATT_SUCCESS), eq(0), + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_SUCCESS), + eq(0), eq(bb.array())); } private void verifyWriteObjIdsInvalid( BluetoothGattCharacteristic characteristic, int id, byte diffByte) { - byte[] value = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diffByte}; + byte[] value = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diffByte}; mMcpService.mServerCallback.onCharacteristicWriteRequest( mCurrentDevice, 1, characteristic, false, true, 0, value); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), eq(0), eq(value)); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), + eq(0), + eq(value)); } @Test @@ -624,8 +707,12 @@ public class MediaControlGattServiceTest { mCurrentDevice, 1, characteristic, false, true, 0, bb.array()); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), eq(0), eq(bb.array())); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), + eq(0), + eq(bb.array())); characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYBACK_SPEED); @@ -637,18 +724,22 @@ public class MediaControlGattServiceTest { mCurrentDevice, 1, characteristic, false, true, 0, bb.array()); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), eq(0), eq(bb.array())); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), + eq(0), + eq(bb.array())); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); verifyWriteObjIdsInvalid(characteristic, ObjectIds.CURRENT_TRACK_OBJ_ID, diff_byte++); characteristic = service.getCharacteristic(MediaControlGattService.UUID_NEXT_TRACK_OBJ_ID); verifyWriteObjIdsInvalid(characteristic, ObjectIds.NEXT_TRACK_OBJ_ID, diff_byte++); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); verifyWriteObjIdsInvalid(characteristic, ObjectIds.CURRENT_GROUP_OBJ_ID, diff_byte++); characteristic = service.getCharacteristic(MediaControlGattService.UUID_PLAYING_ORDER); @@ -660,8 +751,12 @@ public class MediaControlGattServiceTest { mCurrentDevice, 1, characteristic, false, true, 0, bb.array()); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), eq(0), eq(bb.array())); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), + eq(0), + eq(bb.array())); } private void testNotify(boolean registerForNotification) { @@ -676,30 +771,32 @@ public class MediaControlGattServiceTest { PlayingOrder playing_order = PlayingOrder.IN_ORDER_REPEAT; int playing_order_supported = SupportedPlayingOrder.IN_ORDER_REPEAT; int playback_state = MediaState.SEEKING.getValue(); - Integer opcodes_supported = Request.SupportedOpcodes.NONE - | Request.SupportedOpcodes.PLAY - | Request.SupportedOpcodes.PAUSE - | Request.SupportedOpcodes.FAST_REWIND - | Request.SupportedOpcodes.FAST_FORWARD - | Request.SupportedOpcodes.STOP - | Request.SupportedOpcodes.MOVE_RELATIVE - | Request.SupportedOpcodes.PREVIOUS_SEGMENT - | Request.SupportedOpcodes.NEXT_SEGMENT - | Request.SupportedOpcodes.FIRST_SEGMENT - | Request.SupportedOpcodes.LAST_SEGMENT - | Request.SupportedOpcodes.GOTO_SEGMENT - | Request.SupportedOpcodes.PREVIOUS_TRACK - | Request.SupportedOpcodes.NEXT_TRACK - | Request.SupportedOpcodes.FIRST_TRACK - | Request.SupportedOpcodes.LAST_TRACK - | Request.SupportedOpcodes.GOTO_TRACK - | Request.SupportedOpcodes.PREVIOUS_GROUP - | Request.SupportedOpcodes.NEXT_GROUP - | Request.SupportedOpcodes.FIRST_GROUP - | Request.SupportedOpcodes.LAST_GROUP; - byte[] ccc_val = registerForNotification - ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE.clone() - : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE.clone(); + Integer opcodes_supported = + Request.SupportedOpcodes.NONE + | Request.SupportedOpcodes.PLAY + | Request.SupportedOpcodes.PAUSE + | Request.SupportedOpcodes.FAST_REWIND + | Request.SupportedOpcodes.FAST_FORWARD + | Request.SupportedOpcodes.STOP + | Request.SupportedOpcodes.MOVE_RELATIVE + | Request.SupportedOpcodes.PREVIOUS_SEGMENT + | Request.SupportedOpcodes.NEXT_SEGMENT + | Request.SupportedOpcodes.FIRST_SEGMENT + | Request.SupportedOpcodes.LAST_SEGMENT + | Request.SupportedOpcodes.GOTO_SEGMENT + | Request.SupportedOpcodes.PREVIOUS_TRACK + | Request.SupportedOpcodes.NEXT_TRACK + | Request.SupportedOpcodes.FIRST_TRACK + | Request.SupportedOpcodes.LAST_TRACK + | Request.SupportedOpcodes.GOTO_TRACK + | Request.SupportedOpcodes.PREVIOUS_GROUP + | Request.SupportedOpcodes.NEXT_GROUP + | Request.SupportedOpcodes.FIRST_GROUP + | Request.SupportedOpcodes.LAST_GROUP; + byte[] ccc_val = + registerForNotification + ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE.clone() + : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE.clone(); int times_cnt = registerForNotification ? 1 : 0; int media_control_request_opcode = Request.Opcodes.MOVE_RELATIVE; @@ -746,8 +843,8 @@ public class MediaControlGattServiceTest { verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_TRACK_OBJ_ID); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.updateObjectID(ObjectIds.CURRENT_TRACK_OBJ_ID, obj_id); verify(mMockGattServer, times(times_cnt)) @@ -759,15 +856,15 @@ public class MediaControlGattServiceTest { verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_CURRENT_GROUP_OBJ_ID); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.updateObjectID(ObjectIds.CURRENT_GROUP_OBJ_ID, obj_id); verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_PARENT_GROUP_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_PARENT_GROUP_OBJ_ID); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.updateObjectID(ObjectIds.PARENT_GROUP_OBJ_ID, obj_id); verify(mMockGattServer, times(times_cnt)) @@ -780,31 +877,31 @@ public class MediaControlGattServiceTest { verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_MEDIA_CONTROL_POINT); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.setMediaControlRequestResult( - new Request(media_control_request_opcode, 0), - Request.Results.SUCCESS); + new Request(media_control_request_opcode, 0), Request.Results.SUCCESS); verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); + characteristic = + service.getCharacteristic( + MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.updateSupportedOpcodesChar(opcodes_supported, true); verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_SEARCH_RESULT_OBJ_ID); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_SEARCH_RESULT_OBJ_ID); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.updateObjectID(ObjectIds.SEARCH_RESULT_OBJ_ID, obj_id); verify(mMockGattServer, times(times_cnt)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - characteristic = service.getCharacteristic( - MediaControlGattService.UUID_SEARCH_CONTROL_POINT); + characteristic = + service.getCharacteristic(MediaControlGattService.UUID_SEARCH_CONTROL_POINT); prepareConnectedDevicesCccVal(characteristic, ccc_val); mMcpService.setSearchRequestResult(null, SearchRequest.Results.SUCCESS, obj_id); verify(mMockGattServer, times(times_cnt)) @@ -821,8 +918,12 @@ public class MediaControlGattServiceTest { testNotify(false); } - private void verifyMediaControlPointRequest(BluetoothGattService service, int opcode, - Integer value, int expectedGattResult, int invocation_count) { + private void verifyMediaControlPointRequest( + BluetoothGattService service, + int opcode, + Integer value, + int expectedGattResult, + int invocation_count) { BluetoothGattCharacteristic characteristic = service.getCharacteristic(MediaControlGattService.UUID_MEDIA_CONTROL_POINT); ByteBuffer bb; @@ -830,15 +931,17 @@ public class MediaControlGattServiceTest { if (expectedGattResult == BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH) { bb = ByteBuffer.allocate(6).order(ByteOrder.LITTLE_ENDIAN); } else { - bb = ByteBuffer.allocate(value != null ? (Integer.BYTES + Byte.BYTES) : Byte.BYTES) - .order(ByteOrder.LITTLE_ENDIAN); + bb = + ByteBuffer.allocate(value != null ? (Integer.BYTES + Byte.BYTES) : Byte.BYTES) + .order(ByteOrder.LITTLE_ENDIAN); } bb.put((byte) opcode); if (value != null) { bb.putInt(value); } - Assert.assertEquals(expectedGattResult, + Assert.assertEquals( + expectedGattResult, mMcpService.handleMediaControlPointRequest(mCurrentDevice, bb.array())); if (expectedGattResult == BluetoothGatt.GATT_SUCCESS) { @@ -851,81 +954,112 @@ public class MediaControlGattServiceTest { private void verifyMediaControlPointRequests(int expectedGattResult) { BluetoothGattService service = initAllFeaturesGattService(); int invocation_count = 1; - Integer opcodes_supported = Request.SupportedOpcodes.PLAY - | Request.SupportedOpcodes.PAUSE - | Request.SupportedOpcodes.FAST_REWIND - | Request.SupportedOpcodes.FAST_FORWARD - | Request.SupportedOpcodes.STOP - | Request.SupportedOpcodes.MOVE_RELATIVE - | Request.SupportedOpcodes.PREVIOUS_SEGMENT - | Request.SupportedOpcodes.NEXT_SEGMENT - | Request.SupportedOpcodes.FIRST_SEGMENT - | Request.SupportedOpcodes.LAST_SEGMENT - | Request.SupportedOpcodes.GOTO_SEGMENT - | Request.SupportedOpcodes.PREVIOUS_TRACK - | Request.SupportedOpcodes.NEXT_TRACK - | Request.SupportedOpcodes.FIRST_TRACK - | Request.SupportedOpcodes.LAST_TRACK - | Request.SupportedOpcodes.GOTO_TRACK - | Request.SupportedOpcodes.PREVIOUS_GROUP - | Request.SupportedOpcodes.NEXT_GROUP - | Request.SupportedOpcodes.FIRST_GROUP - | Request.SupportedOpcodes.LAST_GROUP - | Request.SupportedOpcodes.GOTO_GROUP; - - BluetoothGattCharacteristic characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); + Integer opcodes_supported = + Request.SupportedOpcodes.PLAY + | Request.SupportedOpcodes.PAUSE + | Request.SupportedOpcodes.FAST_REWIND + | Request.SupportedOpcodes.FAST_FORWARD + | Request.SupportedOpcodes.STOP + | Request.SupportedOpcodes.MOVE_RELATIVE + | Request.SupportedOpcodes.PREVIOUS_SEGMENT + | Request.SupportedOpcodes.NEXT_SEGMENT + | Request.SupportedOpcodes.FIRST_SEGMENT + | Request.SupportedOpcodes.LAST_SEGMENT + | Request.SupportedOpcodes.GOTO_SEGMENT + | Request.SupportedOpcodes.PREVIOUS_TRACK + | Request.SupportedOpcodes.NEXT_TRACK + | Request.SupportedOpcodes.FIRST_TRACK + | Request.SupportedOpcodes.LAST_TRACK + | Request.SupportedOpcodes.GOTO_TRACK + | Request.SupportedOpcodes.PREVIOUS_GROUP + | Request.SupportedOpcodes.NEXT_GROUP + | Request.SupportedOpcodes.FIRST_GROUP + | Request.SupportedOpcodes.LAST_GROUP + | Request.SupportedOpcodes.GOTO_GROUP; + + BluetoothGattCharacteristic characteristic = + service.getCharacteristic( + MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); prepareConnectedDevicesCccVal( characteristic, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE.clone()); mMcpService.updateSupportedOpcodesChar(opcodes_supported, true); verify(mMockGattServer, times(0)) .notifyCharacteristicChanged(eq(mCurrentDevice), eq(characteristic), eq(false)); - verifyMediaControlPointRequest(service, Request.Opcodes.PLAY, null, - expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.PAUSE, null, - expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.FAST_REWIND, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.FAST_FORWARD, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.STOP, null, - expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.MOVE_RELATIVE, - 100, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, - Request.Opcodes.PREVIOUS_SEGMENT, null, expectedGattResult, + verifyMediaControlPointRequest( + service, Request.Opcodes.PLAY, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.PAUSE, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.FAST_REWIND, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, + Request.Opcodes.FAST_FORWARD, + null, + expectedGattResult, + invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.STOP, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, + Request.Opcodes.MOVE_RELATIVE, + 100, + expectedGattResult, + invocation_count++); + verifyMediaControlPointRequest( + service, + Request.Opcodes.PREVIOUS_SEGMENT, + null, + expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.NEXT_SEGMENT, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.FIRST_SEGMENT, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.LAST_SEGMENT, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.GOTO_SEGMENT, - 10, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, - Request.Opcodes.PREVIOUS_TRACK, null, expectedGattResult, + verifyMediaControlPointRequest( + service, + Request.Opcodes.NEXT_SEGMENT, + null, + expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.NEXT_TRACK, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.FIRST_TRACK, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.LAST_TRACK, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.GOTO_TRACK, 7, - expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, - Request.Opcodes.PREVIOUS_GROUP, null, expectedGattResult, + verifyMediaControlPointRequest( + service, + Request.Opcodes.FIRST_SEGMENT, + null, + expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.NEXT_GROUP, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.FIRST_GROUP, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.LAST_GROUP, - null, expectedGattResult, invocation_count++); - verifyMediaControlPointRequest(service, Request.Opcodes.GOTO_GROUP, - 10, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, + Request.Opcodes.LAST_SEGMENT, + null, + expectedGattResult, + invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.GOTO_SEGMENT, 10, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, + Request.Opcodes.PREVIOUS_TRACK, + null, + expectedGattResult, + invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.NEXT_TRACK, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.FIRST_TRACK, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.LAST_TRACK, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.GOTO_TRACK, 7, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, + Request.Opcodes.PREVIOUS_GROUP, + null, + expectedGattResult, + invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.NEXT_GROUP, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.FIRST_GROUP, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.LAST_GROUP, null, expectedGattResult, invocation_count++); + verifyMediaControlPointRequest( + service, Request.Opcodes.GOTO_GROUP, 10, expectedGattResult, invocation_count++); } @Test @@ -942,8 +1076,7 @@ public class MediaControlGattServiceTest { public void testMediaControlPointRequestInvalid() { Integer opcodes_supported = Request.SupportedOpcodes.NONE; - Assert.assertFalse( - mMcpService.isOpcodeSupported(Request.Opcodes.PLAY)); + Assert.assertFalse(mMcpService.isOpcodeSupported(Request.Opcodes.PLAY)); } @Test @@ -952,8 +1085,8 @@ public class MediaControlGattServiceTest { BluetoothGattService service = initAllFeaturesGattService(); prepareConnectedDevice(); mMcpService.updateSupportedOpcodesChar(Request.SupportedOpcodes.PLAY, true); - verifyMediaControlPointRequest(service, Request.Opcodes.PLAY, null, - BluetoothGatt.GATT_SUCCESS, 1); + verifyMediaControlPointRequest( + service, Request.Opcodes.PLAY, null, BluetoothGatt.GATT_SUCCESS, 1); if (!Flags.leaudioBroadcastFeatureSupport()) { verify(mMockLeAudioService).setActiveDevice(any(BluetoothDevice.class)); } else { @@ -996,30 +1129,32 @@ public class MediaControlGattServiceTest { @Test public void testUpdateSupportedOpcodesChar() { BluetoothGattService service = initAllFeaturesGattService(); - Integer opcodes_supported = Request.SupportedOpcodes.PLAY - | Request.SupportedOpcodes.PAUSE - | Request.SupportedOpcodes.FAST_REWIND - | Request.SupportedOpcodes.FAST_FORWARD - | Request.SupportedOpcodes.STOP - | Request.SupportedOpcodes.MOVE_RELATIVE - | Request.SupportedOpcodes.PREVIOUS_SEGMENT - | Request.SupportedOpcodes.NEXT_SEGMENT - | Request.SupportedOpcodes.FIRST_SEGMENT - | Request.SupportedOpcodes.LAST_SEGMENT - | Request.SupportedOpcodes.GOTO_SEGMENT - | Request.SupportedOpcodes.PREVIOUS_TRACK - | Request.SupportedOpcodes.NEXT_TRACK - | Request.SupportedOpcodes.FIRST_TRACK - | Request.SupportedOpcodes.LAST_TRACK - | Request.SupportedOpcodes.GOTO_TRACK - | Request.SupportedOpcodes.PREVIOUS_GROUP - | Request.SupportedOpcodes.NEXT_GROUP - | Request.SupportedOpcodes.FIRST_GROUP - | Request.SupportedOpcodes.LAST_GROUP - | Request.SupportedOpcodes.GOTO_GROUP; - - BluetoothGattCharacteristic characteristic = service.getCharacteristic( - MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); + Integer opcodes_supported = + Request.SupportedOpcodes.PLAY + | Request.SupportedOpcodes.PAUSE + | Request.SupportedOpcodes.FAST_REWIND + | Request.SupportedOpcodes.FAST_FORWARD + | Request.SupportedOpcodes.STOP + | Request.SupportedOpcodes.MOVE_RELATIVE + | Request.SupportedOpcodes.PREVIOUS_SEGMENT + | Request.SupportedOpcodes.NEXT_SEGMENT + | Request.SupportedOpcodes.FIRST_SEGMENT + | Request.SupportedOpcodes.LAST_SEGMENT + | Request.SupportedOpcodes.GOTO_SEGMENT + | Request.SupportedOpcodes.PREVIOUS_TRACK + | Request.SupportedOpcodes.NEXT_TRACK + | Request.SupportedOpcodes.FIRST_TRACK + | Request.SupportedOpcodes.LAST_TRACK + | Request.SupportedOpcodes.GOTO_TRACK + | Request.SupportedOpcodes.PREVIOUS_GROUP + | Request.SupportedOpcodes.NEXT_GROUP + | Request.SupportedOpcodes.FIRST_GROUP + | Request.SupportedOpcodes.LAST_GROUP + | Request.SupportedOpcodes.GOTO_GROUP; + + BluetoothGattCharacteristic characteristic = + service.getCharacteristic( + MediaControlGattService.UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); prepareConnectedDevicesCccVal( characteristic, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE.clone()); @@ -1088,8 +1223,12 @@ public class MediaControlGattServiceTest { mCurrentDevice, 1, 0, characteristic); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any()); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); } @Test @@ -1185,8 +1324,12 @@ public class MediaControlGattServiceTest { mCurrentDevice, 1, characteristic, false, true, 0, bb.array()); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any()); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); } @Test @@ -1228,8 +1371,12 @@ public class MediaControlGattServiceTest { mMcpService.mServerCallback.onDescriptorReadRequest(mCurrentDevice, 1, 0, descriptor); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any()); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); } @Test @@ -1279,8 +1426,12 @@ public class MediaControlGattServiceTest { mCurrentDevice, 1, descriptor, false, true, 0, bb.array()); verify(mMockGattServer) - .sendResponse(eq(mCurrentDevice), eq(1), - eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any()); + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java index 7ce0374564d..07cbc9a9b9b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java @@ -129,7 +129,7 @@ public class MediaControlProfileTest { MediaControlProfile.setsMediaPlayerListForTesting(mMockMediaPlayerList); mMediaControlProfile = new MediaControlProfile(mMockMcpService); - //this is equivalent of what usually happens inside init class + // this is equivalent of what usually happens inside init class mMediaControlProfile.injectGattServiceForTesting(packageName, mMockGMcsService); mMediaControlProfile.onServiceInstanceRegistered(ServiceStatus.OK, mMockGMcsService); mMcpServiceCallbacks = mMediaControlProfile; @@ -173,21 +173,27 @@ public class MediaControlProfileTest { // No metadata equals no track duration mMockMediaData.metadata = null; - Assert.assertEquals(MediaControlGattServiceInterface.TRACK_DURATION_UNAVAILABLE, + Assert.assertEquals( + MediaControlGattServiceInterface.TRACK_DURATION_UNAVAILABLE, mMediaControlProfile.getCurrentTrackDuration()); } @Test public void testPlayerState2McsState() { - Assert.assertEquals(mMediaControlProfile.playerState2McsState(PlaybackState.STATE_PLAYING), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState(PlaybackState.STATE_PLAYING), MediaState.PLAYING); - Assert.assertEquals(mMediaControlProfile.playerState2McsState(PlaybackState.STATE_NONE), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState(PlaybackState.STATE_NONE), MediaState.INACTIVE); - Assert.assertEquals(mMediaControlProfile.playerState2McsState(PlaybackState.STATE_STOPPED), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState(PlaybackState.STATE_STOPPED), MediaState.PAUSED); - Assert.assertEquals(mMediaControlProfile.playerState2McsState(PlaybackState.STATE_PAUSED), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState(PlaybackState.STATE_PAUSED), MediaState.PAUSED); - Assert.assertEquals(mMediaControlProfile.playerState2McsState(PlaybackState.STATE_PLAYING), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState(PlaybackState.STATE_PLAYING), MediaState.PLAYING); Assert.assertEquals( mMediaControlProfile.playerState2McsState(PlaybackState.STATE_FAST_FORWARDING), @@ -198,7 +204,8 @@ public class MediaControlProfileTest { Assert.assertEquals( mMediaControlProfile.playerState2McsState(PlaybackState.STATE_BUFFERING), MediaState.PAUSED); - Assert.assertEquals(mMediaControlProfile.playerState2McsState(PlaybackState.STATE_ERROR), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState(PlaybackState.STATE_ERROR), MediaState.INACTIVE); Assert.assertEquals( mMediaControlProfile.playerState2McsState(PlaybackState.STATE_CONNECTING), @@ -209,8 +216,9 @@ public class MediaControlProfileTest { Assert.assertEquals( mMediaControlProfile.playerState2McsState(PlaybackState.STATE_SKIPPING_TO_NEXT), MediaState.PAUSED); - Assert.assertEquals(mMediaControlProfile.playerState2McsState( - PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM), + Assert.assertEquals( + mMediaControlProfile.playerState2McsState( + PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM), MediaState.PAUSED); } @@ -221,7 +229,8 @@ public class MediaControlProfileTest { float playback_speed = 1.5f; long update_time = 77; - Assert.assertEquals(mMcpServiceCallbacks.onGetCurrentTrackPosition(), + Assert.assertEquals( + mMcpServiceCallbacks.onGetCurrentTrackPosition(), MediaControlGattServiceInterface.TRACK_POSITION_UNAVAILABLE); PlaybackState.Builder bob = new PlaybackState.Builder(mMockMediaData.state); @@ -229,7 +238,8 @@ public class MediaControlProfileTest { mMockMediaData.state = bob.build(); doReturn(mMockMediaData.state).when(mMockMediaPlayerWrapper).getPlaybackState(); - Assert.assertNotEquals(mMcpServiceCallbacks.onGetCurrentTrackPosition(), + Assert.assertNotEquals( + mMcpServiceCallbacks.onGetCurrentTrackPosition(), MediaControlGattServiceInterface.TRACK_POSITION_UNAVAILABLE); } @@ -276,8 +286,7 @@ public class MediaControlProfileTest { verify(mMockMediaPlayerWrapper, timeout(100).times(times)).seekTo(positionCaptor.capture()); // position cannot be negative and bigger than track duration - if (position < 0) - Assert.assertEquals(positionCaptor.getValue().longValue(), 0); + if (position < 0) Assert.assertEquals(positionCaptor.getValue().longValue(), 0); else if (position > duration) { Assert.assertEquals(positionCaptor.getValue().longValue(), duration); } else { @@ -328,18 +337,22 @@ public class MediaControlProfileTest { @Test public void testHandleMediaControlRequest() { - long actions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PAUSE - | PlaybackState.ACTION_STOP | PlaybackState.ACTION_SKIP_TO_PREVIOUS - | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_REWIND - | PlaybackState.ACTION_FAST_FORWARD | PlaybackState.ACTION_SEEK_TO; + long actions = + PlaybackState.ACTION_PLAY + | PlaybackState.ACTION_PAUSE + | PlaybackState.ACTION_STOP + | PlaybackState.ACTION_SKIP_TO_PREVIOUS + | PlaybackState.ACTION_SKIP_TO_NEXT + | PlaybackState.ACTION_REWIND + | PlaybackState.ACTION_FAST_FORWARD + | PlaybackState.ACTION_SEEK_TO; long duration = 10; PlaybackState.Builder bob = new PlaybackState.Builder(mMockMediaData.state); bob.setActions(actions); mMockMediaData.state = bob.build(); - Request request = - new Request(Request.Opcodes.PLAY, 0); + Request request = new Request(Request.Opcodes.PLAY, 0); mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).playCurrent(); request = new Request(Request.Opcodes.PAUSE, 0); @@ -349,27 +362,22 @@ public class MediaControlProfileTest { mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).seekTo(0); verify(mMockMediaPlayerWrapper).stopCurrent(); - request = new Request( - Request.Opcodes.PREVIOUS_TRACK, 0); + request = new Request(Request.Opcodes.PREVIOUS_TRACK, 0); mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).skipToPrevious(); - request = new Request( - Request.Opcodes.NEXT_TRACK, 0); + request = new Request(Request.Opcodes.NEXT_TRACK, 0); mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).skipToNext(); - request = new Request( - Request.Opcodes.FAST_REWIND, 0); + request = new Request(Request.Opcodes.FAST_REWIND, 0); mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).rewind(); - request = new Request( - Request.Opcodes.FAST_FORWARD, 0); + request = new Request(Request.Opcodes.FAST_FORWARD, 0); mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).fastForward(); mMockMetadata.duration = Long.toString(duration); Assert.assertEquals(duration, mMediaControlProfile.getCurrentTrackDuration()); - request = new Request( - Request.Opcodes.MOVE_RELATIVE, 100); + request = new Request(Request.Opcodes.MOVE_RELATIVE, 100); mMcpServiceCallbacks.onMediaControlRequest(request); verify(mMockMediaPlayerWrapper, timeout(100)).seekTo(duration); @@ -410,26 +418,31 @@ public class MediaControlProfileTest { @Test public void testPlayerActions2McsSupportedOpcodes() { - long actions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PAUSE - | PlaybackState.ACTION_STOP | PlaybackState.ACTION_SKIP_TO_PREVIOUS - | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_REWIND - | PlaybackState.ACTION_FAST_FORWARD | PlaybackState.ACTION_SEEK_TO; - int opcodes_supported = Request.SupportedOpcodes.STOP - | Request.SupportedOpcodes.PAUSE - | Request.SupportedOpcodes.PLAY - | Request.SupportedOpcodes.FAST_REWIND - | Request.SupportedOpcodes.PREVIOUS_TRACK - | Request.SupportedOpcodes.NEXT_TRACK - | Request.SupportedOpcodes.FAST_FORWARD - | Request.SupportedOpcodes.MOVE_RELATIVE; + long actions = + PlaybackState.ACTION_PLAY + | PlaybackState.ACTION_PAUSE + | PlaybackState.ACTION_STOP + | PlaybackState.ACTION_SKIP_TO_PREVIOUS + | PlaybackState.ACTION_SKIP_TO_NEXT + | PlaybackState.ACTION_REWIND + | PlaybackState.ACTION_FAST_FORWARD + | PlaybackState.ACTION_SEEK_TO; + int opcodes_supported = + Request.SupportedOpcodes.STOP + | Request.SupportedOpcodes.PAUSE + | Request.SupportedOpcodes.PLAY + | Request.SupportedOpcodes.FAST_REWIND + | Request.SupportedOpcodes.PREVIOUS_TRACK + | Request.SupportedOpcodes.NEXT_TRACK + | Request.SupportedOpcodes.FAST_FORWARD + | Request.SupportedOpcodes.MOVE_RELATIVE; Assert.assertEquals( mMediaControlProfile.playerActions2McsSupportedOpcodes(actions), opcodes_supported); // Verify toggle-style play/pause control support actions = PlaybackState.ACTION_PLAY_PAUSE; - opcodes_supported = Request.SupportedOpcodes.PAUSE - | Request.SupportedOpcodes.PLAY; + opcodes_supported = Request.SupportedOpcodes.PAUSE | Request.SupportedOpcodes.PLAY; Assert.assertEquals( mMediaControlProfile.playerActions2McsSupportedOpcodes(actions), opcodes_supported); @@ -447,11 +460,18 @@ public class MediaControlProfileTest { mMockMediaData.state = bob.build(); doReturn(mMockMediaData.state).when(mMockMediaPlayerWrapper).getPlaybackState(); - PlayerStateField[] state_fields = new PlayerStateField[] {PlayerStateField.PLAYBACK_STATE, - PlayerStateField.TRACK_DURATION, PlayerStateField.PLAYBACK_SPEED, - PlayerStateField.SEEKING_SPEED, PlayerStateField.PLAYING_ORDER, - PlayerStateField.TRACK_POSITION, PlayerStateField.PLAYER_NAME, - PlayerStateField.PLAYING_ORDER_SUPPORTED, PlayerStateField.OPCODES_SUPPORTED}; + PlayerStateField[] state_fields = + new PlayerStateField[] { + PlayerStateField.PLAYBACK_STATE, + PlayerStateField.TRACK_DURATION, + PlayerStateField.PLAYBACK_SPEED, + PlayerStateField.SEEKING_SPEED, + PlayerStateField.PLAYING_ORDER, + PlayerStateField.TRACK_POSITION, + PlayerStateField.PLAYER_NAME, + PlayerStateField.PLAYING_ORDER_SUPPORTED, + PlayerStateField.OPCODES_SUPPORTED + }; mMcpServiceCallbacks.onPlayerStateRequest(state_fields); // First time called from ListCallback. Give some time to verify if post function @@ -489,13 +509,10 @@ public class MediaControlProfileTest { private void testGetSupportedPlayingOrder(boolean is_shuffle_set, boolean is_repeat_set) { int expected_value = SupportedPlayingOrder.IN_ORDER_ONCE; - if (is_repeat_set) - expected_value |= SupportedPlayingOrder.IN_ORDER_REPEAT; + if (is_repeat_set) expected_value |= SupportedPlayingOrder.IN_ORDER_REPEAT; if (is_shuffle_set) { - if (is_repeat_set) - expected_value |= SupportedPlayingOrder.SHUFFLE_REPEAT; - else - expected_value |= SupportedPlayingOrder.SHUFFLE_ONCE; + if (is_repeat_set) expected_value |= SupportedPlayingOrder.SHUFFLE_REPEAT; + else expected_value |= SupportedPlayingOrder.SHUFFLE_ONCE; } doReturn(is_shuffle_set).when(mMockMediaPlayerWrapper).isShuffleSupported(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexServer.java b/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexServer.java index a040001b9b8..85beb8e1162 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexServer.java +++ b/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexServer.java @@ -29,8 +29,8 @@ import java.io.IOException; * A fake obex server for testing obex clients. Test cases should implement *Validator functions to * validate input and return appropriate responses for individual tests. * - * Note: it is important to not perform any testing Assert operations within the validators as that - * would crash the testing framework. + *

Note: it is important to not perform any testing Assert operations within the validators as + * that would crash the testing framework. */ public abstract class FakeObexServer { @@ -52,8 +52,8 @@ public abstract class FakeObexServer { public abstract int onPutValidator(Operation op); - public abstract int onSetPathValidator(HeaderSet request, HeaderSet reply, - boolean backup, boolean create); + public abstract int onSetPathValidator( + HeaderSet request, HeaderSet reply, boolean backup, boolean create); class Server extends ServerRequestHandler { @@ -63,8 +63,7 @@ public abstract class FakeObexServer { } @Override - public void onDisconnect(final HeaderSet request, HeaderSet reply) { - } + public void onDisconnect(final HeaderSet request, HeaderSet reply) {} @Override public int onGet(final Operation op) { @@ -82,13 +81,15 @@ public abstract class FakeObexServer { } @Override - public int onSetPath(final HeaderSet request, HeaderSet reply, final boolean backup, + public int onSetPath( + final HeaderSet request, + HeaderSet reply, + final boolean backup, final boolean create) { return onSetPathValidator(request, reply, backup, create); } @Override - public void onClose() { - } + public void onClose() {} } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexTransport.java b/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexTransport.java index b2b6c165ff5..27e0a29d46c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexTransport.java +++ b/android/app/tests/unit/src/com/android/bluetooth/obex/FakeObexTransport.java @@ -27,9 +27,9 @@ import java.io.PipedInputStream; import java.io.PipedOutputStream; /** - * A fake obex transport used for testing Client/Server connections. - * The transport uses two pairs of pipes to route input from the client to the server, and back. - * The obex transport is of the simplest form, returning default values for everything. + * A fake obex transport used for testing Client/Server connections. The transport uses two pairs of + * pipes to route input from the client to the server, and back. The obex transport is of the + * simplest form, returning default values for everything. */ public class FakeObexTransport { ObexTransport mClientTransport; @@ -81,24 +81,19 @@ public class FakeObexTransport { } @Override - public void connect() throws IOException { - } + public void connect() throws IOException {} @Override - public void create() throws IOException { - } + public void create() throws IOException {} @Override - public void disconnect() throws IOException { - } + public void disconnect() throws IOException {} @Override - public void listen() throws IOException { - } + public void listen() throws IOException {} @Override - public void close() throws IOException { - } + public void close() throws IOException {} public boolean isConnected() throws IOException { return true; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java index 2c013fc766f..5fb0108b248 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java @@ -44,8 +44,22 @@ public class BluetoothOppBatchTest { @Before public void setUp() throws Exception { - mInitShareInfo = new BluetoothOppShareInfo(0, null, null, null, null, 0, - "00:11:22:33:44:55", 0, 0, BluetoothShare.STATUS_PENDING, 0, 0, 0, false); + mInitShareInfo = + new BluetoothOppShareInfo( + 0, + null, + null, + null, + null, + 0, + "00:11:22:33:44:55", + 0, + 0, + BluetoothShare.STATUS_PENDING, + 0, + 0, + 0, + false); mContext = InstrumentationRegistry.getInstrumentation().getContext(); mBluetoothOppBatch = new BluetoothOppBatch(mContext, mInitShareInfo); } @@ -62,24 +76,36 @@ public class BluetoothOppBatchTest { @Test public void addShare_shareInfoStoredCorrectly() { - BluetoothOppShareInfo newBluetoothOppShareInfo = new BluetoothOppShareInfo(1, null, null, - null, null, 0, "AA:BB:22:CD:E0:55", 0, 0, BluetoothShare.STATUS_PENDING, 0, 0, 0, - false); - - mBluetoothOppBatch.registerListener(new BluetoothOppBatch.BluetoothOppBatchListener() { - @Override - public void onShareAdded(int id) { - assertThat(id).isEqualTo(newBluetoothOppShareInfo.mId); - } - - @Override - public void onShareDeleted(int id) { - } - - @Override - public void onBatchCanceled() { - } - }); + BluetoothOppShareInfo newBluetoothOppShareInfo = + new BluetoothOppShareInfo( + 1, + null, + null, + null, + null, + 0, + "AA:BB:22:CD:E0:55", + 0, + 0, + BluetoothShare.STATUS_PENDING, + 0, + 0, + 0, + false); + + mBluetoothOppBatch.registerListener( + new BluetoothOppBatch.BluetoothOppBatchListener() { + @Override + public void onShareAdded(int id) { + assertThat(id).isEqualTo(newBluetoothOppShareInfo.mId); + } + + @Override + public void onShareDeleted(int id) {} + + @Override + public void onBatchCanceled() {} + }); assertThat(mBluetoothOppBatch.isEmpty()).isFalse(); assertThat(mBluetoothOppBatch.getNumShares()).isEqualTo(1); assertThat(mBluetoothOppBatch.hasShare(mInitShareInfo)).isTrue(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java index 3b5ede4f2ac..158a29caa91 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java @@ -77,15 +77,17 @@ public class BluetoothOppBtEnableActivityTest { @Test public void onCreate_clickOnEnable_launchEnablingActivity() { - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); activityScenario.onActivity( activity -> activity.mOppManager = mock(BluetoothOppManager.class)); onView(withText(mTargetContext.getText(R.string.bt_enable_ok).toString())) .inRoot(isDialog()) .perform(ViewActions.scrollTo()); - onView(withText(mTargetContext.getText(R.string.bt_enable_ok).toString())).inRoot( - isDialog()).check(matches(isDisplayed())).perform(click()); + onView(withText(mTargetContext.getText(R.string.bt_enable_ok).toString())) + .inRoot(isDialog()) + .check(matches(isDisplayed())) + .perform(click()); intended(hasComponent(BluetoothOppBtEnablingActivity.class.getName())); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java index 83003113f4f..4625a2e4a36 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java @@ -60,8 +60,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class BluetoothOppBtEnablingActivityTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Spy - BluetoothMethodProxy mBluetoothMethodProxy; + @Spy BluetoothMethodProxy mBluetoothMethodProxy; Intent mIntent; Context mTargetContext; @@ -104,13 +103,14 @@ public class BluetoothOppBtEnablingActivityTest { BluetoothOppBtEnablingActivity.sBtEnablingTimeoutMs = spedUpTimeoutValue; doReturn(false).when(mBluetoothMethodProxy).bluetoothAdapterIsEnabled(any()); - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); final BluetoothOppManager[] mOppManager = new BluetoothOppManager[1]; - activityScenario.onActivity(activity -> { - // Should be cancelled after timeout - mOppManager[0] = BluetoothOppManager.getInstance(activity); - }); + activityScenario.onActivity( + activity -> { + // Should be cancelled after timeout + mOppManager[0] = BluetoothOppManager.getInstance(activity); + }); Thread.sleep(spedUpTimeoutValue); assertThat(mOppManager[0].mSendingFlag).isEqualTo(false); assertActivityState(activityScenario, DESTROYED); @@ -119,8 +119,8 @@ public class BluetoothOppBtEnablingActivityTest { @Test public void onKeyDown_cancelProgress() throws Exception { doReturn(false).when(mBluetoothMethodProxy).bluetoothAdapterIsEnabled(any()); - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); AtomicBoolean finishCalled = new AtomicBoolean(false); @@ -141,16 +141,16 @@ public class BluetoothOppBtEnablingActivityTest { @Test public void onCreate_bluetoothAlreadyEnabled_finishImmediately() throws Exception { doReturn(true).when(mBluetoothMethodProxy).bluetoothAdapterIsEnabled(any()); - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); assertActivityState(activityScenario, DESTROYED); } @Test public void broadcastReceiver_onReceive_finishImmediately() throws Exception { doReturn(false).when(mBluetoothMethodProxy).bluetoothAdapterIsEnabled(any()); - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); AtomicBoolean finishCalled = new AtomicBoolean(false); activityScenario.onActivity( @@ -165,22 +165,25 @@ public class BluetoothOppBtEnablingActivityTest { } private void assertActivityState(ActivityScenario activityScenario, Lifecycle.State state) - throws Exception { + throws Exception { // TODO: Change this into an event driven systems Thread.sleep(3_000); assertThat(activityScenario.getState()).isEqualTo(state); } private void enableActivity(boolean enable) { - int enabledState = enable ? COMPONENT_ENABLED_STATE_ENABLED - : COMPONENT_ENABLED_STATE_DEFAULT; - - mTargetContext.getPackageManager().setApplicationEnabledSetting( - mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); - - ComponentName activityName = new ComponentName(mTargetContext, - BluetoothOppTransferActivity.class); - mTargetContext.getPackageManager().setComponentEnabledSetting( - activityName, enabledState, DONT_KILL_APP); + int enabledState = + enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT; + + mTargetContext + .getPackageManager() + .setApplicationEnabledSetting( + mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); + + ComponentName activityName = + new ComponentName(mTargetContext, BluetoothOppTransferActivity.class); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java index b27740bf0be..6c3fcbb66fe 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java @@ -56,16 +56,16 @@ public class BluetoothOppHandoverReceiverTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Spy - BluetoothMethodProxy mCallProxy = BluetoothMethodProxy.getInstance(); + @Spy BluetoothMethodProxy mCallProxy = BluetoothMethodProxy.getInstance(); @Before public void setUp() { mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); BluetoothMethodProxy.setInstanceForTesting(mCallProxy); doReturn(0).when(mCallProxy).contentResolverDelete(any(), any(Uri.class), any(), any()); - doReturn(null).when(mCallProxy).contentResolverInsert( - any(), eq(BluetoothShare.CONTENT_URI), any()); + doReturn(null) + .when(mCallProxy) + .contentResolverInsert(any(), eq(BluetoothShare.CONTENT_URI), any()); } @After @@ -78,8 +78,10 @@ public class BluetoothOppHandoverReceiverTest { Intent intent = new Intent(Constants.ACTION_HANDOVER_SEND); String address = "AA:BB:CC:DD:EE:FF"; Uri uri = Uri.parse("content:///abc/xyz.txt"); - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(Intent.EXTRA_STREAM, uri); intent.setType("text/plain"); @@ -92,8 +94,9 @@ public class BluetoothOppHandoverReceiverTest { // this will run BluetoothOppManager#startTransfer, which will then make // InsertShareInfoThread insert into content resolver - verify(mCallProxy, timeout(3_000).times(1)).contentResolverInsert(any(), - eq(BluetoothShare.CONTENT_URI), nullable(ContentValues.class)); + verify(mCallProxy, timeout(3_000).times(1)) + .contentResolverInsert( + any(), eq(BluetoothShare.CONTENT_URI), nullable(ContentValues.class)); BluetoothOppManager.setInstance(null); } @@ -101,12 +104,16 @@ public class BluetoothOppHandoverReceiverTest { public void onReceive_withActionHandoverSendMultiple_startTransfer() { Intent intent = new Intent(Constants.ACTION_HANDOVER_SEND_MULTIPLE); String address = "AA:BB:CC:DD:EE:FF"; - ArrayList uris = new ArrayList( - List.of(Uri.parse("content:///abc/xyz.txt"), - Uri.parse("content:///a/b/c/d/x/y/z.txt"), - Uri.parse("content:///123/456.txt"))); - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + ArrayList uris = + new ArrayList( + List.of( + Uri.parse("content:///abc/xyz.txt"), + Uri.parse("content:///a/b/c/d/x/y/z.txt"), + Uri.parse("content:///123/456.txt"))); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(Intent.EXTRA_STREAM, uris); intent.setType("text/plain"); @@ -119,8 +126,9 @@ public class BluetoothOppHandoverReceiverTest { // this will run BluetoothOppManager#startTransfer, which will then make // InsertShareInfoThread insert into content resolver - verify(mCallProxy, timeout(3_000).times(3)).contentResolverInsert(any(), - eq(BluetoothShare.CONTENT_URI), nullable(ContentValues.class)); + verify(mCallProxy, timeout(3_000).times(3)) + .contentResolverInsert( + any(), eq(BluetoothShare.CONTENT_URI), nullable(ContentValues.class)); BluetoothOppManager.setInstance(null); } @@ -128,14 +136,17 @@ public class BluetoothOppHandoverReceiverTest { public void onReceive_withActionStopHandover_triggerContentResolverDelete() { Intent intent = new Intent(Constants.ACTION_STOP_HANDOVER); String address = "AA:BB:CC:DD:EE:FF"; - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_ID, 0); new BluetoothOppHandoverReceiver().onReceive(mContext, intent); - verify(mCallProxy).contentResolverDelete(any(), any(), - nullable(String.class), nullable(String[].class)); + verify(mCallProxy) + .contentResolverDelete( + any(), any(), nullable(String.class), nullable(String[].class)); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java index 234a3134c42..7ee7bd25f4f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java @@ -73,8 +73,7 @@ public class BluetoothOppLauncherActivityTest { BluetoothMethodProxy mMethodProxy; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - BluetoothOppManager mBluetoothOppManager; + @Mock BluetoothOppManager mBluetoothOppManager; // Activity tests can sometimes flaky because of external factors like system dialog, etc. // making the expected Espresso's root not focused or the activity doesn't show up. @@ -85,8 +84,7 @@ public class BluetoothOppLauncherActivityTest { public void setUp() throws Exception { Assume.assumeTrue(BluetoothProperties.isProfileOppEnabled().orElse(false)); - mTargetContext = spy(new ContextWrapper( - ApplicationProvider.getApplicationContext())); + mTargetContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mMethodProxy = spy(BluetoothMethodProxy.getInstance()); BluetoothMethodProxy.setInstanceForTesting(mMethodProxy); @@ -112,16 +110,16 @@ public class BluetoothOppLauncherActivityTest { @Test public void onCreate_withNoAction_returnImmediately() throws Exception { - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); assertActivityState(activityScenario, Lifecycle.State.DESTROYED); } @Test public void onCreate_withActionSend_withoutMetadata_finishImmediately() throws Exception { mIntent.setAction(Intent.ACTION_SEND); - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); assertActivityState(activityScenario, Lifecycle.State.DESTROYED); } @@ -129,8 +127,8 @@ public class BluetoothOppLauncherActivityTest { public void onCreate_withActionSendMultiple_withoutMetadata_finishImmediately() throws Exception { mIntent.setAction(Intent.ACTION_SEND_MULTIPLE); - ActivityScenario activityScenario = ActivityScenario.launch( - mIntent); + ActivityScenario activityScenario = + ActivityScenario.launch(mIntent); assertActivityState(activityScenario, Lifecycle.State.DESTROYED); } @@ -186,10 +184,10 @@ public class BluetoothOppLauncherActivityTest { final String shareContent = "\na < b & c > a string to trigger pattern match with url: \r" + "www.google.com, phone number: +821023456798, and email: abc@test.com"; - scenario.onActivity(activity -> { - fileUri[0] = activity.createFileForSharedContent(activity, shareContent); - - }); + scenario.onActivity( + activity -> { + fileUri[0] = activity.createFileForSharedContent(activity, shareContent); + }); assertThat(fileUri[0].toString().endsWith(".html")).isTrue(); File file = new File(fileUri[0].getPath()); @@ -204,11 +202,13 @@ public class BluetoothOppLauncherActivityTest { // Unsupported action, the activity will stay without being finished right the way mIntent.setAction("unsupported-action"); ActivityScenario scenario = ActivityScenario.launch(mIntent); - doThrow(new IllegalArgumentException()).when(mBluetoothOppManager).saveSendingFileInfo( - any(), any(String.class), any(), any()); - scenario.onActivity(activity -> { - activity.sendFileInfo("text/plain", "content:///abc.txt", false, false); - }); + doThrow(new IllegalArgumentException()) + .when(mBluetoothOppManager) + .saveSendingFileInfo(any(), any(String.class), any(), any()); + scenario.onActivity( + activity -> { + activity.sendFileInfo("text/plain", "content:///abc.txt", false, false); + }); assertActivityState(scenario, Lifecycle.State.DESTROYED); } @@ -219,17 +219,19 @@ public class BluetoothOppLauncherActivityTest { assertThat(activityScenario.getState()).isEqualTo(state); } - private void enableActivity(boolean enable) { - int enabledState = enable ? COMPONENT_ENABLED_STATE_ENABLED - : COMPONENT_ENABLED_STATE_DEFAULT; - - mTargetContext.getPackageManager().setApplicationEnabledSetting( - mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); - - ComponentName activityName = new ComponentName(mTargetContext, - BluetoothOppLauncherActivity.class); - mTargetContext.getPackageManager().setComponentEnabledSetting( - activityName, enabledState, DONT_KILL_APP); + int enabledState = + enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT; + + mTargetContext + .getPackageManager() + .setApplicationEnabledSetting( + mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); + + ComponentName activityName = + new ComponentName(mTargetContext, BluetoothOppLauncherActivity.class); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java index 695703c1f39..77163fa53bc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java @@ -64,14 +64,17 @@ public class BluetoothOppManagerTest { @Before public void setUp() { - mContext = spy(new ContextWrapper( - InstrumentationRegistry.getInstrumentation().getTargetContext())); + mContext = + spy( + new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); mCallProxy = spy(BluetoothMethodProxy.getInstance()); BluetoothMethodProxy.setInstanceForTesting(mCallProxy); - doReturn(null).when(mCallProxy).contentResolverInsert( - any(), eq(BluetoothShare.CONTENT_URI), any()); + doReturn(null) + .when(mCallProxy) + .contentResolverInsert(any(), eq(BluetoothShare.CONTENT_URI), any()); Intents.init(); } @@ -88,54 +91,58 @@ public class BluetoothOppManagerTest { @Test public void - restoreApplicationData_afterSavingSingleSendingFileInfo_containsSendingFileInfoSaved() { + restoreApplicationData_afterSavingSingleSendingFileInfo_containsSendingFileInfoSaved() { BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext); bluetoothOppManager.mSendingFlag = true; - bluetoothOppManager.saveSendingFileInfo("text/plain", "content:///abc/xyz.txt", false, - true); + bluetoothOppManager.saveSendingFileInfo( + "text/plain", "content:///abc/xyz.txt", false, true); BluetoothOppManager.sInstance = null; - BluetoothOppManager restartedBluetoothOppManager = BluetoothOppManager.getInstance( - mContext); - assertThat(bluetoothOppManager.mSendingFlag).isEqualTo( - restartedBluetoothOppManager.mSendingFlag); - assertThat(bluetoothOppManager.mMultipleFlag).isEqualTo( - restartedBluetoothOppManager.mMultipleFlag); - assertThat(bluetoothOppManager.mUriOfSendingFile).isEqualTo( - restartedBluetoothOppManager.mUriOfSendingFile); - assertThat(bluetoothOppManager.mUrisOfSendingFiles).isEqualTo( - restartedBluetoothOppManager.mUrisOfSendingFiles); - assertThat(bluetoothOppManager.mMimeTypeOfSendingFile).isEqualTo( - restartedBluetoothOppManager.mMimeTypeOfSendingFile); - assertThat(bluetoothOppManager.mMimeTypeOfSendingFiles).isEqualTo( - restartedBluetoothOppManager.mMimeTypeOfSendingFiles); + BluetoothOppManager restartedBluetoothOppManager = + BluetoothOppManager.getInstance(mContext); + assertThat(bluetoothOppManager.mSendingFlag) + .isEqualTo(restartedBluetoothOppManager.mSendingFlag); + assertThat(bluetoothOppManager.mMultipleFlag) + .isEqualTo(restartedBluetoothOppManager.mMultipleFlag); + assertThat(bluetoothOppManager.mUriOfSendingFile) + .isEqualTo(restartedBluetoothOppManager.mUriOfSendingFile); + assertThat(bluetoothOppManager.mUrisOfSendingFiles) + .isEqualTo(restartedBluetoothOppManager.mUrisOfSendingFiles); + assertThat(bluetoothOppManager.mMimeTypeOfSendingFile) + .isEqualTo(restartedBluetoothOppManager.mMimeTypeOfSendingFile); + assertThat(bluetoothOppManager.mMimeTypeOfSendingFiles) + .isEqualTo(restartedBluetoothOppManager.mMimeTypeOfSendingFiles); } @Test public void - restoreApplicationData_afterSavingMultipleSendingFileInfo_containsSendingFileInfoSaved() { + restoreApplicationData_afterSavingMultipleSendingFileInfo_containsSendingFileInfoSaved() { BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext); bluetoothOppManager.mSendingFlag = true; - bluetoothOppManager.saveSendingFileInfo("text/plain", new ArrayList( - List.of(Uri.parse("content:///abc/xyz.txt"), Uri.parse("content:///123" - + "/456.txt"))), - false, true); + bluetoothOppManager.saveSendingFileInfo( + "text/plain", + new ArrayList( + List.of( + Uri.parse("content:///abc/xyz.txt"), + Uri.parse("content:///123" + "/456.txt"))), + false, + true); BluetoothOppManager.sInstance = null; - BluetoothOppManager restartedBluetoothOppManager = BluetoothOppManager.getInstance( - mContext); - assertThat(bluetoothOppManager.mSendingFlag).isEqualTo( - restartedBluetoothOppManager.mSendingFlag); - assertThat(bluetoothOppManager.mMultipleFlag).isEqualTo( - restartedBluetoothOppManager.mMultipleFlag); - assertThat(bluetoothOppManager.mUriOfSendingFile).isEqualTo( - restartedBluetoothOppManager.mUriOfSendingFile); - assertThat(bluetoothOppManager.mUrisOfSendingFiles).isEqualTo( - restartedBluetoothOppManager.mUrisOfSendingFiles); - assertThat(bluetoothOppManager.mMimeTypeOfSendingFile).isEqualTo( - restartedBluetoothOppManager.mMimeTypeOfSendingFile); - assertThat(bluetoothOppManager.mMimeTypeOfSendingFiles).isEqualTo( - restartedBluetoothOppManager.mMimeTypeOfSendingFiles); + BluetoothOppManager restartedBluetoothOppManager = + BluetoothOppManager.getInstance(mContext); + assertThat(bluetoothOppManager.mSendingFlag) + .isEqualTo(restartedBluetoothOppManager.mSendingFlag); + assertThat(bluetoothOppManager.mMultipleFlag) + .isEqualTo(restartedBluetoothOppManager.mMultipleFlag); + assertThat(bluetoothOppManager.mUriOfSendingFile) + .isEqualTo(restartedBluetoothOppManager.mUriOfSendingFile); + assertThat(bluetoothOppManager.mUrisOfSendingFiles) + .isEqualTo(restartedBluetoothOppManager.mUrisOfSendingFiles); + assertThat(bluetoothOppManager.mMimeTypeOfSendingFile) + .isEqualTo(restartedBluetoothOppManager.mMimeTypeOfSendingFile); + assertThat(bluetoothOppManager.mMimeTypeOfSendingFiles) + .isEqualTo(restartedBluetoothOppManager.mMimeTypeOfSendingFiles); } @Test @@ -165,30 +172,38 @@ public class BluetoothOppManagerTest { public void startTransfer_withMultipleUris_contentResolverInsertMultipleTimes() { BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext); String address = "AA:BB:CC:DD:EE:FF"; - bluetoothOppManager.saveSendingFileInfo("text/plain", new ArrayList( - List.of(Uri.parse("content:///abc/xyz.txt"), - Uri.parse("content:///a/b/c/d/x/y/z.docs"), - Uri.parse("content:///123/456.txt"))), false, true); - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + bluetoothOppManager.saveSendingFileInfo( + "text/plain", + new ArrayList( + List.of( + Uri.parse("content:///abc/xyz.txt"), + Uri.parse("content:///a/b/c/d/x/y/z.docs"), + Uri.parse("content:///123/456.txt"))), + false, + true); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); bluetoothOppManager.startTransfer(device); // add 2 files - verify(mCallProxy, timeout(5_000) - .times(3)).contentResolverInsert(any(), nullable(Uri.class), - nullable(ContentValues.class)); + verify(mCallProxy, timeout(5_000).times(3)) + .contentResolverInsert(any(), nullable(Uri.class), nullable(ContentValues.class)); } @Test public void startTransfer_withOneUri_contentResolverInsertOnce() { BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext); String address = "AA:BB:CC:DD:EE:FF"; - bluetoothOppManager.saveSendingFileInfo("text/plain", "content:///abc/xyz.txt", - false, true); - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + bluetoothOppManager.saveSendingFileInfo( + "text/plain", "content:///abc/xyz.txt", false, true); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); bluetoothOppManager.startTransfer(device); - verify(mCallProxy, timeout(5_000).times(1)).contentResolverInsert(any(), - nullable(Uri.class), nullable(ContentValues.class)); + verify(mCallProxy, timeout(5_000).times(1)) + .contentResolverInsert(any(), nullable(Uri.class), nullable(ContentValues.class)); } @Ignore("b/267270055") @@ -197,18 +212,21 @@ public class BluetoothOppManagerTest { throws InterruptedException { BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext); String address = "AA:BB:CC:DD:EE:FF"; - bluetoothOppManager.saveSendingFileInfo("text/plain", "content:///abc/xyz.txt", - false, true); - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + bluetoothOppManager.saveSendingFileInfo( + "text/plain", "content:///abc/xyz.txt", false, true); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); AtomicBoolean intended = new AtomicBoolean(false); - intending(anyIntent()).respondWithFunction( - intent -> { - // verify that at least one exceeding thread is blocked - intended.set(true); - return null; - }); + intending(anyIntent()) + .respondWithFunction( + intent -> { + // verify that at least one exceeding thread is blocked + intended.set(true); + return null; + }); // try flushing the transferring queue, for (int i = 0; i < ALLOWED_INSERT_SHARE_THREAD_NUMBER + 15; i++) { @@ -216,9 +234,8 @@ public class BluetoothOppManagerTest { } // success at least ALLOWED_INSERT_SHARE_THREAD_NUMBER times - verify(mCallProxy, - timeout(5_000).atLeast(ALLOWED_INSERT_SHARE_THREAD_NUMBER)).contentResolverInsert( - any(), nullable(Uri.class), nullable(ContentValues.class)); + verify(mCallProxy, timeout(5_000).atLeast(ALLOWED_INSERT_SHARE_THREAD_NUMBER)) + .contentResolverInsert(any(), nullable(Uri.class), nullable(ContentValues.class)); // there is at least a failed attempt assertThat(intended.get()).isTrue(); @@ -238,8 +255,8 @@ public class BluetoothOppManagerTest { BluetoothOppUtility.sSendFileMap.clear(); Uri uri = Uri.parse("content:///a/new/folder/abc/xyz.txt"); assertThat(BluetoothOppUtility.sSendFileMap.size()).isEqualTo(0); - BluetoothOppManager.getInstance(mContext).saveSendingFileInfo("text/plain", - uri.toString(), false, true); + BluetoothOppManager.getInstance(mContext) + .saveSendingFileInfo("text/plain", uri.toString(), false, true); assertThat(BluetoothOppUtility.sSendFileMap.size()).isEqualTo(1); BluetoothOppManager.getInstance(mContext).cleanUpSendingFileInfo(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java index ed4a086a6a2..9cdbf70e3b4 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java @@ -63,8 +63,7 @@ public class BluetoothOppNotificationTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - BluetoothMethodProxy mMethodProxy; + @Mock BluetoothMethodProxy mMethodProxy; Context mTargetContext; @@ -80,12 +79,12 @@ public class BluetoothOppNotificationTest { @Before public void setUp() throws Exception { - mTargetContext = spy(new ContextWrapper( - ApplicationProvider.getApplicationContext())); + mTargetContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); BluetoothMethodProxy.setInstanceForTesting(mMethodProxy); - InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> - mOppNotification = new BluetoothOppNotification(mTargetContext)); + InstrumentationRegistry.getInstrumentation() + .runOnMainSync( + () -> mOppNotification = new BluetoothOppNotification(mTargetContext)); Intents.init(); TestUtils.setUpUiTest(); @@ -93,12 +92,15 @@ public class BluetoothOppNotificationTest { UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).openNotification(); // Enable BluetoothOppReceiver and then check for dismissed notification - mReceiverName = new ComponentName(mTargetContext, - com.android.bluetooth.opp.BluetoothOppReceiver.class); - mPreviousState = mTargetContext.getPackageManager().getComponentEnabledSetting( - mReceiverName); - mTargetContext.getPackageManager().setComponentEnabledSetting( - mReceiverName, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); + mReceiverName = + new ComponentName( + mTargetContext, com.android.bluetooth.opp.BluetoothOppReceiver.class); + mPreviousState = + mTargetContext.getPackageManager().getComponentEnabledSetting(mReceiverName); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting( + mReceiverName, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); // clear all OPP notifications before each test mOppNotification.cancelOppNotifications(); @@ -113,8 +115,9 @@ public class BluetoothOppNotificationTest { BluetoothMethodProxy.setInstanceForTesting(null); Intents.release(); - mTargetContext.getPackageManager().setComponentEnabledSetting( - mReceiverName, mPreviousState, DONT_KILL_APP); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting(mReceiverName, mPreviousState, DONT_KILL_APP); // clear all OPP notifications after each test mOppNotification.cancelOppNotifications(); @@ -132,35 +135,67 @@ public class BluetoothOppNotificationTest { int confirmation = BluetoothShare.USER_CONFIRMATION_CONFIRMED; int confirmationHandoverInitiated = BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED; String destination = "AA:BB:CC:DD:EE:FF"; - MatrixCursor cursor = new MatrixCursor(new String[]{ - BluetoothShare.TIMESTAMP, BluetoothShare.DIRECTION, BluetoothShare._ID, - BluetoothShare.TOTAL_BYTES, BluetoothShare.CURRENT_BYTES, BluetoothShare._DATA, - BluetoothShare.FILENAME_HINT, BluetoothShare.USER_CONFIRMATION, - BluetoothShare.DESTINATION, BluetoothShare.STATUS - }); - cursor.addRow(new Object[]{ - timestamp, dir, id, total, current, null, null, confirmation, destination, status - }); - cursor.addRow(new Object[]{ - timestamp + 10L, dir, id, total, current, null, null, confirmationHandoverInitiated, - destination, status - }); - doReturn(cursor).when(mMethodProxy).contentResolverQuery(any(), - eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothShare.TIMESTAMP, + BluetoothShare.DIRECTION, + BluetoothShare._ID, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.CURRENT_BYTES, + BluetoothShare._DATA, + BluetoothShare.FILENAME_HINT, + BluetoothShare.USER_CONFIRMATION, + BluetoothShare.DESTINATION, + BluetoothShare.STATUS + }); + cursor.addRow( + new Object[] { + timestamp, + dir, + id, + total, + current, + null, + null, + confirmation, + destination, + status + }); + cursor.addRow( + new Object[] { + timestamp + 10L, + dir, + id, + total, + current, + null, + null, + confirmationHandoverInitiated, + destination, + status + }); + doReturn(cursor) + .when(mMethodProxy) + .contentResolverQuery( + any(), eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any()); mOppNotification.updateActiveNotification(); - //confirm handover case does broadcast - verify(mTargetContext).sendBroadcast(any(), eq(Constants.HANDOVER_STATUS_PERMISSION), - any()); + // confirm handover case does broadcast + verify(mTargetContext) + .sendBroadcast(any(), eq(Constants.HANDOVER_STATUS_PERMISSION), any()); - final UiDevice device = UiDevice.getInstance( - androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); + final UiDevice device = + UiDevice.getInstance( + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); device.openNotification(); - String titleString = mTargetContext.getString(R.string.notification_receiving, - mTargetContext.getString(R.string.unknown_file)); + String titleString = + mTargetContext.getString( + R.string.notification_receiving, + mTargetContext.getString(R.string.unknown_file)); device.wait(Until.hasObject(By.text(titleString)), TIMEOUT_MS); UiObject2 title = device.findObject(By.text(titleString)); assertThat(title).isNotNull(); @@ -179,26 +214,56 @@ public class BluetoothOppNotificationTest { long current = 100; int confirmation = BluetoothShare.USER_CONFIRMATION_CONFIRMED; String destination = "AA:BB:CC:DD:EE:FF"; - MatrixCursor cursor = new MatrixCursor(new String[]{ - BluetoothShare.TIMESTAMP, BluetoothShare.DIRECTION, BluetoothShare._ID, - BluetoothShare.TOTAL_BYTES, BluetoothShare.CURRENT_BYTES, BluetoothShare._DATA, - BluetoothShare.FILENAME_HINT, BluetoothShare.USER_CONFIRMATION, - BluetoothShare.DESTINATION, BluetoothShare.STATUS - }); - cursor.addRow(new Object[]{ - timestamp, dir, id, total, current, null, null, confirmation, destination, status - }); - cursor.addRow(new Object[]{ - timestamp + 10L, dir, id, total, current, null, null, confirmation, - destination, statusError - }); - doReturn(cursor).when(mMethodProxy).contentResolverQuery(any(), - eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothShare.TIMESTAMP, + BluetoothShare.DIRECTION, + BluetoothShare._ID, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.CURRENT_BYTES, + BluetoothShare._DATA, + BluetoothShare.FILENAME_HINT, + BluetoothShare.USER_CONFIRMATION, + BluetoothShare.DESTINATION, + BluetoothShare.STATUS + }); + cursor.addRow( + new Object[] { + timestamp, + dir, + id, + total, + current, + null, + null, + confirmation, + destination, + status + }); + cursor.addRow( + new Object[] { + timestamp + 10L, + dir, + id, + total, + current, + null, + null, + confirmation, + destination, + statusError + }); + doReturn(cursor) + .when(mMethodProxy) + .contentResolverQuery( + any(), eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any()); mOppNotification.updateCompletedNotification(); - final UiDevice device = UiDevice.getInstance( - androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); + final UiDevice device = + UiDevice.getInstance( + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); device.openNotification(); @@ -229,26 +294,56 @@ public class BluetoothOppNotificationTest { long current = 100; int confirmation = BluetoothShare.USER_CONFIRMATION_CONFIRMED; String destination = "AA:BB:CC:DD:EE:FF"; - MatrixCursor cursor = new MatrixCursor(new String[]{ - BluetoothShare.TIMESTAMP, BluetoothShare.DIRECTION, BluetoothShare._ID, - BluetoothShare.TOTAL_BYTES, BluetoothShare.CURRENT_BYTES, BluetoothShare._DATA, - BluetoothShare.FILENAME_HINT, BluetoothShare.USER_CONFIRMATION, - BluetoothShare.DESTINATION, BluetoothShare.STATUS - }); - cursor.addRow(new Object[]{ - timestamp, dir, id, total, current, null, null, confirmation, destination, status - }); - cursor.addRow(new Object[]{ - timestamp + 10L, dir, id, total, current, null, null, confirmation, - destination, statusError - }); - doReturn(cursor).when(mMethodProxy).contentResolverQuery(any(), - eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothShare.TIMESTAMP, + BluetoothShare.DIRECTION, + BluetoothShare._ID, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.CURRENT_BYTES, + BluetoothShare._DATA, + BluetoothShare.FILENAME_HINT, + BluetoothShare.USER_CONFIRMATION, + BluetoothShare.DESTINATION, + BluetoothShare.STATUS + }); + cursor.addRow( + new Object[] { + timestamp, + dir, + id, + total, + current, + null, + null, + confirmation, + destination, + status + }); + cursor.addRow( + new Object[] { + timestamp + 10L, + dir, + id, + total, + current, + null, + null, + confirmation, + destination, + statusError + }); + doReturn(cursor) + .when(mMethodProxy) + .contentResolverQuery( + any(), eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any()); mOppNotification.updateCompletedNotification(); - final UiDevice device = UiDevice.getInstance( - androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); + final UiDevice device = + UiDevice.getInstance( + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); device.openNotification(); @@ -282,44 +377,65 @@ public class BluetoothOppNotificationTest { mOppNotification.mNotificationMgr = spy(mOppNotification.mNotificationMgr); - MatrixCursor cursor = new MatrixCursor(new String[]{ - BluetoothShare.TIMESTAMP, BluetoothShare.DIRECTION, BluetoothShare._ID, - BluetoothShare.TOTAL_BYTES, BluetoothShare.CURRENT_BYTES, BluetoothShare._DATA, - BluetoothShare.FILENAME_HINT, BluetoothShare.USER_CONFIRMATION, BluetoothShare.URI, - BluetoothShare.DESTINATION, BluetoothShare.STATUS, BluetoothShare.MIMETYPE - }); - cursor.addRow(new Object[]{ - timestamp, dir, id, total, current, null, null, confirmation, url, destination, - status, mimeType - }); - doReturn(cursor).when(mMethodProxy).contentResolverQuery(any(), - eq(com.android.bluetooth.opp.BluetoothShare.CONTENT_URI), any(), any(), any(), - any()); + MatrixCursor cursor = + new MatrixCursor( + new String[] { + BluetoothShare.TIMESTAMP, BluetoothShare.DIRECTION, BluetoothShare._ID, + BluetoothShare.TOTAL_BYTES, BluetoothShare.CURRENT_BYTES, + BluetoothShare._DATA, + BluetoothShare.FILENAME_HINT, BluetoothShare.USER_CONFIRMATION, + BluetoothShare.URI, + BluetoothShare.DESTINATION, BluetoothShare.STATUS, + BluetoothShare.MIMETYPE + }); + cursor.addRow( + new Object[] { + timestamp, + dir, + id, + total, + current, + null, + null, + confirmation, + url, + destination, + status, + mimeType + }); + doReturn(cursor) + .when(mMethodProxy) + .contentResolverQuery( + any(), + eq(com.android.bluetooth.opp.BluetoothShare.CONTENT_URI), + any(), + any(), + any(), + any()); mOppNotification.updateIncomingFileConfirmNotification(); - final UiDevice device = UiDevice.getInstance( - androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); + final UiDevice device = + UiDevice.getInstance( + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()); - String titleString = mTargetContext.getString( - R.string.incoming_file_confirm_Notification_title); + String titleString = + mTargetContext.getString(R.string.incoming_file_confirm_Notification_title); - String confirmString = mTargetContext.getString( - R.string.incoming_file_confirm_ok); - String declineString = mTargetContext.getString( - R.string.incoming_file_confirm_cancel); + String confirmString = mTargetContext.getString(R.string.incoming_file_confirm_ok); + String declineString = mTargetContext.getString(R.string.incoming_file_confirm_cancel); device.wait(Until.hasObject(By.text(titleString)), TIMEOUT_MS); UiObject2 title = device.findObject(By.text(titleString)); UiObject2 buttonOk = device.findObject(By.text(confirmString)); // In AOSP, all actions' titles are converted into upper case - if(buttonOk == null) { + if (buttonOk == null) { buttonOk = device.findObject(By.text(confirmString.toUpperCase())); } UiObject2 buttonDecline = device.findObject(By.text(declineString)); // In AOSP, all actions' titles are converted into upper case - if(buttonDecline == null) { + if (buttonDecline == null) { buttonDecline = device.findObject(By.text(declineString.toUpperCase())); } @@ -343,4 +459,3 @@ public class BluetoothOppNotificationTest { assertThat(device.findObject(By.text(declineString.toUpperCase()))).isNull(); } } - diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java index 60a04b61494..e848b52c8f3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java @@ -61,12 +61,10 @@ import java.util.concurrent.TimeUnit; public class BluetoothOppObexClientSessionTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - BluetoothMethodProxy mMethodProxy; + @Mock BluetoothMethodProxy mMethodProxy; Context mTargetContext; - @Mock - BluetoothObexTransport mTransport; + @Mock BluetoothObexTransport mTransport; BluetoothOppObexClientSession mClientSession; @@ -104,11 +102,24 @@ public class BluetoothOppObexClientSessionTest { int currentBytes = 42; int timestamp = 123456789; boolean mediaScanned = false; - BluetoothOppShareInfo shareInfo = new BluetoothOppShareInfo(0, uri, hintString, filename, - mimetype, direction, destination, visibility, confirm, status, totalBytes, - currentBytes, timestamp, mediaScanned); - BluetoothOppSendFileInfo sendFileInfo = new BluetoothOppSendFileInfo( - filename, mimetype, totalBytes, null, status); + BluetoothOppShareInfo shareInfo = + new BluetoothOppShareInfo( + 0, + uri, + hintString, + filename, + mimetype, + direction, + destination, + visibility, + confirm, + status, + totalBytes, + currentBytes, + timestamp, + mediaScanned); + BluetoothOppSendFileInfo sendFileInfo = + new BluetoothOppSendFileInfo(filename, mimetype, totalBytes, null, status); BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); // throw exception so the session will not connect @@ -116,15 +127,17 @@ public class BluetoothOppObexClientSessionTest { doThrow(new IOException()).when(mTransport).openOutputStream(); CountDownLatch sessionCompletedLatch = new CountDownLatch(1); - mClientSession.start(new Handler(Looper.getMainLooper()) { - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - if (msg.what == MSG_SESSION_COMPLETE) { - sessionCompletedLatch.countDown(); - } - } - }, 1); + mClientSession.start( + new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + if (msg.what == MSG_SESSION_COMPLETE) { + sessionCompletedLatch.countDown(); + } + } + }, + 1); // make mWaitingForShare be false mClientSession.addShare(shareInfo); @@ -157,11 +170,24 @@ public class BluetoothOppObexClientSessionTest { int currentBytes = 42; int timestamp = 123456789; boolean mediaScanned = false; - BluetoothOppShareInfo shareInfo = new BluetoothOppShareInfo(0, uri, hintString, filename, - mimetype, direction, destination, visibility, confirm, status, totalBytes, - currentBytes, timestamp, mediaScanned); - BluetoothOppSendFileInfo sendFileInfo = new BluetoothOppSendFileInfo( - filename, mimetype, totalBytes, null, status); + BluetoothOppShareInfo shareInfo = + new BluetoothOppShareInfo( + 0, + uri, + hintString, + filename, + mimetype, + direction, + destination, + visibility, + confirm, + status, + totalBytes, + currentBytes, + timestamp, + mediaScanned); + BluetoothOppSendFileInfo sendFileInfo = + new BluetoothOppSendFileInfo(filename, mimetype, totalBytes, null, status); BluetoothOppObexClientSession.ClientThread thread = mClientSession @@ -174,7 +200,7 @@ public class BluetoothOppObexClientSessionTest { thread.mCs = new ClientSession(mTransport); thread.addShare(shareInfo); - //thread.mCs.put() will throw because the obexconnection is not connected + // thread.mCs.put() will throw because the obexconnection is not connected assertThat(thread.sendFile(sendFileInfo)).isEqualTo(BluetoothShare.STATUS_OBEX_DATA_ERROR); } @@ -206,8 +232,7 @@ public class BluetoothOppObexClientSessionTest { InputStream is = mock(InputStream.class); byte[] buffer = new byte[2]; int size = 10000; - doReturn(500, 500, -1).when(is).read(eq(buffer), anyInt(), - anyInt()); + doReturn(500, 500, -1).when(is).read(eq(buffer), anyInt(), anyInt()); assertThat(BluetoothOppObexClientSession.readFully(is, buffer, size)).isEqualTo(1000); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java index 2e5bf6383e9..6b45823e1ca 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java @@ -62,27 +62,24 @@ import java.io.OutputStream; public class BluetoothOppObexServerSessionTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - BluetoothMethodProxy mMethodProxy; + @Mock BluetoothMethodProxy mMethodProxy; Context mTargetContext; - @Mock - BluetoothObexTransport mTransport; + @Mock BluetoothObexTransport mTransport; - @Mock - BluetoothOppService mBluetoothOppService; - @Mock - Operation mOperation; + @Mock BluetoothOppService mBluetoothOppService; + @Mock Operation mOperation; BluetoothOppObexServerSession mServerSession; @Before public void setUp() throws IOException { - mTargetContext = spy( - new ContextWrapper( - InstrumentationRegistry.getInstrumentation().getTargetContext())); - mServerSession = new BluetoothOppObexServerSession(mTargetContext, mTransport, - mBluetoothOppService); + mTargetContext = + spy( + new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); + mServerSession = + new BluetoothOppObexServerSession(mTargetContext, mTransport, mBluetoothOppService); // to control the mServerSession.mSession InputStream input = mock(InputStream.class); @@ -101,8 +98,8 @@ public class BluetoothOppObexServerSessionTest { @Test public void constructor_createInstanceCorrectly() { - mServerSession = new BluetoothOppObexServerSession(mTargetContext, mTransport, - mBluetoothOppService); + mServerSession = + new BluetoothOppObexServerSession(mTargetContext, mTransport, mBluetoothOppService); assertThat(mServerSession.mBluetoothOppService).isEqualTo(mBluetoothOppService); assertThat(mServerSession.mTransport).isEqualTo(mTransport); assertThat(mServerSession.mContext).isEqualTo(mTargetContext); @@ -146,9 +143,22 @@ public class BluetoothOppObexServerSessionTest { int currentBytes = 42; int timestamp = 123456789; boolean mediaScanned = false; - BluetoothOppShareInfo info = new BluetoothOppShareInfo(0, uri, hintString, filename, - mimetype, direction, destination, visibility, confirm, status, totalBytes, - currentBytes, timestamp, mediaScanned); + BluetoothOppShareInfo info = + new BluetoothOppShareInfo( + 0, + uri, + hintString, + filename, + mimetype, + direction, + destination, + visibility, + confirm, + status, + totalBytes, + currentBytes, + timestamp, + mediaScanned); mServerSession.addShare(info); assertThat(mServerSession.mInfo).isEqualTo(info); @@ -176,8 +186,8 @@ public class BluetoothOppObexServerSessionTest { headerSet.setHeader(HeaderSet.NAME, name); headerSet.setHeader(HeaderSet.LENGTH, length); headerSet.setHeader(HeaderSet.TYPE, mimeType); - assertThat(mServerSession.onPut(mOperation)).isEqualTo( - ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED); + assertThat(mServerSession.onPut(mOperation)) + .isEqualTo(ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED); } @Test @@ -216,8 +226,8 @@ public class BluetoothOppObexServerSessionTest { headerSet.setHeader(HeaderSet.LENGTH, length); headerSet.setHeader(HeaderSet.TYPE, mimeType); doReturn(headerSet).when(mOperation).getReceivedHeader(); - assertThat(mServerSession.onPut(mOperation)).isEqualTo( - ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE); + assertThat(mServerSession.onPut(mOperation)) + .isEqualTo(ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE); } @Test @@ -228,7 +238,8 @@ public class BluetoothOppObexServerSessionTest { // unblock the server and remove timeout message // modify mInfo & mFileInfo, manipulate receiveFile() then return ResponseCodes.OBEX_HTTP_OK - Assume.assumeTrue("Ignore test when if there is not media mounted", + Assume.assumeTrue( + "Ignore test when if there is not media mounted", Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)); String name = "randomFile.txt"; long length = 10; @@ -245,9 +256,22 @@ public class BluetoothOppObexServerSessionTest { int currentBytes = 42; int timestamp = 123456789; boolean mediaScanned = false; - mServerSession.mInfo = new BluetoothOppShareInfo(0, uri, hint, name, - mimeType, direction, destination, visibility, confirm, status, totalBytes, - currentBytes, timestamp, mediaScanned); + mServerSession.mInfo = + new BluetoothOppShareInfo( + 0, + uri, + hint, + name, + mimeType, + direction, + destination, + visibility, + confirm, + status, + totalBytes, + currentBytes, + timestamp, + mediaScanned); mServerSession.mFileInfo = new BluetoothOppReceiveFileInfo(name, length, uri, status); HeaderSet headerSet = new HeaderSet(); @@ -256,20 +280,25 @@ public class BluetoothOppObexServerSessionTest { headerSet.setHeader(HeaderSet.TYPE, mimeType); doReturn(headerSet).when(mOperation).getReceivedHeader(); - doReturn(contentUri).when(mMethodProxy) + doReturn(contentUri) + .when(mMethodProxy) .contentResolverInsert(any(), eq(BluetoothShare.CONTENT_URI), any()); // unblocking the session mServerSession.unblock(); mServerSession.mAccepted = BluetoothShare.USER_CONFIRMATION_CONFIRMED; Handler handler = mock(Handler.class); - doAnswer(arg -> { - mServerSession.unblock(); - // to ignore removeMessage, which is not mockable - mServerSession.mTimeoutMsgSent = false; - return true; - }).when(handler).sendMessageAtTime( - argThat(arg -> arg.what == BluetoothOppObexSession.MSG_CONNECT_TIMEOUT), anyLong()); + doAnswer( + arg -> { + mServerSession.unblock(); + // to ignore removeMessage, which is not mockable + mServerSession.mTimeoutMsgSent = false; + return true; + }) + .when(handler) + .sendMessageAtTime( + argThat(arg -> arg.what == BluetoothOppObexSession.MSG_CONNECT_TIMEOUT), + anyLong()); mServerSession.start(handler, 0); // manipulate ReceiveFile @@ -289,8 +318,8 @@ public class BluetoothOppObexServerSessionTest { HeaderSet reply = new HeaderSet(); byte[] target = new byte[10]; request.setHeader(HeaderSet.TARGET, target); - assertThat(mServerSession.onConnect(request, reply)).isEqualTo( - ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE); + assertThat(mServerSession.onConnect(request, reply)) + .isEqualTo(ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE); } @Test @@ -298,12 +327,13 @@ public class BluetoothOppObexServerSessionTest { HeaderSet request = new HeaderSet(); HeaderSet reply = new HeaderSet(); request.setHeader(HeaderSet.TARGET, null); - BluetoothOppManager bluetoothOppManager = spy( - BluetoothOppManager.getInstance(mTargetContext)); + BluetoothOppManager bluetoothOppManager = + spy(BluetoothOppManager.getInstance(mTargetContext)); BluetoothOppManager.setInstance(bluetoothOppManager); doReturn(true).when(bluetoothOppManager).isAcceptlisted(any()); - doNothing().when(mTargetContext).sendBroadcast(any(), - eq(Constants.HANDOVER_STATUS_PERMISSION), any()); + doNothing() + .when(mTargetContext) + .sendBroadcast(any(), eq(Constants.HANDOVER_STATUS_PERMISSION), any()); assertThat(mServerSession.onConnect(request, reply)).isEqualTo(ResponseCodes.OBEX_HTTP_OK); BluetoothOppManager.setInstance(null); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java index fa690958bc1..6ec5566961a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java @@ -48,14 +48,17 @@ public class BluetoothOppPreferenceTest { @Before public void setUp() { - mContext = spy(new ContextWrapper( - InstrumentationRegistry.getInstrumentation().getTargetContext())); + mContext = + spy( + new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); mCallProxy = spy(BluetoothMethodProxy.getInstance()); BluetoothMethodProxy.setInstanceForTesting(mCallProxy); - doReturn(null).when(mCallProxy).contentResolverInsert( - any(), eq(BluetoothShare.CONTENT_URI), any()); + doReturn(null) + .when(mCallProxy) + .contentResolverInsert(any(), eq(BluetoothShare.CONTENT_URI), any()); } @After @@ -75,13 +78,14 @@ public class BluetoothOppPreferenceTest { public void setNameAndGetNameAndRemoveName_setsAndGetsAndRemovesNameCorrectly() { String address = "AA:BB:CC:DD:EE:FF"; String name = "randomName"; - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); BluetoothOppPreference.getInstance(mContext).setName(device, name); assertThat(BluetoothOppPreference.getInstance(mContext).getName(device)).isEqualTo(name); - // Undo the change so this will not be saved on share preference BluetoothOppPreference.getInstance(mContext).removeName(device); assertThat(BluetoothOppPreference.getInstance(mContext).getName(device)).isNull(); @@ -92,15 +96,17 @@ public class BluetoothOppPreferenceTest { String address = "AA:BB:CC:DD:EE:FF"; int uuid = 1234; int channel = 78910; - BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class)) - .getAdapter().getRemoteDevice(address); + BluetoothDevice device = + (mContext.getSystemService(BluetoothManager.class)) + .getAdapter() + .getRemoteDevice(address); BluetoothOppPreference.getInstance(mContext).setChannel(device, uuid, channel); - assertThat(BluetoothOppPreference.getInstance(mContext).getChannel(device, uuid)).isEqualTo( - channel); + assertThat(BluetoothOppPreference.getInstance(mContext).getChannel(device, uuid)) + .isEqualTo(channel); // Undo the change so this will not be saved on share preference BluetoothOppPreference.getInstance(mContext).removeChannel(device, uuid); - assertThat(BluetoothOppPreference.getInstance(mContext).getChannel(device, uuid)).isEqualTo( - -1); + assertThat(BluetoothOppPreference.getInstance(mContext).getChannel(device, uuid)) + .isEqualTo(-1); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java index e0254948f7c..07cea67691d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java @@ -50,14 +50,17 @@ public class BluetoothOppReceiveFileInfoTest { @Before public void setUp() { - mContext = spy(new ContextWrapper( - InstrumentationRegistry.getInstrumentation().getTargetContext())); + mContext = + spy( + new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); mCallProxy = spy(BluetoothMethodProxy.getInstance()); BluetoothMethodProxy.setInstanceForTesting(mCallProxy); - doReturn(null).when(mCallProxy).contentResolverInsert( - any(), eq(BluetoothShare.CONTENT_URI), any()); + doReturn(null) + .when(mCallProxy) + .contentResolverInsert(any(), eq(BluetoothShare.CONTENT_URI), any()); } @After @@ -103,21 +106,32 @@ public class BluetoothOppReceiveFileInfoTest { @Test public void generateFileInfo_wrongHint_fileError() { - Assume.assumeTrue("Ignore test when if there is no media mounted", + Assume.assumeTrue( + "Ignore test when if there is no media mounted", Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)); int id = 0; long fileLength = 100; String hint = "content:///arandomhint/"; String mimeType = "text/plain"; - mCursor = new MatrixCursor( - new String[]{BluetoothShare.FILENAME_HINT, BluetoothShare.TOTAL_BYTES, - BluetoothShare.MIMETYPE}); - mCursor.addRow(new Object[]{hint, fileLength, mimeType}); - - doReturn(mCursor).when(mCallProxy).contentResolverQuery( - any(), eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), any(), any(), any(), - any()); + mCursor = + new MatrixCursor( + new String[] { + BluetoothShare.FILENAME_HINT, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.MIMETYPE + }); + mCursor.addRow(new Object[] {hint, fileLength, mimeType}); + + doReturn(mCursor) + .when(mCallProxy) + .contentResolverQuery( + any(), + eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), + any(), + any(), + any(), + any()); BluetoothOppReceiveFileInfo info = BluetoothOppReceiveFileInfo.generateFileInfo(mContext, id); @@ -127,7 +141,8 @@ public class BluetoothOppReceiveFileInfoTest { @Test public void generateFileInfo_noMediaMounted_noSdcardError() { - Assume.assumeTrue("Ignore test when if there is media mounted", + Assume.assumeTrue( + "Ignore test when if there is media mounted", !Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)); int id = 0; @@ -139,24 +154,36 @@ public class BluetoothOppReceiveFileInfoTest { @Test public void generateFileInfo_noInsertUri_returnFileError() { - Assume.assumeTrue("Ignore test when if there is not media mounted", + Assume.assumeTrue( + "Ignore test when if there is not media mounted", Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)); int id = 0; long fileLength = 100; String hint = "content:///arandomhint.txt"; String mimeType = "text/plain"; - mCursor = new MatrixCursor( - new String[]{BluetoothShare.FILENAME_HINT, BluetoothShare.TOTAL_BYTES, - BluetoothShare.MIMETYPE}); - mCursor.addRow(new Object[]{hint, fileLength, mimeType}); - - doReturn(mCursor).when(mCallProxy).contentResolverQuery( - any(), eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), any(), any(), any(), - any()); - - doReturn(null).when(mCallProxy).contentResolverInsert( - any(), eq(MediaStore.Downloads.EXTERNAL_CONTENT_URI), any()); + mCursor = + new MatrixCursor( + new String[] { + BluetoothShare.FILENAME_HINT, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.MIMETYPE + }); + mCursor.addRow(new Object[] {hint, fileLength, mimeType}); + + doReturn(mCursor) + .when(mCallProxy) + .contentResolverQuery( + any(), + eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), + any(), + any(), + any(), + any()); + + doReturn(null) + .when(mCallProxy) + .contentResolverInsert(any(), eq(MediaStore.Downloads.EXTERNAL_CONTENT_URI), any()); BluetoothOppReceiveFileInfo info = BluetoothOppReceiveFileInfo.generateFileInfo(mContext, id); @@ -166,7 +193,8 @@ public class BluetoothOppReceiveFileInfoTest { @Test public void generateFileInfo_withInsertUri_workCorrectly() { - Assume.assumeTrue("Ignore test when if there is not media mounted", + Assume.assumeTrue( + "Ignore test when if there is not media mounted", Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)); int id = 0; long fileLength = 100; @@ -174,17 +202,28 @@ public class BluetoothOppReceiveFileInfoTest { String mimeType = "text/plain"; Uri insertUri = Uri.parse("content:///abc/xyz"); - mCursor = new MatrixCursor( - new String[]{BluetoothShare.FILENAME_HINT, BluetoothShare.TOTAL_BYTES, - BluetoothShare.MIMETYPE}); - mCursor.addRow(new Object[]{hint, fileLength, mimeType}); - - doReturn(mCursor).when(mCallProxy).contentResolverQuery( - any(), eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), any(), any(), any(), - any()); - - doReturn(insertUri).when(mCallProxy).contentResolverInsert( - any(), eq(MediaStore.Downloads.EXTERNAL_CONTENT_URI), any()); + mCursor = + new MatrixCursor( + new String[] { + BluetoothShare.FILENAME_HINT, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.MIMETYPE + }); + mCursor.addRow(new Object[] {hint, fileLength, mimeType}); + + doReturn(mCursor) + .when(mCallProxy) + .contentResolverQuery( + any(), + eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), + any(), + any(), + any(), + any()); + + doReturn(insertUri) + .when(mCallProxy) + .contentResolverInsert(any(), eq(MediaStore.Downloads.EXTERNAL_CONTENT_URI), any()); assertThat(mCursor.moveToFirst()).isTrue(); @@ -198,7 +237,8 @@ public class BluetoothOppReceiveFileInfoTest { @Test public void generateFileInfo_longFileName_trimFileName() { - Assume.assumeTrue("Ignore test when if there is not media mounted", + Assume.assumeTrue( + "Ignore test when if there is not media mounted", Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)); int id = 0; long fileLength = 100; @@ -206,17 +246,28 @@ public class BluetoothOppReceiveFileInfoTest { String mimeType = "text/plain"; Uri insertUri = Uri.parse("content:///abc/xyz"); - mCursor = new MatrixCursor( - new String[]{BluetoothShare.FILENAME_HINT, BluetoothShare.TOTAL_BYTES, - BluetoothShare.MIMETYPE}); - mCursor.addRow(new Object[]{hint, fileLength, mimeType}); - - doReturn(mCursor).when(mCallProxy).contentResolverQuery( - any(), eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), any(), any(), any(), - any()); - - doReturn(insertUri).when(mCallProxy).contentResolverInsert( - any(), eq(MediaStore.Downloads.EXTERNAL_CONTENT_URI), any()); + mCursor = + new MatrixCursor( + new String[] { + BluetoothShare.FILENAME_HINT, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.MIMETYPE + }); + mCursor.addRow(new Object[] {hint, fileLength, mimeType}); + + doReturn(mCursor) + .when(mCallProxy) + .contentResolverQuery( + any(), + eq(Uri.parse(BluetoothShare.CONTENT_URI + "/" + id)), + any(), + any(), + any(), + any()); + + doReturn(insertUri) + .when(mCallProxy) + .contentResolverInsert(any(), eq(MediaStore.Downloads.EXTERNAL_CONTENT_URI), any()); assertThat(mCursor.moveToFirst()).isTrue(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java index b47cbd99b8b..7b6c5f73444 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java @@ -77,14 +77,15 @@ public class BluetoothOppReceiverTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - BluetoothMethodProxy mBluetoothMethodProxy; + @Mock BluetoothMethodProxy mBluetoothMethodProxy; BluetoothOppReceiver mReceiver; @Before public void setUp() throws Exception { - mContext = spy(new ContextWrapper( - InstrumentationRegistry.getInstrumentation().getTargetContext())); + mContext = + spy( + new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); // mock instance so query/insert/update/etc. will not be executed BluetoothMethodProxy.setInstanceForTesting(mBluetoothMethodProxy); @@ -110,8 +111,10 @@ public class BluetoothOppReceiverTest { BluetoothOppManager bluetoothOppManager = spy(BluetoothOppManager.getInstance(mContext)); BluetoothOppManager.setInstance(bluetoothOppManager); String address = "AA:BB:CC:DD:EE:FF"; - BluetoothDevice device = mContext.getSystemService(BluetoothManager.class) - .getAdapter().getRemoteDevice(address); + BluetoothDevice device = + mContext.getSystemService(BluetoothManager.class) + .getAdapter() + .getRemoteDevice(address); Intent intent = new Intent(); intent.setAction(BluetoothDevicePicker.ACTION_DEVICE_SELECTED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); @@ -153,9 +156,17 @@ public class BluetoothOppReceiverTest { intent.setAction(Constants.ACTION_ACCEPT); intent.setData(uri); mReceiver.onReceive(mContext, intent); - verify(mBluetoothMethodProxy).contentResolverUpdate(any(), eq(uri), argThat(arg -> - Objects.equal(BluetoothShare.USER_CONFIRMATION_CONFIRMED, - arg.get(BluetoothShare.USER_CONFIRMATION))), any(), any()); + verify(mBluetoothMethodProxy) + .contentResolverUpdate( + any(), + eq(uri), + argThat( + arg -> + Objects.equal( + BluetoothShare.USER_CONFIRMATION_CONFIRMED, + arg.get(BluetoothShare.USER_CONFIRMATION))), + any(), + any()); } @Test @@ -165,9 +176,17 @@ public class BluetoothOppReceiverTest { intent.setAction(Constants.ACTION_DECLINE); intent.setData(uri); mReceiver.onReceive(mContext, intent); - verify(mBluetoothMethodProxy).contentResolverUpdate(any(), eq(uri), argThat(arg -> - Objects.equal(BluetoothShare.USER_CONFIRMATION_DENIED, - arg.get(BluetoothShare.USER_CONFIRMATION))), any(), any()); + verify(mBluetoothMethodProxy) + .contentResolverUpdate( + any(), + eq(uri), + argThat( + arg -> + Objects.equal( + BluetoothShare.USER_CONFIRMATION_DENIED, + arg.get(BluetoothShare.USER_CONFIRMATION))), + any(), + any()); } @Test @@ -217,26 +236,40 @@ public class BluetoothOppReceiverTest { public void onReceive_withActionHide_contentUpdate() { List cursorMockDataList; Cursor cursor = mock(Cursor.class); - cursorMockDataList = new ArrayList<>(List.of( - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.VISIBILITY, 0, - BluetoothShare.VISIBILITY_VISIBLE), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.USER_CONFIRMATION, 1, - BluetoothShare.USER_CONFIRMATION_PENDING) - )); + cursorMockDataList = + new ArrayList<>( + List.of( + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.VISIBILITY, + 0, + BluetoothShare.VISIBILITY_VISIBLE), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.USER_CONFIRMATION, + 1, + BluetoothShare.USER_CONFIRMATION_PENDING))); BluetoothOppTestUtils.setUpMockCursor(cursor, cursorMockDataList); - doReturn(cursor).when(mBluetoothMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any(), any()); + doReturn(cursor) + .when(mBluetoothMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); doReturn(true).when(cursor).moveToFirst(); Intent intent = new Intent(); intent.setAction(Constants.ACTION_HIDE); mReceiver.onReceive(mContext, intent); - verify(mBluetoothMethodProxy).contentResolverUpdate(any(), any(), - argThat(arg -> Objects.equal(BluetoothShare.VISIBILITY_HIDDEN, - arg.get(BluetoothShare.VISIBILITY))), any(), any()); + verify(mBluetoothMethodProxy) + .contentResolverUpdate( + any(), + any(), + argThat( + arg -> + Objects.equal( + BluetoothShare.VISIBILITY_HIDDEN, + arg.get(BluetoothShare.VISIBILITY))), + any(), + any()); } @Test @@ -245,9 +278,17 @@ public class BluetoothOppReceiverTest { Intent intent = new Intent(); intent.setAction(Constants.ACTION_COMPLETE_HIDE); mReceiver.onReceive(mContext, intent); - verify(mBluetoothMethodProxy).contentResolverUpdate(any(), eq(BluetoothShare.CONTENT_URI), - argThat(arg -> Objects.equal(BluetoothShare.VISIBILITY_HIDDEN, - arg.get(BluetoothShare.VISIBILITY))), any(), any()); + verify(mBluetoothMethodProxy) + .contentResolverUpdate( + any(), + eq(BluetoothShare.CONTENT_URI), + argThat( + arg -> + Objects.equal( + BluetoothShare.VISIBILITY_HIDDEN, + arg.get(BluetoothShare.VISIBILITY))), + any(), + any()); } @Test @@ -297,31 +338,43 @@ public class BluetoothOppReceiverTest { String destinationValue = "AA:BB:CC:00:11:22"; String fileTypeValue = "text/plain"; - cursorMockDataList = new ArrayList<>(List.of( - new BluetoothOppTestUtils.CursorMockData(BluetoothShare._ID, 0, idValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.STATUS, 1, - BluetoothShare.STATUS_SUCCESS), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DIRECTION, 2, - BluetoothShare.DIRECTION_OUTBOUND), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 100), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.MIMETYPE, 5, fileTypeValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TIMESTAMP, 6, - timestampValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DESTINATION, 7, - destinationValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare._DATA, 8, null), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.FILENAME_HINT, 9, null), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.URI, 10, - "content://textfile.txt"), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.USER_CONFIRMATION, 11, - BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) - )); + cursorMockDataList = + new ArrayList<>( + List.of( + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare._ID, 0, idValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.STATUS, 1, BluetoothShare.STATUS_SUCCESS), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.DIRECTION, + 2, + BluetoothShare.DIRECTION_OUTBOUND), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.TOTAL_BYTES, 3, 100), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.CURRENT_BYTES, 4, 100), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.MIMETYPE, 5, fileTypeValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.TIMESTAMP, 6, timestampValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.DESTINATION, 7, destinationValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare._DATA, 8, null), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.FILENAME_HINT, 9, null), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.URI, 10, "content://textfile.txt"), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.USER_CONFIRMATION, + 11, + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED))); BluetoothOppTestUtils.setUpMockCursor(cursor, cursorMockDataList); - doReturn(cursor).when(mBluetoothMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any(), any()); + doReturn(cursor) + .when(mBluetoothMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); doReturn(true).when(cursor).moveToFirst(); Intent intent = new Intent(); @@ -341,31 +394,43 @@ public class BluetoothOppReceiverTest { String destinationValue = "AA:BB:CC:00:11:22"; String fileTypeValue = "text/plain"; - cursorMockDataList = new ArrayList<>(List.of( - new BluetoothOppTestUtils.CursorMockData(BluetoothShare._ID, 0, idValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.STATUS, 1, - BluetoothShare.STATUS_SUCCESS), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DIRECTION, 2, - BluetoothShare.DIRECTION_OUTBOUND), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 100), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.MIMETYPE, 5, fileTypeValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TIMESTAMP, 6, - timestampValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DESTINATION, 7, - destinationValue), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare._DATA, 8, null), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.FILENAME_HINT, 9, null), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.URI, 10, - "content://textfile.txt"), - new BluetoothOppTestUtils.CursorMockData(BluetoothShare.USER_CONFIRMATION, 11, - BluetoothShare.USER_CONFIRMATION_CONFIRMED) - )); + cursorMockDataList = + new ArrayList<>( + List.of( + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare._ID, 0, idValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.STATUS, 1, BluetoothShare.STATUS_SUCCESS), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.DIRECTION, + 2, + BluetoothShare.DIRECTION_OUTBOUND), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.TOTAL_BYTES, 3, 100), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.CURRENT_BYTES, 4, 100), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.MIMETYPE, 5, fileTypeValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.TIMESTAMP, 6, timestampValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.DESTINATION, 7, destinationValue), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare._DATA, 8, null), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.FILENAME_HINT, 9, null), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.URI, 10, "content://textfile.txt"), + new BluetoothOppTestUtils.CursorMockData( + BluetoothShare.USER_CONFIRMATION, + 11, + BluetoothShare.USER_CONFIRMATION_CONFIRMED))); BluetoothOppTestUtils.setUpMockCursor(cursor, cursorMockDataList); - doReturn(cursor).when(mBluetoothMethodProxy).contentResolverQuery(any(), any(), any(), - any(), any(), any()); + doReturn(cursor) + .when(mBluetoothMethodProxy) + .contentResolverQuery(any(), any(), any(), any(), any(), any()); doReturn(true).when(cursor).moveToFirst(); Intent intent = new Intent(); @@ -375,7 +440,7 @@ public class BluetoothOppReceiverTest { // check Toast with Espresso seems not to work on Android 11+. Check not send broadcast // context instead - verify(mContext, never()).sendBroadcast(any(), eq(Constants.HANDOVER_STATUS_PERMISSION), - any()); + verify(mContext, never()) + .sendBroadcast(any(), eq(Constants.HANDOVER_STATUS_PERMISSION), any()); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java index 7d39d32d37b..273f6fd8d5c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.android.bluetooth.opp; import static com.google.common.truth.Truth.assertThat; @@ -56,8 +55,7 @@ public class BluetoothOppSendFileInfoTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - BluetoothMethodProxy mCallProxy; + @Mock BluetoothMethodProxy mCallProxy; @Before public void setUp() { @@ -93,8 +91,7 @@ public class BluetoothOppSendFileInfoTest { long length = 10000; int status = BluetoothShare.STATUS_SUCCESS; String data = "Testing is boring"; - BluetoothOppSendFileInfo info = - new BluetoothOppSendFileInfo(data, type, length, status); + BluetoothOppSendFileInfo info = new BluetoothOppSendFileInfo(data, type, length, status); assertThat(info.mStatus).isEqualTo(status); assertThat(info.mData).isEqualTo(data); @@ -107,8 +104,8 @@ public class BluetoothOppSendFileInfoTest { String type = "text/plain"; Uri uri = Uri.parse("https://www.google.com"); - BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, - type, true); + BluetoothOppSendFileInfo info = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, type, true); assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR); } @@ -117,8 +114,8 @@ public class BluetoothOppSendFileInfoTest { String type = "text/plain"; Uri uri = Uri.parse("content://com.android.bluetooth.map.MmsFileProvider:8080"); - BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, - type, true); + BluetoothOppSendFileInfo info = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, type, true); assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR); } @@ -127,12 +124,12 @@ public class BluetoothOppSendFileInfoTest { String type = "text/plain"; Uri uri = Uri.parse("content:///hello/world"); - doThrow(new SecurityException()).when(mCallProxy).contentResolverQuery( - any(), eq(uri), any(), any(), any(), - any()); + doThrow(new SecurityException()) + .when(mCallProxy) + .contentResolverQuery(any(), eq(uri), any(), any(), any(), any()); - BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, - type, true); + BluetoothOppSendFileInfo info = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, type, true); assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR); } @@ -148,24 +145,22 @@ public class BluetoothOppSendFileInfoTest { AssetFileDescriptor fd = mock(AssetFileDescriptor.class); FileInputStream fs = mock(FileInputStream.class); - mCursor = new MatrixCursor(new String[]{ - OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE - }); - mCursor.addRow(new Object[]{fileName, fileLength}); + mCursor = + new MatrixCursor(new String[] {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}); + mCursor.addRow(new Object[] {fileName, fileLength}); - doReturn(mCursor).when(mCallProxy).contentResolverQuery( - any(), eq(uri), any(), any(), any(), - any()); + doReturn(mCursor) + .when(mCallProxy) + .contentResolverQuery(any(), eq(uri), any(), any(), any(), any()); - doReturn(fd).when(mCallProxy).contentResolverOpenAssetFileDescriptor( - any(), eq(uri), any()); + doReturn(fd).when(mCallProxy).contentResolverOpenAssetFileDescriptor(any(), eq(uri), any()); doReturn(0L).when(fd).getLength(); doThrow(new IOException()).when(fd).createInputStream(); doReturn(fs).when(mCallProxy).contentResolverOpenInputStream(any(), eq(uri)); doReturn(0, -1).when(fs).read(any(), anyInt(), anyInt()); - BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, - type, true); + BluetoothOppSendFileInfo info = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, type, true); assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR); } @@ -183,25 +178,23 @@ public class BluetoothOppSendFileInfoTest { AssetFileDescriptor fd = mock(AssetFileDescriptor.class); FileInputStream fs = mock(FileInputStream.class); - mCursor = new MatrixCursor(new String[]{ - OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE - }); - mCursor.addRow(new Object[]{fileName, fileLength}); + mCursor = + new MatrixCursor(new String[] {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}); + mCursor.addRow(new Object[] {fileName, fileLength}); - doReturn(mCursor).when(mCallProxy).contentResolverQuery( - any(), eq(uri), any(), any(), any(), - any()); + doReturn(mCursor) + .when(mCallProxy) + .contentResolverQuery(any(), eq(uri), any(), any(), any(), any()); - doReturn(fd).when(mCallProxy).contentResolverOpenAssetFileDescriptor( - any(), eq(uri), any()); + doReturn(fd).when(mCallProxy).contentResolverOpenAssetFileDescriptor(any(), eq(uri), any()); doReturn(0L).when(fd).getLength(); doReturn(fs).when(fd).createInputStream(); // the real size will be returned in getStreamSize(fs) doReturn((int) correctFileLength, -1).when(fs).read(any(), anyInt(), anyInt()); - BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, - type, true); + BluetoothOppSendFileInfo info = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, type, true); assertThat(info.mInputStream).isEqualTo(fs); assertThat(info.mFileName).isEqualTo(fileName); @@ -214,8 +207,8 @@ public class BluetoothOppSendFileInfoTest { String type = "text/plain"; Uri uri = Uri.parse("file:///obviously/not/in/external/storage"); - BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, - type, true); + BluetoothOppSendFileInfo info = + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, type, true); assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java index ca549ecd8f4..1ec8853e9a6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java @@ -48,9 +48,22 @@ public class BluetoothOppShareInfoTest { @Before public void setUp() throws Exception { - mBluetoothOppShareInfo = new BluetoothOppShareInfo(0, uri, hintString, filename, - mimetype, direction, destination, visibility, confirm, status, totalBytes, - currentBytes, timestamp, mediaScanned); + mBluetoothOppShareInfo = + new BluetoothOppShareInfo( + 0, + uri, + hintString, + filename, + mimetype, + direction, + destination, + visibility, + confirm, + status, + totalBytes, + currentBytes, + timestamp, + mediaScanned); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java index 0c238563118..33455307659 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java @@ -42,7 +42,7 @@ public class BluetoothOppTestUtils { * @attr columnName is name of column to be used as a parameter in cursor.getColumnIndexOrThrow * @attr mIndex should be returned from cursor.getColumnIndexOrThrow * @attr mValue should be returned from cursor.getInt() or cursor.getString() or - * cursor.getLong() + * cursor.getLong() */ public static class CursorMockData { public final String mColumnName; @@ -57,8 +57,8 @@ public class BluetoothOppTestUtils { } /** - * Set up a mock single-row Cursor that work for common use cases in the OPP package. - * It mocks the database column index and value of the cell in that column of the current row + * Set up a mock single-row Cursor that work for common use cases in the OPP package. It mocks + * the database column index and value of the cell in that column of the current row * *

      *  cursorMockDataList.add(
@@ -74,37 +74,59 @@ public class BluetoothOppTestUtils {
      * @param cursor a mock/spy cursor to be setup
      * @param cursorMockDataList a list representing what cursor will return
      */
-    public static void setUpMockCursor(
-            Cursor cursor, List cursorMockDataList) {
-        assert(MockUtil.isMock(cursor));
-
-        doAnswer(invocation -> {
-            String name = invocation.getArgument(0);
-            return cursorMockDataList.stream().filter(
-                    mockCursorData -> Objects.equals(mockCursorData.mColumnName, name)
-            ).findFirst().orElse(new CursorMockData("", -1, null)).mColumnIndex;
-        }).when(cursor).getColumnIndexOrThrow(anyString());
-
-        doAnswer(invocation -> {
-            int index = invocation.getArgument(0);
-            return cursorMockDataList.stream().filter(
-                    mockCursorData -> mockCursorData.mColumnIndex == index
-            ).findFirst().orElse(new CursorMockData("", -1, -1)).mValue;
-        }).when(cursor).getInt(anyInt());
-
-        doAnswer(invocation -> {
-            int index = invocation.getArgument(0);
-            return cursorMockDataList.stream().filter(
-                    mockCursorData -> mockCursorData.mColumnIndex == index
-            ).findFirst().orElse(new CursorMockData("", -1, -1)).mValue;
-        }).when(cursor).getLong(anyInt());
-
-        doAnswer(invocation -> {
-            int index = invocation.getArgument(0);
-            return cursorMockDataList.stream().filter(
-                    mockCursorData -> mockCursorData.mColumnIndex == index
-            ).findFirst().orElse(new CursorMockData("", -1, null)).mValue;
-        }).when(cursor).getString(anyInt());
+    public static void setUpMockCursor(Cursor cursor, List cursorMockDataList) {
+        assert (MockUtil.isMock(cursor));
+
+        doAnswer(
+                        invocation -> {
+                            String name = invocation.getArgument(0);
+                            return cursorMockDataList.stream()
+                                    .filter(
+                                            mockCursorData ->
+                                                    Objects.equals(
+                                                            mockCursorData.mColumnName, name))
+                                    .findFirst()
+                                    .orElse(new CursorMockData("", -1, null))
+                                    .mColumnIndex;
+                        })
+                .when(cursor)
+                .getColumnIndexOrThrow(anyString());
+
+        doAnswer(
+                        invocation -> {
+                            int index = invocation.getArgument(0);
+                            return cursorMockDataList.stream()
+                                    .filter(mockCursorData -> mockCursorData.mColumnIndex == index)
+                                    .findFirst()
+                                    .orElse(new CursorMockData("", -1, -1))
+                                    .mValue;
+                        })
+                .when(cursor)
+                .getInt(anyInt());
+
+        doAnswer(
+                        invocation -> {
+                            int index = invocation.getArgument(0);
+                            return cursorMockDataList.stream()
+                                    .filter(mockCursorData -> mockCursorData.mColumnIndex == index)
+                                    .findFirst()
+                                    .orElse(new CursorMockData("", -1, -1))
+                                    .mValue;
+                        })
+                .when(cursor)
+                .getLong(anyInt());
+
+        doAnswer(
+                        invocation -> {
+                            int index = invocation.getArgument(0);
+                            return cursorMockDataList.stream()
+                                    .filter(mockCursorData -> mockCursorData.mColumnIndex == index)
+                                    .findFirst()
+                                    .orElse(new CursorMockData("", -1, null))
+                                    .mValue;
+                        })
+                .when(cursor)
+                .getString(anyInt());
 
         doReturn(true).when(cursor).moveToFirst();
         doReturn(true).when(cursor).moveToLast();
@@ -135,4 +157,3 @@ public class BluetoothOppTestUtils {
                 .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP);
     }
 }
-
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java
index 2fef8475083..2eaa49cf18c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java
@@ -16,7 +16,6 @@
 
 package com.android.bluetooth.opp;
 
-
 import static com.android.bluetooth.opp.BluetoothOppTestUtils.CursorMockData;
 import static com.android.bluetooth.opp.BluetoothOppTransferActivity.DIALOG_RECEIVE_COMPLETE_FAIL;
 import static com.android.bluetooth.opp.BluetoothOppTransferActivity.DIALOG_RECEIVE_COMPLETE_SUCCESS;
@@ -62,10 +61,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 public class BluetoothOppTransferActivityTest {
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Cursor mCursor;
-    @Spy
-    BluetoothMethodProxy mBluetoothMethodProxy;
+    @Mock Cursor mCursor;
+    @Spy BluetoothMethodProxy mBluetoothMethodProxy;
 
     List mCursorMockDataList;
 
@@ -89,29 +86,34 @@ public class BluetoothOppTransferActivityTest {
         mIntent.setClass(mTargetContext, BluetoothOppTransferActivity.class);
         mIntent.setData(dataUrl);
 
-        doReturn(mCursor).when(mBluetoothMethodProxy).contentResolverQuery(any(), eq(dataUrl),
-                eq(null), eq(null),
-                eq(null), eq(null));
+        doReturn(mCursor)
+                .when(mBluetoothMethodProxy)
+                .contentResolverQuery(any(), eq(dataUrl), eq(null), eq(null), eq(null), eq(null));
 
-        doReturn(1).when(mBluetoothMethodProxy).contentResolverUpdate(any(), eq(dataUrl),
-                any(), eq(null), eq(null));
+        doReturn(1)
+                .when(mBluetoothMethodProxy)
+                .contentResolverUpdate(any(), eq(dataUrl), any(), eq(null), eq(null));
 
         int idValue = 1234;
         Long timestampValue = 123456789L;
         String destinationValue = "AA:BB:CC:00:11:22";
         String fileTypeValue = "text/plain";
 
-        mCursorMockDataList = new ArrayList<>(List.of(
-                new CursorMockData(BluetoothShare._ID, 0, idValue),
-                new CursorMockData(BluetoothShare.MIMETYPE, 5, fileTypeValue),
-                new CursorMockData(BluetoothShare.TIMESTAMP, 6, timestampValue),
-                new CursorMockData(BluetoothShare.DESTINATION, 7, destinationValue),
-                new CursorMockData(BluetoothShare._DATA, 8, null),
-                new CursorMockData(BluetoothShare.FILENAME_HINT, 9, null),
-                new CursorMockData(BluetoothShare.URI, 10, "content://textfile.txt"),
-                new CursorMockData(BluetoothShare.USER_CONFIRMATION, 11,
-                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)
-        ));
+        mCursorMockDataList =
+                new ArrayList<>(
+                        List.of(
+                                new CursorMockData(BluetoothShare._ID, 0, idValue),
+                                new CursorMockData(BluetoothShare.MIMETYPE, 5, fileTypeValue),
+                                new CursorMockData(BluetoothShare.TIMESTAMP, 6, timestampValue),
+                                new CursorMockData(BluetoothShare.DESTINATION, 7, destinationValue),
+                                new CursorMockData(BluetoothShare._DATA, 8, null),
+                                new CursorMockData(BluetoothShare.FILENAME_HINT, 9, null),
+                                new CursorMockData(
+                                        BluetoothShare.URI, 10, "content://textfile.txt"),
+                                new CursorMockData(
+                                        BluetoothShare.USER_CONFIRMATION,
+                                        11,
+                                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)));
         BluetoothOppTestUtils.enableActivity(
                 BluetoothOppTransferActivity.class, true, mTargetContext);
         TestUtils.setUpUiTest();
@@ -131,19 +133,19 @@ public class BluetoothOppTransferActivityTest {
         mCursorMockDataList.add(
                 new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_PENDING));
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND)
-        );
+                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 0));
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
         AtomicBoolean check = new AtomicBoolean(false);
-        ActivityScenario activityScenario = ActivityScenario.launch(
-                mIntent);
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
 
-        activityScenario.onActivity(activity -> {
-            check.set(activity.mWhichDialog == DIALOG_SEND_ONGOING);
-        });
+        activityScenario.onActivity(
+                activity -> {
+                    check.set(activity.mWhichDialog == DIALOG_SEND_ONGOING);
+                });
 
         assertThat(check.get()).isTrue();
     }
@@ -151,23 +153,21 @@ public class BluetoothOppTransferActivityTest {
     @Test
     public void onCreate_showSendCompleteSuccessDialog() {
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_SUCCESS)
-        );
+                new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_SUCCESS));
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND)
-        );
+                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100));
-        mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 100));
+        mCursorMockDataList.add(new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 100));
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
         AtomicBoolean check = new AtomicBoolean(false);
-        ActivityScenario activityScenario = ActivityScenario.launch(
-                mIntent);
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
 
-        activityScenario.onActivity(activity -> {
-            check.set(activity.mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS);
-        });
+        activityScenario.onActivity(
+                activity -> {
+                    check.set(activity.mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS);
+                });
 
         assertThat(check.get()).isTrue();
     }
@@ -177,19 +177,19 @@ public class BluetoothOppTransferActivityTest {
         mCursorMockDataList.add(
                 new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_FORBIDDEN));
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND)
-        );
+                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 42));
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
         AtomicBoolean check = new AtomicBoolean(false);
-        ActivityScenario activityScenario = ActivityScenario.launch(
-                mIntent);
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
 
-        activityScenario.onActivity(activity -> {
-            check.set(activity.mWhichDialog == DIALOG_SEND_COMPLETE_FAIL);
-        });
+        activityScenario.onActivity(
+                activity -> {
+                    check.set(activity.mWhichDialog == DIALOG_SEND_COMPLETE_FAIL);
+                });
 
         assertThat(check.get()).isTrue();
     }
@@ -199,19 +199,19 @@ public class BluetoothOppTransferActivityTest {
         mCursorMockDataList.add(
                 new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_PENDING));
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND)
-        );
+                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 0));
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
         AtomicBoolean check = new AtomicBoolean(false);
-        ActivityScenario activityScenario = ActivityScenario.launch(
-                mIntent);
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
 
-        activityScenario.onActivity(activity -> {
-            check.set(activity.mWhichDialog == DIALOG_RECEIVE_ONGOING);
-        });
+        activityScenario.onActivity(
+                activity -> {
+                    check.set(activity.mWhichDialog == DIALOG_RECEIVE_ONGOING);
+                });
 
         assertThat(check.get()).isTrue();
     }
@@ -221,22 +221,20 @@ public class BluetoothOppTransferActivityTest {
         mCursorMockDataList.add(
                 new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_SUCCESS));
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND)
-        );
+                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100));
-        mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 100)
-        );
+        mCursorMockDataList.add(new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 100));
 
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
         AtomicBoolean check = new AtomicBoolean(false);
-        ActivityScenario activityScenario = ActivityScenario.launch(
-                mIntent);
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
 
-        activityScenario.onActivity(activity -> {
-            check.set(activity.mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS);
-        });
+        activityScenario.onActivity(
+                activity -> {
+                    check.set(activity.mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS);
+                });
 
         assertThat(check.get()).isTrue();
     }
@@ -246,20 +244,20 @@ public class BluetoothOppTransferActivityTest {
         mCursorMockDataList.add(
                 new CursorMockData(BluetoothShare.STATUS, 1, BluetoothShare.STATUS_FORBIDDEN));
         mCursorMockDataList.add(
-                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND)
-        );
+                new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100));
         mCursorMockDataList.add(new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 42));
 
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
         AtomicBoolean check = new AtomicBoolean(false);
-        ActivityScenario activityScenario = ActivityScenario.launch(
-                mIntent);
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
 
-        activityScenario.onActivity(activity -> {
-            check.set(activity.mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL);
-        });
+        activityScenario.onActivity(
+                activity -> {
+                    check.set(activity.mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL);
+                });
 
         assertThat(check.get()).isTrue();
     }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java
index 9cc3c0397bd..a50be0b5dec 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java
@@ -64,17 +64,13 @@ import org.mockito.junit.MockitoRule;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * This class will also test BluetoothOppTransferAdapter
- */
+/** This class will also test BluetoothOppTransferAdapter */
 @RunWith(AndroidJUnit4.class)
 public class BluetoothOppTransferHistoryTest {
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Cursor mCursor;
-    @Spy
-    BluetoothMethodProxy mBluetoothMethodProxy;
+    @Mock Cursor mCursor;
+    @Spy BluetoothMethodProxy mBluetoothMethodProxy;
 
     List mCursorMockDataList;
 
@@ -98,35 +94,47 @@ public class BluetoothOppTransferHistoryTest {
         mIntent.setClass(mTargetContext, BluetoothOppTransferHistory.class);
         mIntent.setData(dataUrl);
 
-        doReturn(mCursor).when(mBluetoothMethodProxy).contentResolverQuery(any(),
-                eq(BluetoothShare.CONTENT_URI),
-                any(), any(), any(), any());
+        doReturn(mCursor)
+                .when(mBluetoothMethodProxy)
+                .contentResolverQuery(
+                        any(), eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any());
 
         int idValue = 1234;
         Long timestampValue = 123456789L;
         String destinationValue = "AA:BB:CC:00:11:22";
         String fileTypeValue = "text/plain";
 
-        mCursorMockDataList = new ArrayList<>(List.of(
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.STATUS, 1,
-                        BluetoothShare.STATUS_SUCCESS),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DIRECTION, 2,
-                        BluetoothShare.DIRECTION_INBOUND),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 0),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare._ID, 0, idValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.MIMETYPE, 5, fileTypeValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TIMESTAMP, 6,
-                        timestampValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DESTINATION, 7,
-                        destinationValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare._DATA, 8, null),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.FILENAME_HINT, 9, null),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.URI, 10,
-                        "content://textfile.txt"),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.USER_CONFIRMATION, 11,
-                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)
-        ));
+        mCursorMockDataList =
+                new ArrayList<>(
+                        List.of(
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.STATUS, 1, BluetoothShare.STATUS_SUCCESS),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.DIRECTION,
+                                        2,
+                                        BluetoothShare.DIRECTION_INBOUND),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.TOTAL_BYTES, 3, 100),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.CURRENT_BYTES, 4, 0),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare._ID, 0, idValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.MIMETYPE, 5, fileTypeValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.TIMESTAMP, 6, timestampValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.DESTINATION, 7, destinationValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare._DATA, 8, null),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.FILENAME_HINT, 9, null),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.URI, 10, "content://textfile.txt"),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.USER_CONFIRMATION,
+                                        11,
+                                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)));
 
         BluetoothOppTestUtils.enableActivity(
                 BluetoothOppTransferHistory.class, true, mTargetContext);
@@ -156,8 +164,8 @@ public class BluetoothOppTransferHistoryTest {
         ActivityScenario scenario = ActivityScenario.launch(mIntent);
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        onView(withText(mTargetContext.getText(R.string.inbound_history_title).toString())).check(
-                matches(isDisplayed()));
+        onView(withText(mTargetContext.getText(R.string.inbound_history_title).toString()))
+                .check(matches(isDisplayed()));
     }
 
     @Test
@@ -166,9 +174,10 @@ public class BluetoothOppTransferHistoryTest {
                 mTargetContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH));
 
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
-        mCursorMockDataList.set(1,
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DIRECTION, 2,
-                        BluetoothShare.DIRECTION_OUTBOUND));
+        mCursorMockDataList.set(
+                1,
+                new BluetoothOppTestUtils.CursorMockData(
+                        BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND));
         if (Flags.oppStartActivityDirectlyFromNotification()) {
             mIntent.setAction(Constants.ACTION_OPEN_OUTBOUND_TRANSFER);
         } else {
@@ -178,8 +187,8 @@ public class BluetoothOppTransferHistoryTest {
         ActivityScenario scenario = ActivityScenario.launch(mIntent);
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        onView(withText(mTargetContext.getText(R.string.outbound_history_title).toString())).check(
-                matches(isDisplayed()));
+        onView(withText(mTargetContext.getText(R.string.outbound_history_title).toString()))
+                .check(matches(isDisplayed()));
     }
 
     // TODO: Check whether watch devices can pass this test
@@ -191,31 +200,51 @@ public class BluetoothOppTransferHistoryTest {
 
         ActivityScenario scenario = ActivityScenario.launch(mIntent);
 
-
         MenuItem mockMenuItem = mock(MenuItem.class);
         doReturn(R.id.transfer_menu_clear_all).when(mockMenuItem).getItemId();
-        scenario.onActivity(activity -> {
-            activity.onOptionsItemSelected(mockMenuItem);
-        });
+        scenario.onActivity(
+                activity -> {
+                    activity.onOptionsItemSelected(mockMenuItem);
+                });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Controlling clear all download
         doReturn(true, false).when(mCursor).moveToFirst();
         doReturn(false, true).when(mCursor).isAfterLast();
-        doReturn(0).when(mBluetoothMethodProxy).contentResolverUpdate(any(), any(),
-                argThat(arg -> Objects.equal(arg.get(BluetoothShare.VISIBILITY),
-                        BluetoothShare.VISIBILITY_HIDDEN)), any(), any());
+        doReturn(0)
+                .when(mBluetoothMethodProxy)
+                .contentResolverUpdate(
+                        any(),
+                        any(),
+                        argThat(
+                                arg ->
+                                        Objects.equal(
+                                                arg.get(BluetoothShare.VISIBILITY),
+                                                BluetoothShare.VISIBILITY_HIDDEN)),
+                        any(),
+                        any());
 
         onView(withText(mTargetContext.getText(R.string.transfer_clear_dlg_title).toString()))
-                .inRoot(isDialog()).check(matches(isDisplayed()));
+                .inRoot(isDialog())
+                .check(matches(isDisplayed()));
 
         // Click ok on the prompted dialog
-        onView(withText(mTargetContext.getText(android.R.string.ok).toString())).inRoot(
-                isDialog()).check(matches(isDisplayed())).perform(click());
+        onView(withText(mTargetContext.getText(android.R.string.ok).toString()))
+                .inRoot(isDialog())
+                .check(matches(isDisplayed()))
+                .perform(click());
 
         // Verify that item is hidden
-        verify(mBluetoothMethodProxy).contentResolverUpdate(any(), any(),
-                argThat(arg -> Objects.equal(arg.get(BluetoothShare.VISIBILITY),
-                        BluetoothShare.VISIBILITY_HIDDEN)), any(), any());
+        verify(mBluetoothMethodProxy)
+                .contentResolverUpdate(
+                        any(),
+                        any(),
+                        argThat(
+                                arg ->
+                                        Objects.equal(
+                                                arg.get(BluetoothShare.VISIBILITY),
+                                                BluetoothShare.VISIBILITY_HIDDEN)),
+                        any(),
+                        any());
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java
index 46a1d5496e3..fbf67c4a736 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java
@@ -83,10 +83,8 @@ public class BluetoothOppTransferTest {
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
     @Rule public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
 
-    @Mock
-    BluetoothOppObexSession mSession;
-    @Mock
-    BluetoothMethodProxy mCallProxy;
+    @Mock BluetoothOppObexSession mSession;
+    @Mock BluetoothMethodProxy mCallProxy;
     Context mContext;
     BluetoothOppBatch mBluetoothOppBatch;
     BluetoothOppTransfer mTransfer;
@@ -96,18 +94,42 @@ public class BluetoothOppTransferTest {
     @Before
     public void setUp() throws Exception {
         BluetoothMethodProxy.setInstanceForTesting(mCallProxy);
-        doReturn(0).when(mCallProxy).contentResolverDelete(any(), nullable(Uri.class),
-                nullable(String.class), nullable(String[].class));
-        doReturn(0).when(mCallProxy).contentResolverUpdate(any(), nullable(Uri.class),
-                nullable(ContentValues.class), nullable(String.class), nullable(String[].class));
-
-        mInitShareInfo = new BluetoothOppShareInfo(8765, mUri, mHintString, mFilename, mMimetype,
-                mDirection, mDestination, mVisibility, mConfirm, mStatus, mTotalBytes,
-                mCurrentBytes,
-                mTimestamp, mMediaScanned);
-        mContext = spy(
-                new ContextWrapper(
-                        InstrumentationRegistry.getInstrumentation().getTargetContext()));
+        doReturn(0)
+                .when(mCallProxy)
+                .contentResolverDelete(
+                        any(),
+                        nullable(Uri.class),
+                        nullable(String.class),
+                        nullable(String[].class));
+        doReturn(0)
+                .when(mCallProxy)
+                .contentResolverUpdate(
+                        any(),
+                        nullable(Uri.class),
+                        nullable(ContentValues.class),
+                        nullable(String.class),
+                        nullable(String[].class));
+
+        mInitShareInfo =
+                new BluetoothOppShareInfo(
+                        8765,
+                        mUri,
+                        mHintString,
+                        mFilename,
+                        mMimetype,
+                        mDirection,
+                        mDestination,
+                        mVisibility,
+                        mConfirm,
+                        mStatus,
+                        mTotalBytes,
+                        mCurrentBytes,
+                        mTimestamp,
+                        mMediaScanned);
+        mContext =
+                spy(
+                        new ContextWrapper(
+                                InstrumentationRegistry.getInstrumentation().getTargetContext()));
         mBluetoothOppBatch = spy(new BluetoothOppBatch(mContext, mInitShareInfo));
         mTransfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch, mSession);
         mEventHandler = mTransfer.new EventHandler(Looper.getMainLooper());
@@ -120,17 +142,31 @@ public class BluetoothOppTransferTest {
 
     @Test
     public void onShareAdded_checkFirstPendingShare() {
-        BluetoothOppShareInfo newShareInfo = new BluetoothOppShareInfo(1, mUri, mHintString,
-                mFilename, mMimetype, BluetoothShare.DIRECTION_INBOUND, mDestination, mVisibility,
-                BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED, mStatus, mTotalBytes,
-                mCurrentBytes,
-                mTimestamp, mMediaScanned);
-
-        doAnswer(invocation -> {
-            assertThat((BluetoothOppShareInfo) invocation.getArgument(0))
-                    .isEqualTo(mInitShareInfo);
-            return null;
-        }).when(mSession).addShare(any(BluetoothOppShareInfo.class));
+        BluetoothOppShareInfo newShareInfo =
+                new BluetoothOppShareInfo(
+                        1,
+                        mUri,
+                        mHintString,
+                        mFilename,
+                        mMimetype,
+                        BluetoothShare.DIRECTION_INBOUND,
+                        mDestination,
+                        mVisibility,
+                        BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED,
+                        mStatus,
+                        mTotalBytes,
+                        mCurrentBytes,
+                        mTimestamp,
+                        mMediaScanned);
+
+        doAnswer(
+                        invocation -> {
+                            assertThat((BluetoothOppShareInfo) invocation.getArgument(0))
+                                    .isEqualTo(mInitShareInfo);
+                            return null;
+                        })
+                .when(mSession)
+                .addShare(any(BluetoothOppShareInfo.class));
 
         // This will trigger mTransfer.onShareAdded(), which will call mTransfer
         // .processCurrentShare(),
@@ -179,14 +215,14 @@ public class BluetoothOppTransferTest {
         assertThat(mBluetoothOppBatch.mStatus).isEqualTo(Constants.BATCH_STATUS_FAILED);
     }
 
-// TODO: try to use ShadowBluetoothDevice
-//    @Test
-//    public void eventHandler_handleMessage_SOCKET_ERROR_RETRY_connectThreadInitiated() {
-//        BluetoothDevice bluetoothDevice = ShadowBluetoothDevice();
-//        Message message = Message.obtain(mEventHandler, SOCKET_ERROR_RETRY, bluetoothDevice);
-//        mEventHandler.handleMessage(message);
-//        assertThat(mTransfer.mConnectThread).isNotNull();
-//    }
+    // TODO: try to use ShadowBluetoothDevice
+    //    @Test
+    //    public void eventHandler_handleMessage_SOCKET_ERROR_RETRY_connectThreadInitiated() {
+    //        BluetoothDevice bluetoothDevice = ShadowBluetoothDevice();
+    //        Message message = Message.obtain(mEventHandler, SOCKET_ERROR_RETRY, bluetoothDevice);
+    //        mEventHandler.handleMessage(message);
+    //        assertThat(mTransfer.mConnectThread).isNotNull();
+    //    }
 
     @Test
     public void eventHandler_handleMessage_TRANSPORT_CONNECTED_obexSessionStarted() {
@@ -200,12 +236,26 @@ public class BluetoothOppTransferTest {
     public void eventHandler_handleMessage_MSG_SHARE_COMPLETE_shareAdded() {
         Message message = Message.obtain(mEventHandler, BluetoothOppObexSession.MSG_SHARE_COMPLETE);
 
-        mInitShareInfo = new BluetoothOppShareInfo(123, mUri, mHintString, mFilename, mMimetype,
-                BluetoothShare.DIRECTION_OUTBOUND, mDestination, mVisibility, mConfirm, mStatus,
-                mTotalBytes, mCurrentBytes, mTimestamp, mMediaScanned);
-        mContext = spy(
-                new ContextWrapper(
-                        InstrumentationRegistry.getInstrumentation().getTargetContext()));
+        mInitShareInfo =
+                new BluetoothOppShareInfo(
+                        123,
+                        mUri,
+                        mHintString,
+                        mFilename,
+                        mMimetype,
+                        BluetoothShare.DIRECTION_OUTBOUND,
+                        mDestination,
+                        mVisibility,
+                        mConfirm,
+                        mStatus,
+                        mTotalBytes,
+                        mCurrentBytes,
+                        mTimestamp,
+                        mMediaScanned);
+        mContext =
+                spy(
+                        new ContextWrapper(
+                                InstrumentationRegistry.getInstrumentation().getTargetContext()));
         mBluetoothOppBatch = spy(new BluetoothOppBatch(mContext, mInitShareInfo));
         mTransfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch, mSession);
         mEventHandler = mTransfer.new EventHandler(Looper.getMainLooper());
@@ -218,9 +268,8 @@ public class BluetoothOppTransferTest {
     @Test
     public void eventHandler_handleMessage_MSG_SESSION_COMPLETE_batchFinished() {
         BluetoothOppShareInfo info = mock(BluetoothOppShareInfo.class);
-        Message message = Message.obtain(mEventHandler,
-                BluetoothOppObexSession.MSG_SESSION_COMPLETE,
-                info);
+        Message message =
+                Message.obtain(mEventHandler, BluetoothOppObexSession.MSG_SESSION_COMPLETE, info);
         mEventHandler.handleMessage(message);
 
         assertThat(mBluetoothOppBatch.mStatus).isEqualTo(Constants.BATCH_STATUS_FINISHED);
@@ -229,8 +278,8 @@ public class BluetoothOppTransferTest {
     @Test
     public void eventHandler_handleMessage_MSG_SESSION_ERROR_batchFailed() {
         BluetoothOppShareInfo info = mock(BluetoothOppShareInfo.class);
-        Message message = Message.obtain(mEventHandler, BluetoothOppObexSession.MSG_SESSION_ERROR,
-                info);
+        Message message =
+                Message.obtain(mEventHandler, BluetoothOppObexSession.MSG_SESSION_ERROR, info);
         mEventHandler.handleMessage(message);
 
         assertThat(mBluetoothOppBatch.mStatus).isEqualTo(Constants.BATCH_STATUS_FAILED);
@@ -239,17 +288,29 @@ public class BluetoothOppTransferTest {
     @Test
     public void eventHandler_handleMessage_MSG_SHARE_INTERRUPTED_batchFailed() {
 
-        mInitShareInfo = new BluetoothOppShareInfo(123, mUri, mHintString, mFilename, mMimetype,
-                BluetoothShare.DIRECTION_OUTBOUND, mDestination, mVisibility, mConfirm, mStatus,
-                mTotalBytes, mCurrentBytes, mTimestamp, mMediaScanned);
+        mInitShareInfo =
+                new BluetoothOppShareInfo(
+                        123,
+                        mUri,
+                        mHintString,
+                        mFilename,
+                        mMimetype,
+                        BluetoothShare.DIRECTION_OUTBOUND,
+                        mDestination,
+                        mVisibility,
+                        mConfirm,
+                        mStatus,
+                        mTotalBytes,
+                        mCurrentBytes,
+                        mTimestamp,
+                        mMediaScanned);
         mBluetoothOppBatch = spy(new BluetoothOppBatch(mContext, mInitShareInfo));
         mTransfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch, mSession);
         mEventHandler = mTransfer.new EventHandler(Looper.getMainLooper());
 
         BluetoothOppShareInfo info = mock(BluetoothOppShareInfo.class);
-        Message message = Message.obtain(mEventHandler,
-                BluetoothOppObexSession.MSG_SHARE_INTERRUPTED,
-                info);
+        Message message =
+                Message.obtain(mEventHandler, BluetoothOppObexSession.MSG_SHARE_INTERRUPTED, info);
         mEventHandler.handleMessage(message);
 
         assertThat(mBluetoothOppBatch.mStatus).isEqualTo(Constants.BATCH_STATUS_FAILED);
@@ -257,24 +318,45 @@ public class BluetoothOppTransferTest {
 
     @Test
     public void eventHandler_handleMessage_MSG_CONNECT_TIMEOUT() {
-        Message message = Message.obtain(mEventHandler,
-                BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
-        BluetoothOppShareInfo newInfo = new BluetoothOppShareInfo(321, mUri, mHintString,
-                mFilename, mMimetype, mDirection, mDestination, mVisibility, mConfirm, mStatus,
-                mTotalBytes, mCurrentBytes, mTimestamp, mMediaScanned);
+        Message message =
+                Message.obtain(mEventHandler, BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
+        BluetoothOppShareInfo newInfo =
+                new BluetoothOppShareInfo(
+                        321,
+                        mUri,
+                        mHintString,
+                        mFilename,
+                        mMimetype,
+                        mDirection,
+                        mDestination,
+                        mVisibility,
+                        mConfirm,
+                        mStatus,
+                        mTotalBytes,
+                        mCurrentBytes,
+                        mTimestamp,
+                        mMediaScanned);
         // Adding new info will assign value to mCurrentShare
         mBluetoothOppBatch.addShare(newInfo);
         mEventHandler.handleMessage(message);
 
-        verify(mContext).sendBroadcast(argThat(
-                arg -> arg.getAction().equals(BluetoothShare.USER_CONFIRMATION_TIMEOUT_ACTION)));
+        verify(mContext)
+                .sendBroadcast(
+                        argThat(
+                                arg ->
+                                        arg.getAction()
+                                                .equals(
+                                                        BluetoothShare
+                                                                .USER_CONFIRMATION_TIMEOUT_ACTION)));
     }
 
     @Test
     public void socketConnectThreadConstructors() {
         String address = "AA:BB:CC:EE:DD:11";
-        BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
-                .getAdapter().getRemoteDevice(address);
+        BluetoothDevice device =
+                (mContext.getSystemService(BluetoothManager.class))
+                        .getAdapter()
+                        .getRemoteDevice(address);
         BluetoothOppTransfer transfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch);
         BluetoothOppTransfer.SocketConnectThread socketConnectThread =
                 transfer.new SocketConnectThread(device, true);
@@ -287,8 +369,10 @@ public class BluetoothOppTransferTest {
     @Test
     public void socketConnectThreadInterrupt() {
         String address = "AA:BB:CC:EE:DD:11";
-        BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
-                .getAdapter().getRemoteDevice(address);
+        BluetoothDevice device =
+                (mContext.getSystemService(BluetoothManager.class))
+                        .getAdapter()
+                        .getRemoteDevice(address);
         BluetoothOppTransfer transfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch);
         BluetoothOppTransfer.SocketConnectThread socketConnectThread =
                 transfer.new SocketConnectThread(device, true);
@@ -300,8 +384,10 @@ public class BluetoothOppTransferTest {
     @SuppressWarnings("DoNotCall")
     public void socketConnectThreadRun_bluetoothDisabled_connectionFailed() {
         String address = "AA:BB:CC:EE:DD:11";
-        BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
-                .getAdapter().getRemoteDevice(address);
+        BluetoothDevice device =
+                (mContext.getSystemService(BluetoothManager.class))
+                        .getAdapter()
+                        .getRemoteDevice(address);
         BluetoothOppTransfer transfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch);
         BluetoothOppTransfer.SocketConnectThread socketConnectThread =
                 transfer.new SocketConnectThread(device, true);
@@ -313,8 +399,10 @@ public class BluetoothOppTransferTest {
 
     @Test
     public void oppConnectionReceiver_onReceiveWithActionAclDisconnected_sendsConnectTimeout() {
-        BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
-                .getAdapter().getRemoteDevice(mDestination);
+        BluetoothDevice device =
+                (mContext.getSystemService(BluetoothManager.class))
+                        .getAdapter()
+                        .getRemoteDevice(mDestination);
         BluetoothOppTransfer transfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch);
         transfer.mCurrentShare = mInitShareInfo;
         transfer.mCurrentShare.mConfirm = BluetoothShare.USER_CONFIRMATION_PENDING;
@@ -325,15 +413,17 @@ public class BluetoothOppTransferTest {
 
         transfer.mSessionHandler = mEventHandler;
         receiver.onReceive(mContext, intent);
-        verify(mCallProxy).handlerSendEmptyMessage(any(),
-                eq(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT));
+        verify(mCallProxy)
+                .handlerSendEmptyMessage(any(), eq(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT));
     }
 
     @Test
     public void oppConnectionReceiver_onReceiveWithActionSdpRecord_withoutSdpRecord() {
         mSetFlagRule.enableFlags(Flags.FLAG_IDENTITY_ADDRESS_NULL_IF_UNKNOWN);
-        BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
-                .getAdapter().getRemoteDevice(mDestination);
+        BluetoothDevice device =
+                (mContext.getSystemService(BluetoothManager.class))
+                        .getAdapter()
+                        .getRemoteDevice(mDestination);
 
         BluetoothOppTransfer transfer = new BluetoothOppTransfer(mContext, mBluetoothOppBatch);
         transfer.mCurrentShare = mInitShareInfo;
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java
index e8a5dac0e02..9af7c38e32f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java
@@ -65,19 +65,16 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 public class BluetoothOppUtilityTest {
 
-    private static final Uri CORRECT_FORMAT_BUT_INVALID_FILE_URI = Uri.parse(
-            "content://com.android.bluetooth.opp/btopp/0123455343467");
+    private static final Uri CORRECT_FORMAT_BUT_INVALID_FILE_URI =
+            Uri.parse("content://com.android.bluetooth.opp/btopp/0123455343467");
     private static final Uri INCORRECT_FORMAT_URI = Uri.parse("www.google.com");
 
     Context mContext;
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Cursor mCursor;
-
-    @Spy
-    BluetoothMethodProxy mCallProxy = BluetoothMethodProxy.getInstance();
+    @Mock Cursor mCursor;
 
+    @Spy BluetoothMethodProxy mCallProxy = BluetoothMethodProxy.getInstance();
 
     @Before
     public void setUp() throws Exception {
@@ -102,24 +99,36 @@ public class BluetoothOppUtilityTest {
 
     @Test
     public void queryRecord_withInvalidFileUrl_returnsNull() {
-        doReturn(null).when(mCallProxy).contentResolverQuery(any(),
-                eq(CORRECT_FORMAT_BUT_INVALID_FILE_URI), eq(null), eq(null),
-                eq(null), eq(null));
-        assertThat(BluetoothOppUtility.queryRecord(mContext,
-                CORRECT_FORMAT_BUT_INVALID_FILE_URI)).isNull();
+        doReturn(null)
+                .when(mCallProxy)
+                .contentResolverQuery(
+                        any(),
+                        eq(CORRECT_FORMAT_BUT_INVALID_FILE_URI),
+                        eq(null),
+                        eq(null),
+                        eq(null),
+                        eq(null));
+        assertThat(BluetoothOppUtility.queryRecord(mContext, CORRECT_FORMAT_BUT_INVALID_FILE_URI))
+                .isNull();
     }
 
     @Test
     public void queryRecord_mockCursor_returnsInstance() {
         String destinationValue = "AA:BB:CC:00:11:22";
 
-        doReturn(mCursor).when(mCallProxy).contentResolverQuery(any(),
-                eq(CORRECT_FORMAT_BUT_INVALID_FILE_URI), eq(null), eq(null),
-                eq(null), eq(null));
+        doReturn(mCursor)
+                .when(mCallProxy)
+                .contentResolverQuery(
+                        any(),
+                        eq(CORRECT_FORMAT_BUT_INVALID_FILE_URI),
+                        eq(null),
+                        eq(null),
+                        eq(null),
+                        eq(null));
         doReturn(true).when(mCursor).moveToFirst();
         doReturn(destinationValue).when(mCursor).getString(anyInt());
-        assertThat(BluetoothOppUtility.queryRecord(mContext,
-                CORRECT_FORMAT_BUT_INVALID_FILE_URI)).isInstanceOf(BluetoothOppTransferInfo.class);
+        assertThat(BluetoothOppUtility.queryRecord(mContext, CORRECT_FORMAT_BUT_INVALID_FILE_URI))
+                .isInstanceOf(BluetoothOppTransferInfo.class);
     }
 
     @Test
@@ -128,18 +137,21 @@ public class BluetoothOppUtilityTest {
         String where = BluetoothShare.TIMESTAMP + " == " + timestampValue;
         AtomicInteger cnt = new AtomicInteger(1);
 
-        doReturn(mCursor).when(mCallProxy).contentResolverQuery(any(),
-                eq(BluetoothShare.CONTENT_URI), eq(new String[]{
-                        BluetoothShare._DATA
-                }), eq(where), eq(null), eq(BluetoothShare._ID));
-
+        doReturn(mCursor)
+                .when(mCallProxy)
+                .contentResolverQuery(
+                        any(),
+                        eq(BluetoothShare.CONTENT_URI),
+                        eq(new String[] {BluetoothShare._DATA}),
+                        eq(where),
+                        eq(null),
+                        eq(BluetoothShare._ID));
 
         doAnswer(invocation -> cnt.incrementAndGet() > 5).when(mCursor).isAfterLast();
-        doReturn(CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString()).when(mCursor)
-                .getString(0);
+        doReturn(CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString()).when(mCursor).getString(0);
 
-        ArrayList answer = BluetoothOppUtility.queryTransfersInBatch(mContext,
-                timestampValue);
+        ArrayList answer =
+                BluetoothOppUtility.queryTransfersInBatch(mContext, timestampValue);
         for (String url : answer) {
             assertThat(url).isEqualTo(CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString());
         }
@@ -154,26 +166,32 @@ public class BluetoothOppUtilityTest {
         Context spiedContext = spy(new ContextWrapper(mContext));
 
         doReturn(0).when(mCallProxy).contentResolverDelete(any(), any(), any(), any());
-        doReturn(mCursor).when(mCallProxy).contentResolverQuery(any(),
-                eq(contentResolverUri), any(), eq(null),
-                eq(null), eq(null));
+        doReturn(mCursor)
+                .when(mCallProxy)
+                .contentResolverQuery(
+                        any(), eq(contentResolverUri), any(), eq(null), eq(null), eq(null));
 
         doReturn(true).when(mCursor).moveToFirst();
         doReturn(fileUri.toString()).when(mCursor).getString(anyInt());
 
-        doReturn(0).when(mCallProxy).contentResolverDelete(any(), any(), nullable(String.class),
-                nullable(String[].class));
+        doReturn(0)
+                .when(mCallProxy)
+                .contentResolverDelete(
+                        any(), any(), nullable(String.class), nullable(String[].class));
 
         // Do nothing since we don't need the actual activity to be launched.
         doNothing().when(spiedContext).startActivity(any());
 
-        BluetoothOppUtility.openReceivedFile(spiedContext, "randomFileName.txt",
-                "text/plain", 0L, contentResolverUri);
+        BluetoothOppUtility.openReceivedFile(
+                spiedContext, "randomFileName.txt", "text/plain", 0L, contentResolverUri);
 
-        verify(spiedContext).startActivity(argThat(argument
-                -> Objects.equals(argument.getComponent().getClassName(),
-                BluetoothOppBtErrorActivity.class.getName())
-        ));
+        verify(spiedContext)
+                .startActivity(
+                        argThat(
+                                argument ->
+                                        Objects.equals(
+                                                argument.getComponent().getClassName(),
+                                                BluetoothOppBtErrorActivity.class.getName())));
     }
 
     @Test
@@ -185,9 +203,10 @@ public class BluetoothOppUtilityTest {
 
         Context spiedContext = spy(new ContextWrapper(mContext));
         // Control BluetoothOppUtility#fileExists flow
-        doReturn(mCursor).when(mCallProxy).contentResolverQuery(any(),
-                eq(contentResolverUri), any(), eq(null),
-                eq(null), eq(null));
+        doReturn(mCursor)
+                .when(mCallProxy)
+                .contentResolverQuery(
+                        any(), eq(contentResolverUri), any(), eq(null), eq(null), eq(null));
 
         doReturn(true).when(mCursor).moveToFirst();
         doReturn(fileUri.toString()).when(mCursor).getString(anyInt());
@@ -198,17 +217,23 @@ public class BluetoothOppUtilityTest {
         // Control BluetoothOppUtility#isRecognizedFileType flow
         PackageManager mockManager = mock(PackageManager.class);
         doReturn(mockManager).when(spiedContext).getPackageManager();
-        doReturn(List.of(new ResolveInfo())).when(mockManager).queryIntentActivities(any(),
-                anyInt());
-
-        BluetoothOppUtility.openReceivedFile(spiedContext, "randomFileName.txt",
-                "text/plain", 0L, contentResolverUri);
-
-        verify(spiedContext).startActivity(argThat(argument
-                        -> Objects.equals(
-                        argument.getData(), Uri.parse("content:///tmp/randomFileName.txt")
-                ) && Objects.equals(argument.getAction(), Intent.ACTION_VIEW)
-        ));
+        doReturn(List.of(new ResolveInfo()))
+                .when(mockManager)
+                .queryIntentActivities(any(), anyInt());
+
+        BluetoothOppUtility.openReceivedFile(
+                spiedContext, "randomFileName.txt", "text/plain", 0L, contentResolverUri);
+
+        verify(spiedContext)
+                .startActivity(
+                        argThat(
+                                argument ->
+                                        Objects.equals(
+                                                        argument.getData(),
+                                                        Uri.parse(
+                                                                "content:///tmp/randomFileName.txt"))
+                                                && Objects.equals(
+                                                        argument.getAction(), Intent.ACTION_VIEW)));
 
         verify(pfd).close();
     }
@@ -221,14 +246,14 @@ public class BluetoothOppUtilityTest {
 
         Context spiedContext = spy(new ContextWrapper(mContext));
         // Control BluetoothOppUtility#fileExists flow
-        doReturn(mCursor).when(mCallProxy).contentResolverQuery(any(),
-                eq(contentResolverUri), any(), eq(null),
-                eq(null), eq(null));
+        doReturn(mCursor)
+                .when(mCallProxy)
+                .contentResolverQuery(
+                        any(), eq(contentResolverUri), any(), eq(null), eq(null), eq(null));
 
         doReturn(true).when(mCursor).moveToFirst();
         doReturn(fileUri.toString()).when(mCursor).getString(anyInt());
 
-
         doReturn(0).when(mCallProxy).contentResolverDelete(any(), any(), any(), any());
         doReturn(pfd).when(mCallProxy).contentResolverOpenFileDescriptor(any(), eq(fileUri), any());
 
@@ -240,13 +265,18 @@ public class BluetoothOppUtilityTest {
         // Do nothing since we don't need the actual activity to be launched.
         doNothing().when(spiedContext).startActivity(any());
 
-        BluetoothOppUtility.openReceivedFile(spiedContext, "randomFileName.txt",
-                "text/plain", 0L, contentResolverUri);
-
-        verify(spiedContext).startActivity(
-                argThat(argument -> argument.getComponent().getClassName().equals(
-                        BluetoothOppBtErrorActivity.class.getName())
-                ));
+        BluetoothOppUtility.openReceivedFile(
+                spiedContext, "randomFileName.txt", "text/plain", 0L, contentResolverUri);
+
+        verify(spiedContext)
+                .startActivity(
+                        argThat(
+                                argument ->
+                                        argument.getComponent()
+                                                .getClassName()
+                                                .equals(
+                                                        BluetoothOppBtErrorActivity.class
+                                                                .getName())));
         verify(pfd).close();
     }
 
@@ -266,18 +296,18 @@ public class BluetoothOppUtilityTest {
         String deviceNameValue =
                 BluetoothOppManager.getInstance(mContext).getDeviceName(remoteDevice);
 
-        List cursorMockDataList = List.of(
-                new CursorMockData(BluetoothShare._ID, 0, idValue),
-                new CursorMockData(BluetoothShare.STATUS, 1, statusValue),
-                new CursorMockData(BluetoothShare.DIRECTION, 2, directionValue),
-                new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, totalBytesValue),
-                new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, currentBytesValue),
-                new CursorMockData(BluetoothShare.TIMESTAMP, 5, timestampValue),
-                new CursorMockData(BluetoothShare.DESTINATION, 6, destinationValue),
-                new CursorMockData(BluetoothShare._DATA, 7, null),
-                new CursorMockData(BluetoothShare.FILENAME_HINT, 8, null),
-                new CursorMockData(BluetoothShare.MIMETYPE, 9, fileTypeValue)
-        );
+        List cursorMockDataList =
+                List.of(
+                        new CursorMockData(BluetoothShare._ID, 0, idValue),
+                        new CursorMockData(BluetoothShare.STATUS, 1, statusValue),
+                        new CursorMockData(BluetoothShare.DIRECTION, 2, directionValue),
+                        new CursorMockData(BluetoothShare.TOTAL_BYTES, 3, totalBytesValue),
+                        new CursorMockData(BluetoothShare.CURRENT_BYTES, 4, currentBytesValue),
+                        new CursorMockData(BluetoothShare.TIMESTAMP, 5, timestampValue),
+                        new CursorMockData(BluetoothShare.DESTINATION, 6, destinationValue),
+                        new CursorMockData(BluetoothShare._DATA, 7, null),
+                        new CursorMockData(BluetoothShare.FILENAME_HINT, 8, null),
+                        new CursorMockData(BluetoothShare.MIMETYPE, 9, fileTypeValue));
 
         BluetoothOppTestUtils.setUpMockCursor(mCursor, cursorMockDataList);
 
@@ -300,18 +330,16 @@ public class BluetoothOppUtilityTest {
 
     @Test
     public void fileExists_returnFalse() {
-        assertThat(
-                BluetoothOppUtility.fileExists(mContext, CORRECT_FORMAT_BUT_INVALID_FILE_URI)
-        ).isFalse();
+        assertThat(BluetoothOppUtility.fileExists(mContext, CORRECT_FORMAT_BUT_INVALID_FILE_URI))
+                .isFalse();
     }
 
     @Test
     public void isRecognizedFileType_withWrongFileUriAndMimeType_returnFalse() {
         assertThat(
-                BluetoothOppUtility.isRecognizedFileType(mContext,
-                        CORRECT_FORMAT_BUT_INVALID_FILE_URI,
-                        "aWrongMimeType")
-        ).isFalse();
+                        BluetoothOppUtility.isRecognizedFileType(
+                                mContext, CORRECT_FORMAT_BUT_INVALID_FILE_URI, "aWrongMimeType"))
+                .isFalse();
     }
 
     @Test
@@ -329,47 +357,60 @@ public class BluetoothOppUtilityTest {
     @Test
     public void getStatusDescription_returnCorrectString() {
         String deviceName = "randomName";
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_PENDING, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_pending));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_RUNNING, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_running));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_SUCCESS, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_success));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_NOT_ACCEPTABLE, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_not_accept));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_FORBIDDEN, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_forbidden));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_CANCELED, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_canceled));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_FILE_ERROR, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_file_error));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_CONNECTION_ERROR, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_connection_error));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_ERROR_NO_SDCARD, deviceName)).isEqualTo(
-                mContext.getString(BluetoothOppUtility.deviceHasNoSdCard()
-                        ? R.string.status_no_sd_card_nosdcard
-                        : R.string.status_no_sd_card_default)
-        );
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_ERROR_SDCARD_FULL, deviceName)).isEqualTo(
-                mContext.getString(
-                        BluetoothOppUtility.deviceHasNoSdCard() ? R.string.bt_sm_2_1_nosdcard
-                                : R.string.bt_sm_2_1_default)
-        );
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext,
-                BluetoothShare.STATUS_BAD_REQUEST, deviceName)).isEqualTo(
-                mContext.getString(R.string.status_protocol_error));
-        assertThat(BluetoothOppUtility.getStatusDescription(mContext, 12345465,
-                deviceName)).isEqualTo(mContext.getString(R.string.status_unknown_error));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_PENDING, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_pending));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_RUNNING, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_running));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_SUCCESS, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_success));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_NOT_ACCEPTABLE, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_not_accept));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_FORBIDDEN, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_forbidden));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_CANCELED, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_canceled));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_FILE_ERROR, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_file_error));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_CONNECTION_ERROR, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_connection_error));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_ERROR_NO_SDCARD, deviceName))
+                .isEqualTo(
+                        mContext.getString(
+                                BluetoothOppUtility.deviceHasNoSdCard()
+                                        ? R.string.status_no_sd_card_nosdcard
+                                        : R.string.status_no_sd_card_default));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_ERROR_SDCARD_FULL, deviceName))
+                .isEqualTo(
+                        mContext.getString(
+                                BluetoothOppUtility.deviceHasNoSdCard()
+                                        ? R.string.bt_sm_2_1_nosdcard
+                                        : R.string.bt_sm_2_1_default));
+        assertThat(
+                        BluetoothOppUtility.getStatusDescription(
+                                mContext, BluetoothShare.STATUS_BAD_REQUEST, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_protocol_error));
+        assertThat(BluetoothOppUtility.getStatusDescription(mContext, 12345465, deviceName))
+                .isEqualTo(mContext.getString(R.string.status_unknown_error));
     }
 
     @Test
@@ -381,22 +422,21 @@ public class BluetoothOppUtilityTest {
 
     @Test
     public void fileInfo_testFileInfoFunctions() {
+        assertThat(BluetoothOppUtility.getSendFileInfo(CORRECT_FORMAT_BUT_INVALID_FILE_URI))
+                .isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
         assertThat(
-                BluetoothOppUtility.getSendFileInfo(CORRECT_FORMAT_BUT_INVALID_FILE_URI)
-        ).isEqualTo(
-                BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR
-        );
-        assertThat(BluetoothOppUtility.generateUri(CORRECT_FORMAT_BUT_INVALID_FILE_URI,
-                BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR).toString()
-        ).contains(
-                CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString());
+                        BluetoothOppUtility.generateUri(
+                                        CORRECT_FORMAT_BUT_INVALID_FILE_URI,
+                                        BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR)
+                                .toString())
+                .contains(CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString());
         try {
-            BluetoothOppUtility.putSendFileInfo(CORRECT_FORMAT_BUT_INVALID_FILE_URI,
+            BluetoothOppUtility.putSendFileInfo(
+                    CORRECT_FORMAT_BUT_INVALID_FILE_URI,
                     BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
             BluetoothOppUtility.closeSendFileInfo(CORRECT_FORMAT_BUT_INVALID_FILE_URI);
         } catch (Exception e) {
             assertWithMessage("Exception should not happen. " + e).fail();
         }
     }
-
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java
index 68756b67e68..b43c6f93a6c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java
@@ -74,10 +74,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 public class IncomingFileConfirmActivityTest {
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Cursor mCursor;
-    @Spy
-    BluetoothMethodProxy mBluetoothMethodProxy;
+    @Mock Cursor mCursor;
+    @Spy BluetoothMethodProxy mBluetoothMethodProxy;
 
     List mCursorMockDataList;
 
@@ -104,38 +102,50 @@ public class IncomingFileConfirmActivityTest {
         mIntent.setClass(mTargetContext, BluetoothOppIncomingFileConfirmActivity.class);
         mIntent.setData(dataUrl);
 
-        doReturn(mCursor).when(mBluetoothMethodProxy).contentResolverQuery(any(), eq(dataUrl),
-                eq(null), eq(null),
-                eq(null), eq(null));
+        doReturn(mCursor)
+                .when(mBluetoothMethodProxy)
+                .contentResolverQuery(any(), eq(dataUrl), eq(null), eq(null), eq(null), eq(null));
 
-        doReturn(1).when(mBluetoothMethodProxy).contentResolverUpdate(any(), eq(dataUrl),
-                any(), eq(null), eq(null));
+        doReturn(1)
+                .when(mBluetoothMethodProxy)
+                .contentResolverUpdate(any(), eq(dataUrl), any(), eq(null), eq(null));
 
         int idValue = 1234;
         Long timestampValue = 123456789L;
         String destinationValue = "AA:BB:CC:00:11:22";
         String fileTypeValue = "text/plain";
 
-        mCursorMockDataList = new ArrayList<>(List.of(
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.STATUS, 1,
-                        BluetoothShare.STATUS_PENDING),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DIRECTION, 2,
-                        BluetoothShare.DIRECTION_OUTBOUND),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TOTAL_BYTES, 3, 100),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.CURRENT_BYTES, 4, 0),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare._ID, 0, idValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.MIMETYPE, 5, fileTypeValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.TIMESTAMP, 6,
-                        timestampValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DESTINATION, 7,
-                        destinationValue),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare._DATA, 8, null),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.FILENAME_HINT, 9, null),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.URI, 10,
-                        "content://textfile.txt"),
-                new BluetoothOppTestUtils.CursorMockData(BluetoothShare.USER_CONFIRMATION, 11,
-                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)
-        ));
+        mCursorMockDataList =
+                new ArrayList<>(
+                        List.of(
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.STATUS, 1, BluetoothShare.STATUS_PENDING),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.DIRECTION,
+                                        2,
+                                        BluetoothShare.DIRECTION_OUTBOUND),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.TOTAL_BYTES, 3, 100),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.CURRENT_BYTES, 4, 0),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare._ID, 0, idValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.MIMETYPE, 5, fileTypeValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.TIMESTAMP, 6, timestampValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.DESTINATION, 7, destinationValue),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare._DATA, 8, null),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.FILENAME_HINT, 9, null),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.URI, 10, "content://textfile.txt"),
+                                new BluetoothOppTestUtils.CursorMockData(
+                                        BluetoothShare.USER_CONFIRMATION,
+                                        11,
+                                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)));
 
         BluetoothOppTestUtils.enableActivity(
                 BluetoothOppIncomingFileConfirmActivity.class, true, mTargetContext);
@@ -156,10 +166,9 @@ public class IncomingFileConfirmActivityTest {
             throws InterruptedException {
         BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList);
 
-        ActivityScenario activityScenario
-                = ActivityScenario.launch(mIntent);
-        activityScenario.onActivity(activity -> {
-        });
+        ActivityScenario activityScenario =
+                ActivityScenario.launch(mIntent);
+        activityScenario.onActivity(activity -> {});
 
         // To work around (possibly) ActivityScenario's bug.
         // The dialog button is clicked (no error throw) but onClick() is not triggered.
@@ -169,13 +178,21 @@ public class IncomingFileConfirmActivityTest {
                 .inRoot(isDialog())
                 .perform(ViewActions.scrollTo());
         onView(withText(mTargetContext.getText(R.string.incoming_file_confirm_cancel).toString()))
-                .inRoot(isDialog()).check(matches(isDisplayed())).perform(click());
-
-        verify(mBluetoothMethodProxy).contentResolverUpdate(any(), any(), argThat(
-                argument -> Objects.equal(
-                        BluetoothShare.USER_CONFIRMATION_DENIED,
-                        argument.get(BluetoothShare.USER_CONFIRMATION))
-        ), nullable(String.class), nullable(String[].class));
+                .inRoot(isDialog())
+                .check(matches(isDisplayed()))
+                .perform(click());
+
+        verify(mBluetoothMethodProxy)
+                .contentResolverUpdate(
+                        any(),
+                        any(),
+                        argThat(
+                                argument ->
+                                        Objects.equal(
+                                                BluetoothShare.USER_CONFIRMATION_DENIED,
+                                                argument.get(BluetoothShare.USER_CONFIRMATION))),
+                        nullable(String.class),
+                        nullable(String[].class));
     }
 
     @Test
@@ -193,13 +210,21 @@ public class IncomingFileConfirmActivityTest {
                 .inRoot(isDialog())
                 .perform(ViewActions.scrollTo());
         onView(withText(mTargetContext.getText(R.string.incoming_file_confirm_ok).toString()))
-                .inRoot(isDialog()).check(matches(isDisplayed())).perform(click());
-
-        verify(mBluetoothMethodProxy).contentResolverUpdate(any(), any(), argThat(
-                argument -> Objects.equal(
-                        BluetoothShare.USER_CONFIRMATION_CONFIRMED,
-                        argument.get(BluetoothShare.USER_CONFIRMATION))
-        ), nullable(String.class), nullable(String[].class));
+                .inRoot(isDialog())
+                .check(matches(isDisplayed()))
+                .perform(click());
+
+        verify(mBluetoothMethodProxy)
+                .contentResolverUpdate(
+                        any(),
+                        any(),
+                        argThat(
+                                argument ->
+                                        Objects.equal(
+                                                BluetoothShare.USER_CONFIRMATION_CONFIRMED,
+                                                argument.get(BluetoothShare.USER_CONFIRMATION))),
+                        nullable(String.class),
+                        nullable(String[].class));
     }
 
     @Test
@@ -212,8 +237,9 @@ public class IncomingFileConfirmActivityTest {
         Intent in = new Intent(BluetoothShare.USER_CONFIRMATION_TIMEOUT_ACTION);
         mTargetContext.sendBroadcast(in);
 
-        verify(mBluetoothMethodProxy, timeout(TIMEOUT_MS)).handlerSendMessageDelayed(any(),
-                eq(DISMISS_TIMEOUT_DIALOG), eq((long) DISMISS_TIMEOUT_DIALOG_VALUE));
+        verify(mBluetoothMethodProxy, timeout(TIMEOUT_MS))
+                .handlerSendMessageDelayed(
+                        any(), eq(DISMISS_TIMEOUT_DIALOG), eq((long) DISMISS_TIMEOUT_DIALOG_VALUE));
     }
 
     @Test
@@ -222,19 +248,26 @@ public class IncomingFileConfirmActivityTest {
         ActivityScenario scenario =
                 ActivityScenario.launch(mIntent);
         AtomicBoolean atomicBoolean = new AtomicBoolean();
-        scenario.onActivity(activity -> {
-            atomicBoolean.set(activity.onKeyDown(KeyEvent.KEYCODE_A,
-                    new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)));
-        });
+        scenario.onActivity(
+                activity -> {
+                    atomicBoolean.set(
+                            activity.onKeyDown(
+                                    KeyEvent.KEYCODE_A,
+                                    new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)));
+                });
 
         assertThat(atomicBoolean.get()).isFalse();
         assertThat(scenario.getState()).isNotEqualTo(Lifecycle.State.DESTROYED);
 
-        scenario.onActivity(activity -> {
-            atomicBoolean.set(activity.onKeyDown(KeyEvent.KEYCODE_BACK,
-                    new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK))
-                    && activity.isFinishing());
-        });
+        scenario.onActivity(
+                activity -> {
+                    atomicBoolean.set(
+                            activity.onKeyDown(
+                                            KeyEvent.KEYCODE_BACK,
+                                            new KeyEvent(
+                                                    KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK))
+                                    && activity.isFinishing());
+                });
 
         assertThat(atomicBoolean.get()).isTrue();
     }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java b/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java
index 2710aa18211..4fa885f1835 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java
@@ -114,13 +114,13 @@ public class TestActivity extends Activity {
                  * Email.ACCEPTABLE_ATTACHMENT_SEND_TYPES)) {
                  * addAttachment(stream);
                  */
-                Log.v(Constants.TAG,
+                Log.v(
+                        Constants.TAG,
                         " Get share intent with Uri " + stream + " mimetype is " + type);
                 // Log.v(Constants.TAG, " trying Uri function " +
                 // stream.getAuthority() + " " + Uri.parse(stream));
                 Cursor cursor = c.getContentResolver().query(stream, null, null, null, null);
                 cursor.close();
-
             }
             /* start insert a record */
             /*
@@ -212,149 +212,164 @@ public class TestActivity extends Activity {
 
     }
 
-    public OnClickListener insertRecordListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
+    public OnClickListener insertRecordListener =
+            new OnClickListener() {
+                @Override
+                public void onClick(View view) {
 
-            String address = null;
-            if (mAddressView.getText().length() != 0) {
-                address = mAddressView.getText().toString();
-                Log.v(Constants.TAG, "Send to address  " + address);
-            }
-            if (address == null) {
-                address = "00:17:83:58:5D:CC";
-            }
+                    String address = null;
+                    if (mAddressView.getText().length() != 0) {
+                        address = mAddressView.getText().toString();
+                        Log.v(Constants.TAG, "Send to address  " + address);
+                    }
+                    if (address == null) {
+                        address = "00:17:83:58:5D:CC";
+                    }
 
-            Integer media = null;
-            if (mMediaView.getText().length() != 0) {
-                media = Integer.parseInt(mMediaView.getText().toString().trim());
-                Log.v(Constants.TAG, "Send media no.  " + media);
-            }
-            if (media == null) {
-                media = 1;
-            }
-            ContentValues values = new ContentValues();
-            values.put(BluetoothShare.URI, "content://media/external/images/media/" + media);
-            // values.put(BluetoothShare.DESTINATION, "FF:FF:FF:00:00:00");
-            // baibai Q9 test
-            // values.put(BluetoothShare.DESTINATION, "12:34:56:78:9A:BC");
-            // java's nokia
-            // values.put(BluetoothShare.DESTINATION, "00:1B:33:F0:58:FB");
-            // Assis phone
-            // values.put(BluetoothShare.DESTINATION, "00:17:E5:5D:74:F3");
-            // Jackson E6
-            // values.put(BluetoothShare.DESTINATION, "00:1A:1B:7F:1E:F0");
-            // Baibai V950
-            // values.put(BluetoothShare.DESTINATION, "00:17:83:58:5D:CC");
-            // Baibai NSC1173
-            // values.put(BluetoothShare.DESTINATION, "00:16:41:49:5B:F3");
-
-            values.put(BluetoothShare.DESTINATION, address);
-
-            values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_OUTBOUND);
-
-            Long ts = System.currentTimeMillis();
-            values.put(BluetoothShare.TIMESTAMP, ts);
-
-            Integer records = null;
-            if (mInsertView.getText().length() != 0) {
-                records = Integer.parseInt(mInsertView.getText().toString().trim());
-                Log.v(Constants.TAG, "parseInt  " + records);
-            }
-            if (records == null) {
-                records = 1;
-            }
-            for (int i = 0; i < records; i++) {
-                Uri contentUri = getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
-                Log.v(Constants.TAG, "insert contentUri: " + contentUri);
-                currentInsert = contentUri.getPathSegments().get(1);
-                Log.v(Constants.TAG, "currentInsert = " + currentInsert);
-            }
+                    Integer media = null;
+                    if (mMediaView.getText().length() != 0) {
+                        media = Integer.parseInt(mMediaView.getText().toString().trim());
+                        Log.v(Constants.TAG, "Send media no.  " + media);
+                    }
+                    if (media == null) {
+                        media = 1;
+                    }
+                    ContentValues values = new ContentValues();
+                    values.put(
+                            BluetoothShare.URI, "content://media/external/images/media/" + media);
+                    // values.put(BluetoothShare.DESTINATION, "FF:FF:FF:00:00:00");
+                    // baibai Q9 test
+                    // values.put(BluetoothShare.DESTINATION, "12:34:56:78:9A:BC");
+                    // java's nokia
+                    // values.put(BluetoothShare.DESTINATION, "00:1B:33:F0:58:FB");
+                    // Assis phone
+                    // values.put(BluetoothShare.DESTINATION, "00:17:E5:5D:74:F3");
+                    // Jackson E6
+                    // values.put(BluetoothShare.DESTINATION, "00:1A:1B:7F:1E:F0");
+                    // Baibai V950
+                    // values.put(BluetoothShare.DESTINATION, "00:17:83:58:5D:CC");
+                    // Baibai NSC1173
+                    // values.put(BluetoothShare.DESTINATION, "00:16:41:49:5B:F3");
+
+                    values.put(BluetoothShare.DESTINATION, address);
+
+                    values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_OUTBOUND);
+
+                    Long ts = System.currentTimeMillis();
+                    values.put(BluetoothShare.TIMESTAMP, ts);
+
+                    Integer records = null;
+                    if (mInsertView.getText().length() != 0) {
+                        records = Integer.parseInt(mInsertView.getText().toString().trim());
+                        Log.v(Constants.TAG, "parseInt  " + records);
+                    }
+                    if (records == null) {
+                        records = 1;
+                    }
+                    for (int i = 0; i < records; i++) {
+                        Uri contentUri =
+                                getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
+                        Log.v(Constants.TAG, "insert contentUri: " + contentUri);
+                        currentInsert = contentUri.getPathSegments().get(1);
+                        Log.v(Constants.TAG, "currentInsert = " + currentInsert);
+                    }
+                }
+            };
 
-        }
-    };
-
-    public OnClickListener deleteRecordListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            Uri contentUri =
-                    Uri.parse(BluetoothShare.CONTENT_URI + "/" + mDeleteView.getText().toString());
-            getContentResolver().delete(contentUri, null, null);
-        }
-    };
-
-    public OnClickListener updateRecordListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            Uri contentUri =
-                    Uri.parse(BluetoothShare.CONTENT_URI + "/" + mUpdateView.getText().toString());
-            ContentValues updateValues = new ContentValues();
-            // mCurrentByte ++;
-            // updateValues.put(BluetoothShare.TOTAL_BYTES, "120000");
-            // updateValues.put(BluetoothShare.CURRENT_BYTES, mCurrentByte);
-            // updateValues.put(BluetoothShare.VISIBILITY,
-            // BluetoothShare.VISIBILITY_HIDDEN);
-            updateValues.put(BluetoothShare.USER_CONFIRMATION,
-                    BluetoothShare.USER_CONFIRMATION_CONFIRMED);
-            getContentResolver().update(contentUri, updateValues, null, null);
-        }
-    };
-
-    public OnClickListener ackRecordListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            Uri contentUri =
-                    Uri.parse(BluetoothShare.CONTENT_URI + "/" + mAckView.getText().toString());
-            ContentValues updateValues = new ContentValues();
-            // mCurrentByte ++;
-            // updateValues.put(BluetoothShare.TOTAL_BYTES, "120000");
-            // updateValues.put(BluetoothShare.CURRENT_BYTES, mCurrentByte);
-            updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN);
-            // updateValues.put(BluetoothShare.USER_CONFIRMATION,
-            // BluetoothShare.USER_CONFIRMATION_CONFIRMED);
-            getContentResolver().update(contentUri, updateValues, null, null);
-        }
-    };
+    public OnClickListener deleteRecordListener =
+            new OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    Uri contentUri =
+                            Uri.parse(
+                                    BluetoothShare.CONTENT_URI
+                                            + "/"
+                                            + mDeleteView.getText().toString());
+                    getContentResolver().delete(contentUri, null, null);
+                }
+            };
 
-    public OnClickListener deleteAllRecordListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            Uri contentUri = Uri.parse(String.valueOf(BluetoothShare.CONTENT_URI));
-            getContentResolver().delete(contentUri, null, null);
-        }
-    };
-
-    public OnClickListener startTcpServerListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            mServer = new TestTcpServer();
-            Thread serverThread = new Thread(mServer);
-            serverThread.start();
-        }
-    };
+    public OnClickListener updateRecordListener =
+            new OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    Uri contentUri =
+                            Uri.parse(
+                                    BluetoothShare.CONTENT_URI
+                                            + "/"
+                                            + mUpdateView.getText().toString());
+                    ContentValues updateValues = new ContentValues();
+                    // mCurrentByte ++;
+                    // updateValues.put(BluetoothShare.TOTAL_BYTES, "120000");
+                    // updateValues.put(BluetoothShare.CURRENT_BYTES, mCurrentByte);
+                    // updateValues.put(BluetoothShare.VISIBILITY,
+                    // BluetoothShare.VISIBILITY_HIDDEN);
+                    updateValues.put(
+                            BluetoothShare.USER_CONFIRMATION,
+                            BluetoothShare.USER_CONFIRMATION_CONFIRMED);
+                    getContentResolver().update(contentUri, updateValues, null, null);
+                }
+            };
 
-    public OnClickListener notifyTcpServerListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            final Thread notifyThread = new Thread() {
+    public OnClickListener ackRecordListener =
+            new OnClickListener() {
                 @Override
-                public void run() {
-                    synchronized (mServer) {
-                        mServer.a = true;
-                        mServer.notify();
-                    }
+                public void onClick(View view) {
+                    Uri contentUri =
+                            Uri.parse(
+                                    BluetoothShare.CONTENT_URI
+                                            + "/"
+                                            + mAckView.getText().toString());
+                    ContentValues updateValues = new ContentValues();
+                    // mCurrentByte ++;
+                    // updateValues.put(BluetoothShare.TOTAL_BYTES, "120000");
+                    // updateValues.put(BluetoothShare.CURRENT_BYTES, mCurrentByte);
+                    updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN);
+                    // updateValues.put(BluetoothShare.USER_CONFIRMATION,
+                    // BluetoothShare.USER_CONFIRMATION_CONFIRMED);
+                    getContentResolver().update(contentUri, updateValues, null, null);
+                }
+            };
+
+    public OnClickListener deleteAllRecordListener =
+            new OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    Uri contentUri = Uri.parse(String.valueOf(BluetoothShare.CONTENT_URI));
+                    getContentResolver().delete(contentUri, null, null);
                 }
+            };
 
+    public OnClickListener startTcpServerListener =
+            new OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    mServer = new TestTcpServer();
+                    Thread serverThread = new Thread(mServer);
+                    serverThread.start();
+                }
             };
-            notifyThread.start();
-        }
 
-    };
+    public OnClickListener notifyTcpServerListener =
+            new OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    final Thread notifyThread =
+                            new Thread() {
+                                @Override
+                                public void run() {
+                                    synchronized (mServer) {
+                                        mServer.a = true;
+                                        mServer.notify();
+                                    }
+                                }
+                            };
+                    notifyThread.start();
+                }
+            };
 }
 
-/**
- * This class listens on OPUSH channel for incoming connection
- */
+/** This class listens on OPUSH channel for incoming connection */
 class TestTcpListener {
 
     private static final String TAG = "BtOppRfcommListener";
@@ -388,66 +403,73 @@ class TestTcpListener {
     public synchronized boolean start(Handler callback) {
         if (mSocketAcceptThread == null) {
             mCallback = callback;
-            mSocketAcceptThread = new Thread(TAG) {
-                ServerSocket mServerSocket;
-
-                @Override
-                public void run() {
-                    if (D) {
-                        Log.d(TAG, "RfcommSocket listen thread starting");
-                    }
-                    try {
-                        if (V) {
-                            Log.v(TAG,
-                                    "Create server RfcommSocket on channel" + mBtOppRfcommChannel);
-                        }
-                        mServerSocket = new ServerSocket(6500, 1);
-                    } catch (IOException e) {
-                        Log.e(TAG, "Error listing on channel" + mBtOppRfcommChannel);
-                        mInterrupted = true;
-                    }
-                    while (!mInterrupted) {
-                        try {
-                            mServerSocket.setSoTimeout(ACCEPT_WAIT_TIMEOUT);
-                            Socket clientSocket = mServerSocket.accept();
-                            if (clientSocket == null) {
+            mSocketAcceptThread =
+                    new Thread(TAG) {
+                        ServerSocket mServerSocket;
+
+                        @Override
+                        public void run() {
+                            if (D) {
+                                Log.d(TAG, "RfcommSocket listen thread starting");
+                            }
+                            try {
                                 if (V) {
-                                    Log.v(TAG, "incomming connection time out");
-                                }
-                            } else {
-                                if (D) {
-                                    Log.d(TAG, "RfcommSocket connected!");
+                                    Log.v(
+                                            TAG,
+                                            "Create server RfcommSocket on channel"
+                                                    + mBtOppRfcommChannel);
                                 }
-                                Log.d(TAG,
-                                        "remote addr is " + clientSocket.getRemoteSocketAddress());
-                                TestTcpTransport transport = new TestTcpTransport(clientSocket);
-                                Message msg = Message.obtain();
-                                msg.setTarget(mCallback);
-                                msg.what = MSG_INCOMING_BTOPP_CONNECTION;
-                                msg.obj = transport;
-                                msg.sendToTarget();
+                                mServerSocket = new ServerSocket(6500, 1);
+                            } catch (IOException e) {
+                                Log.e(TAG, "Error listing on channel" + mBtOppRfcommChannel);
+                                mInterrupted = true;
                             }
-                        } catch (SocketException e) {
-                            Log.e(TAG, "Error accept connection " + e);
-                        } catch (IOException e) {
-                            Log.e(TAG, "Error accept connection " + e);
-                        }
+                            while (!mInterrupted) {
+                                try {
+                                    mServerSocket.setSoTimeout(ACCEPT_WAIT_TIMEOUT);
+                                    Socket clientSocket = mServerSocket.accept();
+                                    if (clientSocket == null) {
+                                        if (V) {
+                                            Log.v(TAG, "incomming connection time out");
+                                        }
+                                    } else {
+                                        if (D) {
+                                            Log.d(TAG, "RfcommSocket connected!");
+                                        }
+                                        Log.d(
+                                                TAG,
+                                                "remote addr is "
+                                                        + clientSocket.getRemoteSocketAddress());
+                                        TestTcpTransport transport =
+                                                new TestTcpTransport(clientSocket);
+                                        Message msg = Message.obtain();
+                                        msg.setTarget(mCallback);
+                                        msg.what = MSG_INCOMING_BTOPP_CONNECTION;
+                                        msg.obj = transport;
+                                        msg.sendToTarget();
+                                    }
+                                } catch (SocketException e) {
+                                    Log.e(TAG, "Error accept connection " + e);
+                                } catch (IOException e) {
+                                    Log.e(TAG, "Error accept connection " + e);
+                                }
 
-                        if (mInterrupted) {
-                            Log.e(TAG, "socketAcceptThread thread was interrupted (2), exiting");
+                                if (mInterrupted) {
+                                    Log.e(
+                                            TAG,
+                                            "socketAcceptThread thread was interrupted (2),"
+                                                    + " exiting");
+                                }
+                            }
+                            if (D) {
+                                Log.d(TAG, "RfcommSocket listen thread finished");
+                            }
                         }
-                    }
-                    if (D) {
-                        Log.d(TAG, "RfcommSocket listen thread finished");
-                    }
-                }
-            };
+                    };
             mInterrupted = false;
             mSocketAcceptThread.start();
-
         }
         return true;
-
     }
 
     public synchronized void stop() {
@@ -471,7 +493,6 @@ class TestTcpListener {
             }
         }
     }
-
 }
 
 class TestTcpServer extends ServerRequestHandler implements Runnable {
@@ -528,8 +549,11 @@ class TestTcpServer extends ServerRequestHandler implements Runnable {
         try {
             java.io.InputStream is = op.openInputStream();
 
-            updateStatus("Got data bytes " + is.available() + " name " + op.getReceivedHeader()
-                    .getHeader(HeaderSet.NAME));
+            updateStatus(
+                    "Got data bytes "
+                            + is.available()
+                            + " name "
+                            + op.getReceivedHeader().getHeader(HeaderSet.NAME));
 
             File f = new File((String) op.getReceivedHeader().getHeader(HeaderSet.NAME));
             fos = new FileOutputStream(f);
@@ -567,8 +591,7 @@ class TestTcpServer extends ServerRequestHandler implements Runnable {
     }
 
     @Override
-    public void onAuthenticationFailure(byte[] userName) {
-    }
+    public void onAuthenticationFailure(byte[] userName) {}
 
     @Override
     public int onSetPath(HeaderSet request, HeaderSet reply, boolean backup, boolean create) {
@@ -585,7 +608,6 @@ class TestTcpServer extends ServerRequestHandler implements Runnable {
     public int onGet(Operation op) {
         return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
     }
-
 }
 
 class TestTcpSessionNotifier {
@@ -613,15 +635,12 @@ class TestTcpSessionNotifier {
         TestTcpTransport tt = new TestTcpTransport(mConn);
 
         return new ServerSession((ObexTransport) tt, handler, auth);
-
     }
 
     public ServerSession acceptAndOpen(ServerRequestHandler handler) throws IOException {
 
         return acceptAndOpen(handler, null);
-
     }
-
 }
 
 class TestTcpTransport implements ObexTransport {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java
index 4adb1889e9c..a80863120b5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java
@@ -42,17 +42,14 @@ import org.mockito.junit.MockitoRule;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * Test cases for {@link BluetoothTetheringNetworkFactory}.
- */
+/** Test cases for {@link BluetoothTetheringNetworkFactory}. */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BluetoothTetheringNetworkFactoryTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private PanService mPanService;
+    @Mock private PanService mPanService;
 
     private Context mContext = ApplicationProvider.getApplicationContext();
 
@@ -100,8 +97,7 @@ public class BluetoothTetheringNetworkFactoryTest {
 
         assertThat(bluetoothTetheringNetworkFactory.getProvider()).isNotNull();
 
-        BluetoothAdapter adapter =
-                mContext.getSystemService(BluetoothManager.class).getAdapter();
+        BluetoothAdapter adapter = mContext.getSystemService(BluetoothManager.class).getAdapter();
         List bluetoothDevices = new ArrayList<>();
         BluetoothDevice bluetoothDevice = adapter.getRemoteDevice("11:11:11:11:11:11");
         bluetoothDevices.add(bluetoothDevice);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java
index 86bfd8e0eaa..2033db98cfc 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java
@@ -40,8 +40,7 @@ public class PanServiceBinderTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private PanService mService;
+    @Mock private PanService mService;
 
     BluetoothDevice mRemoteDevice;
 
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java
index 6467b771613..5d4e9216dc3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java
@@ -175,7 +175,8 @@ public class PanServiceTest {
     public void setConnectionPolicy_whenDatabaseManagerRefuses_returnsFalse() {
         int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED;
         when(mDatabaseManager.setProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PAN, connectionPolicy)).thenReturn(false);
+                        mRemoteDevice, BluetoothProfile.PAN, connectionPolicy))
+                .thenReturn(false);
 
         assertThat(mService.setConnectionPolicy(mRemoteDevice, connectionPolicy)).isFalse();
     }
@@ -183,16 +184,24 @@ public class PanServiceTest {
     @Test
     public void setConnectionPolicy_returnsTrue() {
         when(mDatabaseManager.setProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PAN, BluetoothProfile.CONNECTION_POLICY_ALLOWED))
+                        mRemoteDevice,
+                        BluetoothProfile.PAN,
+                        BluetoothProfile.CONNECTION_POLICY_ALLOWED))
                 .thenReturn(true);
-        assertThat(mService.setConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED)).isTrue();
+        assertThat(
+                        mService.setConnectionPolicy(
+                                mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED))
+                .isTrue();
 
         when(mDatabaseManager.setProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PAN, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN))
+                        mRemoteDevice,
+                        BluetoothProfile.PAN,
+                        BluetoothProfile.CONNECTION_POLICY_FORBIDDEN))
                 .thenReturn(true);
-        assertThat(mService.setConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN)).isTrue();
+        assertThat(
+                        mService.setConnectionPolicy(
+                                mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN))
+                .isTrue();
     }
 
     @Test
@@ -202,8 +211,9 @@ public class PanServiceTest {
         int localRole = 3;
         int remoteRole = 4;
 
-        PanService.ConnectState connectState = new PanService.ConnectState(
-                REMOTE_DEVICE_ADDRESS_AS_ARRAY, state, error, localRole, remoteRole);
+        PanService.ConnectState connectState =
+                new PanService.ConnectState(
+                        REMOTE_DEVICE_ADDRESS_AS_ARRAY, state, error, localRole, remoteRole);
 
         assertThat(connectState.addr).isEqualTo(REMOTE_DEVICE_ADDRESS_AS_ARRAY);
         assertThat(connectState.state).isEqualTo(state);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapActivityTest.java
index e5431c5524f..54674b1d14c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapActivityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapActivityTest.java
@@ -104,8 +104,11 @@ public class BluetoothPbapActivityTest {
     public void onPreferenceChange_returnsTrue() throws Exception {
         AtomicBoolean result = new AtomicBoolean(false);
 
-        mActivityScenario.onActivity(activity -> result.set(
-                activity.onPreferenceChange(/*preference=*/null, /*newValue=*/null)));
+        mActivityScenario.onActivity(
+                activity ->
+                        result.set(
+                                activity.onPreferenceChange(
+                                        /* preference= */ null, /* newValue= */ null)));
 
         assertThat(result.get()).isTrue();
     }
@@ -140,9 +143,10 @@ public class BluetoothPbapActivityTest {
     public void onReceiveTimeoutIntent_sendsDismissDialogMessage() throws Exception {
         Intent intent = new Intent(BluetoothPbapService.USER_CONFIRM_TIMEOUT_ACTION);
 
-        mActivityScenario.onActivity(activity -> {
-            activity.mReceiver.onReceive(activity, intent);
-        });
+        mActivityScenario.onActivity(
+                activity -> {
+                    activity.mReceiver.onReceive(activity, intent);
+                });
 
         verify(mMethodProxy)
                 .handlerSendMessageDelayed(
@@ -154,10 +158,11 @@ public class BluetoothPbapActivityTest {
         Editable editable = new SpannableStringBuilder("An editable text");
         AtomicBoolean result = new AtomicBoolean(false);
 
-        mActivityScenario.onActivity(activity -> {
-            activity.afterTextChanged(editable);
-            result.set(activity.getButton(BUTTON_POSITIVE).isEnabled());
-        });
+        mActivityScenario.onActivity(
+                activity -> {
+                    activity.afterTextChanged(editable);
+                    result.set(activity.getButton(BUTTON_POSITIVE).isEnabled());
+                });
 
         assertThat(result.get()).isTrue();
     }
@@ -169,10 +174,11 @@ public class BluetoothPbapActivityTest {
     @Test
     public void emptyMethods_doesNotThrowException() throws Exception {
         try {
-            mActivityScenario.onActivity(activity -> {
-                activity.beforeTextChanged(null, 0, 0, 0);
-                activity.onTextChanged(null, 0, 0, 0);
-            });
+            mActivityScenario.onActivity(
+                    activity -> {
+                        activity.beforeTextChanged(null, 0, 0, 0);
+                        activity.onTextChanged(null, 0, 0, 0);
+                    });
         } catch (Exception ex) {
             assertWithMessage("Exception should not happen!").fail();
         }
@@ -185,14 +191,17 @@ public class BluetoothPbapActivityTest {
     }
 
     private void enableActivity(boolean enable) {
-        int enabledState = enable ? COMPONENT_ENABLED_STATE_ENABLED
-                : COMPONENT_ENABLED_STATE_DEFAULT;
+        int enabledState =
+                enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT;
 
-        mTargetContext.getPackageManager().setApplicationEnabledSetting(
-                mTargetContext.getPackageName(), enabledState, DONT_KILL_APP);
+        mTargetContext
+                .getPackageManager()
+                .setApplicationEnabledSetting(
+                        mTargetContext.getPackageName(), enabledState, DONT_KILL_APP);
 
         ComponentName activityName = new ComponentName(mTargetContext, BluetoothPbapActivity.class);
-        mTargetContext.getPackageManager().setComponentEnabledSetting(
-                activityName, enabledState, DONT_KILL_APP);
+        mTargetContext
+                .getPackageManager()
+                .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP);
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java
index 9c00501b633..60b79dce88c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java
@@ -42,8 +42,7 @@ public class BluetoothPbapAuthenticatorTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    PbapStateMachine mMockPbapStateMachine;
+    @Mock PbapStateMachine mMockPbapStateMachine;
 
     @Before
     public void setUp() throws Exception {
@@ -90,34 +89,48 @@ public class BluetoothPbapAuthenticatorTest {
     @Test
     public void testOnAuthenticationChallenge() {
         final String sessionKey = "test_session_key";
-        doAnswer(invocation -> {
-            mAuthenticator.setSessionKey(sessionKey);
-            mAuthenticator.setChallenged(true);
-            return null;
-        }).when(mMockPbapStateMachine).sendMessage(PbapStateMachine.CREATE_NOTIFICATION);
+        doAnswer(
+                        invocation -> {
+                            mAuthenticator.setSessionKey(sessionKey);
+                            mAuthenticator.setChallenged(true);
+                            return null;
+                        })
+                .when(mMockPbapStateMachine)
+                .sendMessage(PbapStateMachine.CREATE_NOTIFICATION);
 
         // Note: onAuthenticationChallenge() does not use any arguments
-        PasswordAuthentication passwordAuthentication = mAuthenticator.onAuthenticationChallenge(
-                /*description=*/ null, /*isUserIdRequired=*/ false, /*isFullAccess=*/ false);
+        PasswordAuthentication passwordAuthentication =
+                mAuthenticator.onAuthenticationChallenge(
+                        /* description= */ null,
+                        /* isUserIdRequired= */ false,
+                        /* isFullAccess= */ false);
 
         verify(mMockPbapStateMachine).sendMessage(PbapStateMachine.CREATE_NOTIFICATION);
-        verify(mMockPbapStateMachine).sendMessageDelayed(PbapStateMachine.REMOVE_NOTIFICATION,
-                BluetoothPbapService.USER_CONFIRM_TIMEOUT_VALUE);
+        verify(mMockPbapStateMachine)
+                .sendMessageDelayed(
+                        PbapStateMachine.REMOVE_NOTIFICATION,
+                        BluetoothPbapService.USER_CONFIRM_TIMEOUT_VALUE);
         assertThat(passwordAuthentication.getPassword()).isEqualTo(sessionKey.getBytes());
     }
 
     @Test
     public void testOnAuthenticationChallenge_returnsNullWhenSessionKeyIsEmpty() {
         final String emptySessionKey = "";
-        doAnswer(invocation -> {
-            mAuthenticator.setSessionKey(emptySessionKey);
-            mAuthenticator.setChallenged(true);
-            return null;
-        }).when(mMockPbapStateMachine).sendMessage(PbapStateMachine.CREATE_NOTIFICATION);
+        doAnswer(
+                        invocation -> {
+                            mAuthenticator.setSessionKey(emptySessionKey);
+                            mAuthenticator.setChallenged(true);
+                            return null;
+                        })
+                .when(mMockPbapStateMachine)
+                .sendMessage(PbapStateMachine.CREATE_NOTIFICATION);
 
         // Note: onAuthenticationChallenge() does not use any arguments
-        PasswordAuthentication passwordAuthentication = mAuthenticator.onAuthenticationChallenge(
-                /*description=*/ null, /*isUserIdRequired=*/ false, /*isFullAccess=*/ false);
+        PasswordAuthentication passwordAuthentication =
+                mAuthenticator.onAuthenticationChallenge(
+                        /* description= */ null,
+                        /* isUserIdRequired= */ false,
+                        /* isFullAccess= */ false);
         assertThat(passwordAuthentication).isNull();
     }
 
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java
index 1ea6786e8bf..cd1699a27c9 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java
@@ -64,19 +64,18 @@ public class BluetoothPbapCallLogComposerTest {
 
     private BluetoothPbapCallLogComposer mComposer;
 
-    @Spy
-    BluetoothMethodProxy mPbapCallProxy = BluetoothMethodProxy.getInstance();
+    @Spy BluetoothMethodProxy mPbapCallProxy = BluetoothMethodProxy.getInstance();
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Cursor mMockCursor;
+    @Mock Cursor mMockCursor;
 
     @Before
     public void setUp() throws Exception {
         BluetoothMethodProxy.setInstanceForTesting(mPbapCallProxy);
 
-        doReturn(mMockCursor).when(mPbapCallProxy)
+        doReturn(mMockCursor)
+                .when(mPbapCallProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
         final int validRowCount = 5;
         when(mMockCursor.getCount()).thenReturn(validRowCount);
@@ -92,8 +91,7 @@ public class BluetoothPbapCallLogComposerTest {
 
     @Test
     public void testInit_success() {
-        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER))
-                .isTrue();
+        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER)).isTrue();
         assertThat(mComposer.getErrorReason()).isEqualTo(NO_ERROR);
     }
 
@@ -109,11 +107,11 @@ public class BluetoothPbapCallLogComposerTest {
 
     @Test
     public void testInit_failWhenCursorIsNull() {
-        doReturn(null).when(mPbapCallProxy)
+        doReturn(null)
+                .when(mPbapCallProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
-        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER))
-                .isFalse();
+        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER)).isFalse();
         assertThat(mComposer.getErrorReason())
                 .isEqualTo(FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO);
     }
@@ -122,8 +120,7 @@ public class BluetoothPbapCallLogComposerTest {
     public void testInit_failWhenCursorRowCountIsZero() {
         when(mMockCursor.getCount()).thenReturn(0);
 
-        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER))
-                .isFalse();
+        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER)).isFalse();
         assertThat(mComposer.getErrorReason()).isEqualTo(FAILURE_REASON_NO_ENTRY);
         verify(mMockCursor).close();
     }
@@ -132,8 +129,7 @@ public class BluetoothPbapCallLogComposerTest {
     public void testInit_failWhenCursorMoveToFirstFails() {
         when(mMockCursor.moveToFirst()).thenReturn(false);
 
-        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER))
-                .isFalse();
+        assertThat(mComposer.init(CALL_LOG_URI, SELECTION, SELECTION_ARGS, SORT_ORDER)).isFalse();
         assertThat(mComposer.getErrorReason()).isEqualTo(FAILURE_REASON_NO_ENTRY);
         verify(mMockCursor).close();
     }
@@ -159,8 +155,12 @@ public class BluetoothPbapCallLogComposerTest {
         final String testPhoneName = "test_phone_name";
         final String testPhoneNumber = "0123456789";
 
-        assertThat(BluetoothPbapCallLogComposer.composeVCardForPhoneOwnNumber(
-                testPhoneType, testPhoneName, testPhoneNumber, /*vcardVer21=*/ true))
+        assertThat(
+                        BluetoothPbapCallLogComposer.composeVCardForPhoneOwnNumber(
+                                testPhoneType,
+                                testPhoneName,
+                                testPhoneNumber,
+                                /* vcardVer21= */ true))
                 .contains(testPhoneNumber);
     }
 
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java
index 30445b1399b..634fe3b247c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java
@@ -42,11 +42,9 @@ public class BluetoothPbapConfigTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Context mContext;
+    @Mock Context mContext;
 
-    @Mock
-    Resources mResources;
+    @Mock Resources mResources;
 
     @Before
     public void setUp() throws Exception {
@@ -55,8 +53,7 @@ public class BluetoothPbapConfigTest {
 
     @Test
     public void testInit_whenUseProfileForOwnerVcardIsTrue() {
-        when(mResources.getBoolean(R.bool.pbap_use_profile_for_owner_vcard))
-                .thenReturn(true);
+        when(mResources.getBoolean(R.bool.pbap_use_profile_for_owner_vcard)).thenReturn(true);
 
         BluetoothPbapConfig.init(mContext);
         assertThat(BluetoothPbapConfig.useProfileForOwnerVcard()).isTrue();
@@ -64,8 +61,7 @@ public class BluetoothPbapConfigTest {
 
     @Test
     public void testInit_whenUseProfileForOwnerVcardIsFalse() {
-        when(mResources.getBoolean(R.bool.pbap_use_profile_for_owner_vcard))
-                .thenReturn(false);
+        when(mResources.getBoolean(R.bool.pbap_use_profile_for_owner_vcard)).thenReturn(false);
 
         BluetoothPbapConfig.init(mContext);
         assertThat(BluetoothPbapConfig.useProfileForOwnerVcard()).isFalse();
@@ -82,8 +78,7 @@ public class BluetoothPbapConfigTest {
 
     @Test
     public void testInit_whenIncludePhotosInVcardIsTrue() {
-        when(mResources.getBoolean(R.bool.pbap_include_photos_in_vcard))
-                .thenReturn(true);
+        when(mResources.getBoolean(R.bool.pbap_include_photos_in_vcard)).thenReturn(true);
 
         BluetoothPbapConfig.init(mContext);
         assertThat(BluetoothPbapConfig.includePhotosInVcard()).isTrue();
@@ -91,8 +86,7 @@ public class BluetoothPbapConfigTest {
 
     @Test
     public void testInit_whenIncludePhotosInVcardIsFalse() {
-        when(mResources.getBoolean(R.bool.pbap_include_photos_in_vcard))
-                .thenReturn(false);
+        when(mResources.getBoolean(R.bool.pbap_include_photos_in_vcard)).thenReturn(false);
 
         BluetoothPbapConfig.init(mContext);
         assertThat(BluetoothPbapConfig.includePhotosInVcard()).isFalse();
@@ -106,4 +100,4 @@ public class BluetoothPbapConfigTest {
         BluetoothPbapConfig.init(mContext);
         // Test should not crash
     }
-}
\ No newline at end of file
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java
index 8d176da7a52..473c4fcd43c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java
@@ -89,31 +89,33 @@ public class BluetoothPbapObexServerTest {
     @Mock Handler mMockHandler;
     @Mock PbapStateMachine mMockStateMachine;
 
-    @Spy
-    BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
+    @Spy BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
 
     BluetoothPbapObexServer mServer;
 
-    private static final byte[] WRONG_UUID = new byte[] {
-            0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00,
-    };
+    private static final byte[] WRONG_UUID =
+            new byte[] {
+                0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00,
+            };
 
-    private static final byte[] WRONG_LENGTH_UUID = new byte[] {
-            0x79,
-            0x61,
-            0x35,
-    };
+    private static final byte[] WRONG_LENGTH_UUID =
+            new byte[] {
+                0x79, 0x61, 0x35,
+            };
 
     private static final String ILLEGAL_PATH = "some/random/path";
 
     @Before
     public void setUp() throws Exception {
         BluetoothMethodProxy.setInstanceForTesting(mPbapMethodProxy);
-        mServer = new BluetoothPbapObexServer(
-                mMockHandler, InstrumentationRegistry.getTargetContext(), mMockStateMachine);
+        mServer =
+                new BluetoothPbapObexServer(
+                        mMockHandler,
+                        InstrumentationRegistry.getTargetContext(),
+                        mMockStateMachine);
     }
 
     @After
@@ -122,8 +124,7 @@ public class BluetoothPbapObexServerTest {
     }
 
     @Test
-    public void testOnConnect_whenIoExceptionIsThrownFromGettingTargetHeader()
-            throws Exception {
+    public void testOnConnect_whenIoExceptionIsThrownFromGettingTargetHeader() throws Exception {
         HeaderSet request = new HeaderSet();
         HeaderSet reply = new HeaderSet();
 
@@ -164,8 +165,7 @@ public class BluetoothPbapObexServerTest {
     }
 
     @Test
-    public void testOnConnect_whenIoExceptionIsThrownFromGettingWhoHeader()
-            throws Exception {
+    public void testOnConnect_whenIoExceptionIsThrownFromGettingWhoHeader() throws Exception {
         HeaderSet request = new HeaderSet();
         request.setHeader(HeaderSet.TARGET, BluetoothPbapObexServer.PBAP_TARGET);
         HeaderSet reply = new HeaderSet();
@@ -183,7 +183,8 @@ public class BluetoothPbapObexServerTest {
         request.setHeader(HeaderSet.TARGET, BluetoothPbapObexServer.PBAP_TARGET);
         HeaderSet reply = new HeaderSet();
 
-        doThrow(IOException.class).when(mPbapMethodProxy)
+        doThrow(IOException.class)
+                .when(mPbapMethodProxy)
                 .getHeader(request, HeaderSet.APPLICATION_PARAMETER);
 
         assertThat(mServer.onConnect(request, reply))
@@ -252,7 +253,7 @@ public class BluetoothPbapObexServerTest {
     }
 
     @Test
-    public void testCloseStream_success() throws Exception{
+    public void testCloseStream_success() throws Exception {
         OutputStream outputStream = mock(OutputStream.class);
         Operation operation = mock(Operation.class);
 
@@ -290,7 +291,7 @@ public class BluetoothPbapObexServerTest {
     }
 
     @Test
-    public void testLogHeader() throws Exception{
+    public void testLogHeader() throws Exception {
         HeaderSet headerSet = new HeaderSet();
         try {
             BluetoothPbapObexServer.logHeader(headerSet);
@@ -300,15 +301,13 @@ public class BluetoothPbapObexServerTest {
     }
 
     @Test
-    public void testOnSetPath_whenIoExceptionIsThrownFromGettingNameHeader()
-            throws Exception {
+    public void testOnSetPath_whenIoExceptionIsThrownFromGettingNameHeader() throws Exception {
         HeaderSet request = new HeaderSet();
         HeaderSet reply = new HeaderSet();
         boolean backup = true;
         boolean create = true;
 
-        doThrow(IOException.class).when(mPbapMethodProxy)
-                .getHeader(request, HeaderSet.NAME);
+        doThrow(IOException.class).when(mPbapMethodProxy).getHeader(request, HeaderSet.NAME);
 
         assertThat(mServer.onSetPath(request, reply, backup, create))
                 .isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
@@ -361,7 +360,8 @@ public class BluetoothPbapObexServerTest {
         HeaderSet headerSet = new HeaderSet();
         when(operation.getReceivedHeader()).thenReturn(headerSet);
 
-        doThrow(IOException.class).when(mPbapMethodProxy)
+        doThrow(IOException.class)
+                .when(mPbapMethodProxy)
                 .getHeader(headerSet, HeaderSet.APPLICATION_PARAMETER);
 
         assertThat(mServer.onGet(operation)).isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
@@ -626,8 +626,12 @@ public class BluetoothPbapObexServerTest {
         BluetoothPbapObexServer.writeVCardEntry(vcfIndex, nameWithSpecialChars, stringBuilder);
         String result = stringBuilder.toString();
 
-        String expectedResult = "";
+        String expectedResult =
+                "";
         assertThat(result).isEqualTo(expectedResult);
     }
 
@@ -635,8 +639,7 @@ public class BluetoothPbapObexServerTest {
     public void getDatabaseIdentifier() {
         long databaseIdentifierLow = 1;
         BluetoothPbapUtils.sDbIdentifier.set(databaseIdentifierLow);
-        byte[] expected = new byte[] {0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 1}; // Big-endian
+        byte[] expected = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; // Big-endian
 
         assertThat(mServer.getDatabaseIdentifier()).isEqualTo(expected);
     }
@@ -645,8 +648,7 @@ public class BluetoothPbapObexServerTest {
     public void getPBPrimaryFolderVersion() {
         long primaryVersion = 5;
         BluetoothPbapUtils.sPrimaryVersionCounter = primaryVersion;
-        byte[] expected = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 5}; // Big-endian
+        byte[] expected = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5}; // Big-endian
 
         assertThat(BluetoothPbapObexServer.getPBPrimaryFolderVersion()).isEqualTo(expected);
     }
@@ -655,8 +657,7 @@ public class BluetoothPbapObexServerTest {
     public void getPBSecondaryFolderVersion() {
         long secondaryVersion = 5;
         BluetoothPbapUtils.sSecondaryVersionCounter = secondaryVersion;
-        byte[] expected = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 5}; // Big-endian
+        byte[] expected = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5}; // Big-endian
 
         assertThat(BluetoothPbapObexServer.getPBSecondaryFolderVersion()).isEqualTo(expected);
     }
@@ -681,8 +682,11 @@ public class BluetoothPbapObexServerTest {
 
         byte[] result = param.getHeader();
         assertThat(result).isNotNull();
-        int expectedLength = 2 + ApplicationParameter.TRIPLET_LENGTH.PRIMARYVERSIONCOUNTER_LENGTH
-                + 2 + ApplicationParameter.TRIPLET_LENGTH.SECONDARYVERSIONCOUNTER_LENGTH;
+        int expectedLength =
+                2
+                        + ApplicationParameter.TRIPLET_LENGTH.PRIMARYVERSIONCOUNTER_LENGTH
+                        + 2
+                        + ApplicationParameter.TRIPLET_LENGTH.SECONDARYVERSIONCOUNTER_LENGTH;
         assertThat(result.length).isEqualTo(expectedLength);
     }
 
@@ -690,17 +694,50 @@ public class BluetoothPbapObexServerTest {
     public void setCallversionCounters() {
         ApplicationParameter param = new ApplicationParameter();
         AppParamValue value = new AppParamValue();
-        value.callHistoryVersionCounter = new byte[]
-                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+        value.callHistoryVersionCounter =
+                new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
 
         BluetoothPbapObexServer.setCallversionCounters(param, value);
 
-        byte[] expectedResult = new byte[] {
-                PRIMARYVERSIONCOUNTER_TAGID, PRIMARYVERSIONCOUNTER_LENGTH,
-                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-                SECONDARYVERSIONCOUNTER_TAGID, SECONDARYVERSIONCOUNTER_LENGTH,
-                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
-        };
+        byte[] expectedResult =
+                new byte[] {
+                    PRIMARYVERSIONCOUNTER_TAGID,
+                    PRIMARYVERSIONCOUNTER_LENGTH,
+                    1,
+                    2,
+                    3,
+                    4,
+                    5,
+                    6,
+                    7,
+                    8,
+                    9,
+                    10,
+                    11,
+                    12,
+                    13,
+                    14,
+                    15,
+                    16,
+                    SECONDARYVERSIONCOUNTER_TAGID,
+                    SECONDARYVERSIONCOUNTER_LENGTH,
+                    1,
+                    2,
+                    3,
+                    4,
+                    5,
+                    6,
+                    7,
+                    8,
+                    9,
+                    10,
+                    11,
+                    12,
+                    13,
+                    14,
+                    15,
+                    16
+                };
         assertThat(param.getHeader()).isEqualTo(expectedResult);
     }
 
@@ -750,8 +787,19 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withPropertySelectorTagid() {
-        byte[] rawBytes = new byte[] {PROPERTY_SELECTOR_TAGID, PROPERTY_SELECTOR_LENGTH,
-                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // non-zero value uses filter
+        byte[] rawBytes =
+                new byte[] {
+                    PROPERTY_SELECTOR_TAGID,
+                    PROPERTY_SELECTOR_LENGTH,
+                    0x01,
+                    0x02,
+                    0x03,
+                    0x04,
+                    0x05,
+                    0x06,
+                    0x07,
+                    0x08
+                }; // non-zero value uses filter
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -760,8 +808,10 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withSupportedFeatureTagid() {
-        byte[] rawBytes = new byte[] {SUPPORTEDFEATURE_TAGID, SUPPORTEDFEATURE_LENGTH,
-                0x01, 0x02, 0x03, 0x04};
+        byte[] rawBytes =
+                new byte[] {
+                    SUPPORTEDFEATURE_TAGID, SUPPORTEDFEATURE_LENGTH, 0x01, 0x02, 0x03, 0x04
+                };
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -771,8 +821,7 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withOrderTagid() {
-        byte[] rawBytes = new byte[] {ORDER_TAGID, ORDER_LENGTH,
-                ORDER_BY_ALPHANUMERIC};
+        byte[] rawBytes = new byte[] {ORDER_TAGID, ORDER_LENGTH, ORDER_BY_ALPHANUMERIC};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -782,8 +831,7 @@ public class BluetoothPbapObexServerTest {
     @Test
     public void parseApplicationParameter_withSearchValueTagid() {
         int searchLength = 4;
-        byte[] rawBytes = new byte[] {SEARCH_VALUE_TAGID, (byte) searchLength,
-                'a', 'b', 'c', 'd' };
+        byte[] rawBytes = new byte[] {SEARCH_VALUE_TAGID, (byte) searchLength, 'a', 'b', 'c', 'd'};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -792,8 +840,7 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withSearchAttributeTagid() {
-        byte[] rawBytes = new byte[] {SEARCH_ATTRIBUTE_TAGID, SEARCH_ATTRIBUTE_LENGTH,
-                0x05};
+        byte[] rawBytes = new byte[] {SEARCH_ATTRIBUTE_TAGID, SEARCH_ATTRIBUTE_LENGTH, 0x05};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -802,8 +849,7 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withMaxListCountTagid() {
-        byte[] rawBytes = new byte[] {MAXLISTCOUNT_TAGID, SEARCH_ATTRIBUTE_LENGTH,
-                0x01, 0x02};
+        byte[] rawBytes = new byte[] {MAXLISTCOUNT_TAGID, SEARCH_ATTRIBUTE_LENGTH, 0x01, 0x02};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -812,8 +858,7 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withListStartOffsetTagid() {
-        byte[] rawBytes = new byte[] {LISTSTARTOFFSET_TAGID, LISTSTARTOFFSET_LENGTH,
-                0x01, 0x02};
+        byte[] rawBytes = new byte[] {LISTSTARTOFFSET_TAGID, LISTSTARTOFFSET_LENGTH, 0x01, 0x02};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -822,8 +867,7 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withFormatTagid() {
-        byte[] rawBytes = new byte[] {FORMAT_TAGID, FORMAT_LENGTH,
-                0x01};
+        byte[] rawBytes = new byte[] {FORMAT_TAGID, FORMAT_LENGTH, 0x01};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -832,8 +876,19 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withVCardSelectorTagid() {
-        byte[] rawBytes = new byte[] {VCARDSELECTOR_TAGID, VCARDSELECTOR_LENGTH,
-                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+        byte[] rawBytes =
+                new byte[] {
+                    VCARDSELECTOR_TAGID,
+                    VCARDSELECTOR_LENGTH,
+                    0x01,
+                    0x02,
+                    0x03,
+                    0x04,
+                    0x05,
+                    0x06,
+                    0x07,
+                    0x08
+                };
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
@@ -843,8 +898,8 @@ public class BluetoothPbapObexServerTest {
 
     @Test
     public void parseApplicationParameter_withVCardSelectorOperatorTagid() {
-        byte[] rawBytes = new byte[] {VCARDSELECTOROPERATOR_TAGID, VCARDSELECTOROPERATOR_LENGTH,
-                0x01};
+        byte[] rawBytes =
+                new byte[] {VCARDSELECTOROPERATOR_TAGID, VCARDSELECTOROPERATOR_LENGTH, 0x01};
         AppParamValue appParamValue = new AppParamValue();
 
         assertThat(mServer.parseApplicationParameter(rawBytes, appParamValue)).isTrue();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java
index 116fe9e7430..ff52feeb8fc 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java
@@ -40,8 +40,7 @@ public class BluetoothPbapServiceBinderTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private BluetoothPbapService mService;
+    @Mock private BluetoothPbapService mService;
 
     BluetoothDevice mRemoteDevice;
 
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java
index b509e7e7c4c..013d5dc9200 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java
@@ -171,9 +171,11 @@ public class BluetoothPbapServiceTest {
     @Test
     public void broadcastReceiver_onReceive_withActionConnectionAccessReply() {
         Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
-        intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+        intent.putExtra(
+                BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
                 BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
-        intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
+        intent.putExtra(
+                BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                 BluetoothDevice.CONNECTION_ACCESS_YES);
         intent.putExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, true);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java
index 2e46515c565..d9cb6b3e61f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java
@@ -64,8 +64,7 @@ public class BluetoothPbapSimVcardManagerTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Spy
-    BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
+    @Spy BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
 
     Context mContext;
     BluetoothPbapSimVcardManager mManager;
@@ -75,7 +74,7 @@ public class BluetoothPbapSimVcardManagerTest {
     @Before
     public void setUp() {
         BluetoothMethodProxy.setInstanceForTesting(mPbapMethodProxy);
-        mContext =  InstrumentationRegistry.getTargetContext();
+        mContext = InstrumentationRegistry.getTargetContext();
         mManager = new BluetoothPbapSimVcardManager(mContext);
     }
 
@@ -86,19 +85,18 @@ public class BluetoothPbapSimVcardManagerTest {
 
     @Test
     public void testInit_whenUriIsUnsupported() {
-        assertThat(mManager.init(WRONG_URI, null, null, null))
-                .isFalse();
+        assertThat(mManager.init(WRONG_URI, null, null, null)).isFalse();
         assertThat(mManager.getErrorReason())
                 .isEqualTo(BluetoothPbapSimVcardManager.FAILURE_REASON_UNSUPPORTED_URI);
     }
 
     @Test
     public void testInit_whenCursorIsNull() {
-        doReturn(null).when(mPbapMethodProxy)
+        doReturn(null)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
-        assertThat(mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null))
-                .isFalse();
+        assertThat(mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null)).isFalse();
         assertThat(mManager.getErrorReason())
                 .isEqualTo(BluetoothPbapSimVcardManager.FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO);
     }
@@ -107,11 +105,11 @@ public class BluetoothPbapSimVcardManagerTest {
     public void testInit_whenCursorHasNoEntry() {
         Cursor cursor = mock(Cursor.class);
         when(cursor.getCount()).thenReturn(0);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
-        assertThat(mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null))
-                .isFalse();
+        assertThat(mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null)).isFalse();
         verify(cursor).close();
         assertThat(mManager.getErrorReason())
                 .isEqualTo(BluetoothPbapSimVcardManager.FAILURE_REASON_NO_ENTRY);
@@ -122,11 +120,11 @@ public class BluetoothPbapSimVcardManagerTest {
         Cursor cursor = mock(Cursor.class);
         when(cursor.getCount()).thenReturn(1);
         when(cursor.moveToFirst()).thenReturn(true);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
-        assertThat(mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null))
-                .isTrue();
+        assertThat(mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null)).isTrue();
         assertThat(mManager.getErrorReason()).isEqualTo(BluetoothPbapSimVcardManager.NO_ERROR);
     }
 
@@ -185,8 +183,8 @@ public class BluetoothPbapSimVcardManagerTest {
     @Test
     public void testMoveToPosition_beforeInit() {
         try {
-            mManager.moveToPosition(0, /*sortByAlphabet=*/ true);
-            mManager.moveToPosition(0, /*sortByAlphabet=*/ false);
+            mManager.moveToPosition(0, /* sortByAlphabet= */ true);
+            mManager.moveToPosition(0, /* sortByAlphabet= */ false);
         } catch (Exception e) {
             assertWithMessage("This should not throw exception").fail();
         }
@@ -200,23 +198,35 @@ public class BluetoothPbapSimVcardManagerTest {
         // Implement Cursor iteration
         final int size = nameList.size();
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToFirst()).then((Answer) i -> {
-            currentPosition.set(0);
-            return true;
-        });
-        when(cursor.isAfterLast()).then((Answer) i -> {
-            return currentPosition.get() >= size;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < size;
-        });
-        when(cursor.getString(anyInt())).then((Answer) i -> {
-            return nameList.get(currentPosition.get());
-        });
+        when(cursor.moveToFirst())
+                .then(
+                        (Answer)
+                                i -> {
+                                    currentPosition.set(0);
+                                    return true;
+                                });
+        when(cursor.isAfterLast())
+                .then(
+                        (Answer)
+                                i -> {
+                                    return currentPosition.get() >= size;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < size;
+                                });
+        when(cursor.getString(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return nameList.get(currentPosition.get());
+                                });
         // Find first one in alphabetical order ("A")
         int position = 0;
-        mManager.moveToPosition(position, /*sortByAlphabet=*/ true);
+        mManager.moveToPosition(position, /* sortByAlphabet= */ true);
 
         assertThat(currentPosition.get()).isEqualTo(2);
     }
@@ -226,7 +236,7 @@ public class BluetoothPbapSimVcardManagerTest {
         Cursor cursor = initManager();
         int position = 3;
 
-        mManager.moveToPosition(position, /*sortByAlphabet=*/ false);
+        mManager.moveToPosition(position, /* sortByAlphabet= */ false);
 
         verify(cursor).moveToPosition(position);
     }
@@ -253,23 +263,35 @@ public class BluetoothPbapSimVcardManagerTest {
             // Implement Cursor iteration
             final int size = nameList.size();
             AtomicInteger currentPosition = new AtomicInteger(0);
-            when(cursor.moveToFirst()).then((Answer) i -> {
-                currentPosition.set(0);
-                return true;
-            });
-            when(cursor.isAfterLast()).then((Answer) i -> {
-                return currentPosition.get() >= size;
-            });
-            when(cursor.moveToNext()).then((Answer) i -> {
-                int pos = currentPosition.addAndGet(1);
-                return pos < size;
-            });
-            when(cursor.getString(anyInt())).then((Answer) i -> {
-                return nameList.get(currentPosition.get());
-            });
-
-            ArrayList result = mManager.getSIMPhonebookNameList(
-                    BluetoothPbapObexServer.ORDER_BY_INDEXED);
+            when(cursor.moveToFirst())
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        currentPosition.set(0);
+                                        return true;
+                                    });
+            when(cursor.isAfterLast())
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        return currentPosition.get() >= size;
+                                    });
+            when(cursor.moveToNext())
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        int pos = currentPosition.addAndGet(1);
+                                        return pos < size;
+                                    });
+            when(cursor.getString(anyInt()))
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        return nameList.get(currentPosition.get());
+                                    });
+
+            ArrayList result =
+                    mManager.getSIMPhonebookNameList(BluetoothPbapObexServer.ORDER_BY_INDEXED);
 
             ArrayList expectedResult = new ArrayList<>();
             expectedResult.add(localPhoneName);
@@ -293,23 +315,35 @@ public class BluetoothPbapSimVcardManagerTest {
             // Implement Cursor iteration
             final int size = nameList.size();
             AtomicInteger currentPosition = new AtomicInteger(0);
-            when(cursor.moveToFirst()).then((Answer) i -> {
-                currentPosition.set(0);
-                return true;
-            });
-            when(cursor.isAfterLast()).then((Answer) i -> {
-                return currentPosition.get() >= size;
-            });
-            when(cursor.moveToNext()).then((Answer) i -> {
-                int pos = currentPosition.addAndGet(1);
-                return pos < size;
-            });
-            when(cursor.getString(anyInt())).then((Answer) i -> {
-                return nameList.get(currentPosition.get());
-            });
-
-            List result = mManager.getSIMPhonebookNameList(
-                    BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL);
+            when(cursor.moveToFirst())
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        currentPosition.set(0);
+                                        return true;
+                                    });
+            when(cursor.isAfterLast())
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        return currentPosition.get() >= size;
+                                    });
+            when(cursor.moveToNext())
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        int pos = currentPosition.addAndGet(1);
+                                        return pos < size;
+                                    });
+            when(cursor.getString(anyInt()))
+                    .then(
+                            (Answer)
+                                    i -> {
+                                        return nameList.get(currentPosition.get());
+                                    });
+
+            List result =
+                    mManager.getSIMPhonebookNameList(BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL);
 
             List expectedResult = new ArrayList<>(nameList);
             Collections.sort(expectedResult, String.CASE_INSENSITIVE_ORDER);
@@ -325,35 +359,45 @@ public class BluetoothPbapSimVcardManagerTest {
     public void testGetSIMContactNamesByNumber() {
         Cursor cursor = initManager();
         List nameList = Arrays.asList("A", "B", "C", "D");
-        List numberList = Arrays.asList(
-                "000123456789",
-                "123456789000",
-                "000111111000",
-                "123456789123");
+        List numberList =
+                Arrays.asList("000123456789", "123456789000", "000111111000", "123456789123");
         final String query = "000";
 
         // Implement Cursor iteration
         final int size = nameList.size();
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToFirst()).then((Answer) i -> {
-            currentPosition.set(0);
-            return true;
-        });
-        when(cursor.isAfterLast()).then((Answer) i -> {
-            return currentPosition.get() >= size;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < size;
-        });
-        when(cursor.getString(BluetoothPbapSimVcardManager.NAME_COLUMN_INDEX)).then(
-                (Answer) i -> {
-                    return nameList.get(currentPosition.get());
-                });
-        when(cursor.getString(BluetoothPbapSimVcardManager.NUMBER_COLUMN_INDEX)).then(
-                (Answer) i -> {
-                    return numberList.get(currentPosition.get());
-                });
+        when(cursor.moveToFirst())
+                .then(
+                        (Answer)
+                                i -> {
+                                    currentPosition.set(0);
+                                    return true;
+                                });
+        when(cursor.isAfterLast())
+                .then(
+                        (Answer)
+                                i -> {
+                                    return currentPosition.get() >= size;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < size;
+                                });
+        when(cursor.getString(BluetoothPbapSimVcardManager.NAME_COLUMN_INDEX))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return nameList.get(currentPosition.get());
+                                });
+        when(cursor.getString(BluetoothPbapSimVcardManager.NUMBER_COLUMN_INDEX))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return numberList.get(currentPosition.get());
+                                });
 
         // Find the names whose number ends with 'query', and then
         // also the names whose number starts with 'query'.
@@ -367,8 +411,14 @@ public class BluetoothPbapSimVcardManagerTest {
         Operation operation = mock(Operation.class);
         final int incorrectStartPoint = 0; // Should be greater than zero
 
-        int result = BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(mContext,
-                operation, incorrectStartPoint, 0, /*vcardType21=*/false, /*ownerVCard=*/null);
+        int result =
+                BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(
+                        mContext,
+                        operation,
+                        incorrectStartPoint,
+                        0,
+                        /* vcardType21= */ false,
+                        /* ownerVCard= */ null);
         assertThat(result).isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
     }
 
@@ -378,8 +428,14 @@ public class BluetoothPbapSimVcardManagerTest {
         final int startPoint = 1;
         final int endPoint = 0; // Should be equal or greater than startPoint
 
-        int result = BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(mContext,
-                operation, startPoint, endPoint, /*vcardType21=*/false, /*ownerVCard=*/null);
+        int result =
+                BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(
+                        mContext,
+                        operation,
+                        startPoint,
+                        endPoint,
+                        /* vcardType21= */ false,
+                        /* ownerVCard= */ null);
         assertThat(result).isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
     }
 
@@ -388,11 +444,18 @@ public class BluetoothPbapSimVcardManagerTest {
         Operation operation = mock(Operation.class);
         final int startPoint = 1;
         final int endPoint = 1;
-        doReturn(null).when(mPbapMethodProxy)
+        doReturn(null)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
-        int result = BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(mContext,
-                operation, startPoint, endPoint, /*vcardType21=*/false, /*ownerVCard=*/null);
+        int result =
+                BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(
+                        mContext,
+                        operation,
+                        startPoint,
+                        endPoint,
+                        /* vcardType21= */ false,
+                        /* ownerVCard= */ null);
         assertThat(result).isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
     }
 
@@ -402,7 +465,8 @@ public class BluetoothPbapSimVcardManagerTest {
         when(cursor.getCount()).thenReturn(10);
         when(cursor.moveToFirst()).thenReturn(true);
         when(cursor.isAfterLast()).thenReturn(false);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
         Operation operation = mock(Operation.class);
         OutputStream outputStream = mock(OutputStream.class);
@@ -411,8 +475,14 @@ public class BluetoothPbapSimVcardManagerTest {
         final int endPoint = 1;
         final String testOwnerVcard = "owner_v_card";
 
-        int result = BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(mContext,
-                operation, startPoint, endPoint, /*vcardType21=*/false, testOwnerVcard);
+        int result =
+                BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookVcards(
+                        mContext,
+                        operation,
+                        startPoint,
+                        endPoint,
+                        /* vcardType21= */ false,
+                        testOwnerVcard);
         assertThat(result).isEqualTo(ResponseCodes.OBEX_HTTP_OK);
     }
 
@@ -421,9 +491,14 @@ public class BluetoothPbapSimVcardManagerTest {
         Operation operation = mock(Operation.class);
         final int offset = 0; // Should be greater than zero
 
-        int result = BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookOneVcard(mContext,
-                operation, offset, /*vcardType21=*/false, /*ownerVCard=*/null,
-                BluetoothPbapObexServer.ORDER_BY_INDEXED);
+        int result =
+                BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookOneVcard(
+                        mContext,
+                        operation,
+                        offset,
+                        /* vcardType21= */ false,
+                        /* ownerVCard= */ null,
+                        BluetoothPbapObexServer.ORDER_BY_INDEXED);
         assertThat(result).isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
     }
 
@@ -433,7 +508,8 @@ public class BluetoothPbapSimVcardManagerTest {
         when(cursor.getCount()).thenReturn(10);
         when(cursor.moveToFirst()).thenReturn(true);
         when(cursor.isAfterLast()).thenReturn(false);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
         Operation operation = mock(Operation.class);
         OutputStream outputStream = mock(OutputStream.class);
@@ -441,9 +517,14 @@ public class BluetoothPbapSimVcardManagerTest {
         final int offset = 1;
         final String testOwnerVcard = "owner_v_card";
 
-        int result = BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookOneVcard(mContext,
-                operation, offset, /*vcardType21=*/false, testOwnerVcard,
-                BluetoothPbapObexServer.ORDER_BY_INDEXED);
+        int result =
+                BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookOneVcard(
+                        mContext,
+                        operation,
+                        offset,
+                        /* vcardType21= */ false,
+                        testOwnerVcard,
+                        BluetoothPbapObexServer.ORDER_BY_INDEXED);
         assertThat(result).isEqualTo(ResponseCodes.OBEX_HTTP_OK);
     }
 
@@ -452,7 +533,8 @@ public class BluetoothPbapSimVcardManagerTest {
         when(cursor.getCount()).thenReturn(10);
         when(cursor.moveToFirst()).thenReturn(true);
         when(cursor.isAfterLast()).thenReturn(false);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
         mManager.init(BluetoothPbapSimVcardManager.SIM_URI, null, null, null);
 
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java
index a98d782fdd5..bfae8a91650 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java
@@ -66,14 +66,11 @@ public class BluetoothPbapUtilsTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Context mContext;
+    @Mock Context mContext;
 
-    @Mock
-    Resources mResources;
+    @Mock Resources mResources;
 
-    @Spy
-    BluetoothMethodProxy mProxy;
+    @Spy BluetoothMethodProxy mProxy;
 
     @Before
     public void setUp() throws Exception {
@@ -131,8 +128,17 @@ public class BluetoothPbapUtilsTest {
 
     @Test
     public void createFilteredVCardComposer_returnsNewVCardComposer() {
-        byte[] filter = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-                (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+        byte[] filter =
+                new byte[] {
+                    (byte) 0xFF,
+                    (byte) 0xFF,
+                    (byte) 0xFF,
+                    (byte) 0xFF,
+                    (byte) 0xFF,
+                    (byte) 0xFF,
+                    (byte) 0xFF,
+                    (byte) 0xFF
+                };
         int vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC;
 
         assertThat(BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType, filter))
@@ -154,29 +160,27 @@ public class BluetoothPbapUtilsTest {
     public void setContactFields() {
         String contactId = "1358923";
 
-        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_NAME, contactId,
-                "test_name");
-        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_PHONE, contactId,
-                "0123456789");
-        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_EMAIL, contactId,
-                "android@android.com");
-        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_ADDRESS, contactId,
-                "SomeAddress");
+        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_NAME, contactId, "test_name");
+        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_PHONE, contactId, "0123456789");
+        BluetoothPbapUtils.setContactFields(
+                BluetoothPbapUtils.TYPE_EMAIL, contactId, "android@android.com");
+        BluetoothPbapUtils.setContactFields(
+                BluetoothPbapUtils.TYPE_ADDRESS, contactId, "SomeAddress");
 
         assertThat(BluetoothPbapUtils.sContactDataset.get(contactId)).isNotNull();
     }
 
     @Test
     public void fetchAndSetContacts_whenCursorIsNull_returnsMinusOne() {
-        doReturn(null).when(mProxy).contentResolverQuery(
-                any(), any(), any(), any(), any(), any());
+        doReturn(null).when(mProxy).contentResolverQuery(any(), any(), any(), any(), any(), any());
         HandlerThread handlerThread = new HandlerThread("BluetoothPbapUtilsTest");
         handlerThread.start();
         Handler handler = new Handler(handlerThread.getLooper());
 
         try {
-            assertThat(BluetoothPbapUtils.fetchAndSetContacts(
-                    mContext, handler, null, null, null, true))
+            assertThat(
+                            BluetoothPbapUtils.fetchAndSetContacts(
+                                    mContext, handler, null, null, null, true))
                     .isEqualTo(-1);
         } finally {
             handlerThread.quit();
@@ -192,16 +196,18 @@ public class BluetoothPbapUtilsTest {
         cursor.addRow(new Object[] {"id2", StructuredName.CONTENT_ITEM_TYPE, "And Roid"});
         cursor.addRow(new Object[] {null, null, null});
 
-        doReturn(cursor).when(mProxy).contentResolverQuery(
-                any(), any(), any(), any(), any(), any());
+        doReturn(cursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), any(), any(), any(), any(), any());
         HandlerThread handlerThread = new HandlerThread("BluetoothPbapUtilsTest");
         handlerThread.start();
         Handler handler = new Handler(handlerThread.getLooper());
 
         try {
             boolean isLoad = true;
-            assertThat(BluetoothPbapUtils.fetchAndSetContacts(
-                    mContext, handler, null, null, null, isLoad))
+            assertThat(
+                            BluetoothPbapUtils.fetchAndSetContacts(
+                                    mContext, handler, null, null, null, isLoad))
                     .isEqualTo(2); // Two IDs exist in sContactSet.
         } finally {
             handlerThread.quit();
@@ -217,16 +223,18 @@ public class BluetoothPbapUtilsTest {
         cursor.addRow(new Object[] {"id2", StructuredName.CONTENT_ITEM_TYPE, "And Roid"});
         cursor.addRow(new Object[] {null, null, null});
 
-        doReturn(cursor).when(mProxy).contentResolverQuery(
-                any(), any(), any(), any(), any(), any());
+        doReturn(cursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), any(), any(), any(), any(), any());
         HandlerThread handlerThread = new HandlerThread("BluetoothPbapUtilsTest");
         handlerThread.start();
         Handler handler = new Handler(handlerThread.getLooper());
 
         try {
             boolean isLoad = false;
-            assertThat(BluetoothPbapUtils.fetchAndSetContacts(
-                    mContext, handler, null, null, null, isLoad))
+            assertThat(
+                            BluetoothPbapUtils.fetchAndSetContacts(
+                                    mContext, handler, null, null, null, isLoad))
                     .isEqualTo(2); // Two IDs exist in sContactSet.
             assertThat(BluetoothPbapUtils.sTotalFields).isEqualTo(1);
             assertThat(BluetoothPbapUtils.sTotalSvcFields).isEqualTo(1);
@@ -237,8 +245,7 @@ public class BluetoothPbapUtilsTest {
 
     @Test
     public void updateSecondaryVersionCounter_whenCursorIsNull_shouldNotCrash() {
-        doReturn(null).when(mProxy).contentResolverQuery(
-                any(), any(), any(), any(), any(), any());
+        doReturn(null).when(mProxy).contentResolverQuery(any(), any(), any(), any(), any(), any());
         HandlerThread handlerThread = new HandlerThread("BluetoothPbapUtilsTest");
         handlerThread.start();
         Handler handler = new Handler(handlerThread.getLooper());
@@ -254,22 +261,25 @@ public class BluetoothPbapUtilsTest {
 
     @Test
     public void updateSecondaryVersionCounter_whenContactsAreAdded() {
-        MatrixCursor contactCursor = new MatrixCursor(
-                new String[] {Contacts._ID, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP});
+        MatrixCursor contactCursor =
+                new MatrixCursor(
+                        new String[] {Contacts._ID, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP});
         contactCursor.addRow(new Object[] {"id1", Calendar.getInstance().getTimeInMillis()});
         contactCursor.addRow(new Object[] {"id2", Calendar.getInstance().getTimeInMillis()});
         contactCursor.addRow(new Object[] {"id3", Calendar.getInstance().getTimeInMillis()});
         contactCursor.addRow(new Object[] {"id4", Calendar.getInstance().getTimeInMillis()});
-        doReturn(contactCursor).when(mProxy).contentResolverQuery(
-                any(), eq(Contacts.CONTENT_URI), any(), any(), any(), any());
+        doReturn(contactCursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), eq(Contacts.CONTENT_URI), any(), any(), any(), any());
 
         MatrixCursor dataCursor = new MatrixCursor(new String[] {CONTACT_ID, MIMETYPE, DATA1});
         dataCursor.addRow(new Object[] {"id1", Phone.CONTENT_ITEM_TYPE, "01234567"});
         dataCursor.addRow(new Object[] {"id1", Email.CONTENT_ITEM_TYPE, "android@android.com"});
         dataCursor.addRow(new Object[] {"id1", StructuredPostal.CONTENT_ITEM_TYPE, "01234"});
         dataCursor.addRow(new Object[] {"id2", StructuredName.CONTENT_ITEM_TYPE, "And Roid"});
-        doReturn(dataCursor).when(mProxy).contentResolverQuery(
-                any(), eq(Data.CONTENT_URI), any(), any(), any(), any());
+        doReturn(dataCursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), eq(Data.CONTENT_URI), any(), any(), any(), any());
 
         HandlerThread handlerThread = new HandlerThread("BluetoothPbapUtilsTest");
         handlerThread.start();
@@ -286,14 +296,17 @@ public class BluetoothPbapUtilsTest {
 
     @Test
     public void updateSecondaryVersionCounter_whenContactsAreDeleted() {
-        MatrixCursor contactCursor = new MatrixCursor(
-                new String[] {Contacts._ID, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP});
-        doReturn(contactCursor).when(mProxy).contentResolverQuery(
-                any(), eq(Contacts.CONTENT_URI), any(), any(), any(), any());
+        MatrixCursor contactCursor =
+                new MatrixCursor(
+                        new String[] {Contacts._ID, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP});
+        doReturn(contactCursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), eq(Contacts.CONTENT_URI), any(), any(), any(), any());
 
         MatrixCursor dataCursor = new MatrixCursor(new String[] {CONTACT_ID, MIMETYPE, DATA1});
-        doReturn(dataCursor).when(mProxy).contentResolverQuery(
-                any(), eq(Data.CONTENT_URI), any(), any(), any(), any());
+        doReturn(dataCursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), eq(Data.CONTENT_URI), any(), any(), any(), any());
 
         HandlerThread handlerThread = new HandlerThread("BluetoothPbapUtilsTest");
         handlerThread.start();
@@ -314,24 +327,27 @@ public class BluetoothPbapUtilsTest {
 
     @Test
     public void updateSecondaryVersionCounter_whenContactsAreUpdated() {
-        MatrixCursor contactCursor = new MatrixCursor(
-                new String[] {Contacts._ID, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP});
+        MatrixCursor contactCursor =
+                new MatrixCursor(
+                        new String[] {Contacts._ID, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP});
         contactCursor.addRow(new Object[] {"id1", Calendar.getInstance().getTimeInMillis()});
-        doReturn(contactCursor).when(mProxy).contentResolverQuery(
-                any(), eq(Contacts.CONTENT_URI), any(), any(), any(), any());
+        doReturn(contactCursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), eq(Contacts.CONTENT_URI), any(), any(), any(), any());
 
         MatrixCursor dataCursor = new MatrixCursor(new String[] {CONTACT_ID, MIMETYPE, DATA1});
         dataCursor.addRow(new Object[] {"id1", Phone.CONTENT_ITEM_TYPE, "01234567"});
         dataCursor.addRow(new Object[] {"id1", Email.CONTENT_ITEM_TYPE, "android@android.com"});
         dataCursor.addRow(new Object[] {"id1", StructuredPostal.CONTENT_ITEM_TYPE, "01234"});
         dataCursor.addRow(new Object[] {"id1", StructuredName.CONTENT_ITEM_TYPE, "And Roid"});
-        doReturn(dataCursor).when(mProxy).contentResolverQuery(
-                any(), eq(Data.CONTENT_URI), any(), any(), any(), any());
+        doReturn(dataCursor)
+                .when(mProxy)
+                .contentResolverQuery(any(), eq(Data.CONTENT_URI), any(), any(), any(), any());
         assertThat(BluetoothPbapUtils.sSecondaryVersionCounter).isEqualTo(0);
 
         BluetoothPbapUtils.sTotalContacts = 1;
-        BluetoothPbapUtils.setContactFields(BluetoothPbapUtils.TYPE_NAME, "id1",
-                "test_previous_name_before_update");
+        BluetoothPbapUtils.setContactFields(
+                BluetoothPbapUtils.TYPE_NAME, "id1", "test_previous_name_before_update");
 
         BluetoothPbapUtils.updateSecondaryVersionCounter(mContext, null);
 
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java
index 9fab5c1d8fb..424ad9ebc5b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java
@@ -49,11 +49,9 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    Context mContext;
+    @Mock Context mContext;
 
-    @Mock
-    Resources mResources;
+    @Mock Resources mResources;
 
     @Before
     public void setUp() throws Exception {
@@ -79,34 +77,44 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
 
     @Test
     public void VCardFilter_apply_whenFilterIsNull_returnsSameVcard() {
-        VCardFilter vCardFilter = new VCardFilter(/*filter=*/null);
+        VCardFilter vCardFilter = new VCardFilter(/* filter= */ null);
 
         String vCard = "FN:Full Name";
-        assertThat(vCardFilter.apply(vCard, /*vCardType21=*/ true)).isEqualTo(vCard);
+        assertThat(vCardFilter.apply(vCard, /* vCardType21= */ true)).isEqualTo(vCard);
     }
 
     @Test
     public void VCardFilter_apply_returnsSameVcard() {
         final String separator = System.getProperty("line.separator");
-        String vCard = "FN:Test Full Name" + separator
-                + "EMAIL:android@android.com:" + separator
-                + "X-IRMC-CALL-DATETIME:20170314T173942" + separator;
+        String vCard =
+                "FN:Test Full Name"
+                        + separator
+                        + "EMAIL:android@android.com:"
+                        + separator
+                        + "X-IRMC-CALL-DATETIME:20170314T173942"
+                        + separator;
 
         byte[] emailExcludeFilter = new byte[] {(byte) 0xFE, (byte) 0xFF};
-        VCardFilter vCardFilter = new VCardFilter(/*filter=*/ emailExcludeFilter);
-        String expectedVCard = "FN:Test Full Name" + separator
-                + "X-IRMC-CALL-DATETIME:20170314T173942" + separator;
-
-        assertThat(vCardFilter.apply(vCard, /*vCardType21=*/ true))
-                .isEqualTo(expectedVCard);
+        VCardFilter vCardFilter = new VCardFilter(/* filter= */ emailExcludeFilter);
+        String expectedVCard =
+                "FN:Test Full Name"
+                        + separator
+                        + "X-IRMC-CALL-DATETIME:20170314T173942"
+                        + separator;
+
+        assertThat(vCardFilter.apply(vCard, /* vCardType21= */ true)).isEqualTo(expectedVCard);
     }
 
     @Test
     public void PropertySelector_checkVCardSelector_atLeastOnePropertyExists_returnsTrue() {
         final String separator = System.getProperty("line.separator");
-        String vCard = "FN:Test Full Name" + separator
-                + "EMAIL:android@android.com:" + separator
-                + "TEL:0123456789" + separator;
+        String vCard =
+                "FN:Test Full Name"
+                        + separator
+                        + "EMAIL:android@android.com:"
+                        + separator
+                        + "TEL:0123456789"
+                        + separator;
 
         byte[] emailSelector = new byte[] {0x01, 0x00};
         PropertySelector selector = new PropertySelector(emailSelector);
@@ -117,9 +125,13 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
     @Test
     public void PropertySelector_checkVCardSelector_atLeastOnePropertyExists_returnsFalse() {
         final String separator = System.getProperty("line.separator");
-        String vCard = "FN:Test Full Name" + separator
-                + "EMAIL:android@android.com:" + separator
-                + "TEL:0123456789" + separator;
+        String vCard =
+                "FN:Test Full Name"
+                        + separator
+                        + "EMAIL:android@android.com:"
+                        + separator
+                        + "TEL:0123456789"
+                        + separator;
 
         byte[] organizationSelector = new byte[] {0x01, 0x00, 0x00};
         PropertySelector selector = new PropertySelector(organizationSelector);
@@ -130,9 +142,13 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
     @Test
     public void PropertySelector_checkVCardSelector_allPropertiesExist_returnsTrue() {
         final String separator = System.getProperty("line.separator");
-        String vCard = "FN:Test Full Name" + separator
-                + "EMAIL:android@android.com:" + separator
-                + "TEL:0123456789" + separator;
+        String vCard =
+                "FN:Test Full Name"
+                        + separator
+                        + "EMAIL:android@android.com:"
+                        + separator
+                        + "TEL:0123456789"
+                        + separator;
 
         byte[] fullNameAndEmailSelector = new byte[] {0x01, 0x02};
         PropertySelector selector = new PropertySelector(fullNameAndEmailSelector);
@@ -143,9 +159,13 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
     @Test
     public void PropertySelector_checkVCardSelector_allPropertiesExist_returnsFalse() {
         final String separator = System.getProperty("line.separator");
-        String vCard = "FN:Test Full Name" + separator
-                + "EMAIL:android@android.com:" + separator
-                + "TEL:0123456789" + separator;
+        String vCard =
+                "FN:Test Full Name"
+                        + separator
+                        + "EMAIL:android@android.com:"
+                        + separator
+                        + "TEL:0123456789"
+                        + separator;
 
         byte[] fullNameAndOrganizationSelector = new byte[] {0x01, 0x00, 0x02};
         PropertySelector selector = new PropertySelector(fullNameAndOrganizationSelector);
@@ -162,13 +182,15 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
 
         long[] contactIds = new long[] {1001, 1001, 1002, 1002, 1003, 1003, 1004};
         AtomicInteger currentPos = new AtomicInteger(-1);
-        when(contactCursor.moveToNext()).thenAnswer(invocation -> {
-            if (currentPos.get() < contactIds.length - 1) {
-                currentPos.incrementAndGet();
-                return true;
-            }
-            return false;
-        });
+        when(contactCursor.moveToNext())
+                .thenAnswer(
+                        invocation -> {
+                            if (currentPos.get() < contactIds.length - 1) {
+                                currentPos.incrementAndGet();
+                                return true;
+                            }
+                            return false;
+                        });
         when(contactCursor.getLong(contactIdColumn))
                 .thenAnswer(invocation -> contactIds[currentPos.get()]);
 
@@ -189,20 +211,22 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
 
         long[] contactIds = new long[] {1001, 1001, 1002, 1002, 1003, 1003, 1004};
         AtomicInteger currentPos = new AtomicInteger(-1);
-        when(contactCursor.moveToNext()).thenAnswer(invocation -> {
-            if (currentPos.get() < contactIds.length - 1) {
-                currentPos.incrementAndGet();
-                return true;
-            }
-            return false;
-        });
+        when(contactCursor.moveToNext())
+                .thenAnswer(
+                        invocation -> {
+                            if (currentPos.get() < contactIds.length - 1) {
+                                currentPos.incrementAndGet();
+                                return true;
+                            }
+                            return false;
+                        });
         when(contactCursor.getLong(contactIdColumn))
                 .thenAnswer(invocation -> contactIds[currentPos.get()]);
 
         int startPoint = 2;
         int endPoint = 4;
-        Cursor resultCursor = ContactCursorFilter.filterByRange(
-                contactCursor, startPoint, endPoint);
+        Cursor resultCursor =
+                ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint);
 
         // Should return cursor containing [1002, 1003, 1004]
         assertThat(resultCursor.getCount()).isEqualTo(3);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java
index 3c623679f5f..a0e5268282b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java
@@ -59,8 +59,7 @@ public class BluetoothPbapVcardManagerTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Spy
-    BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
+    @Spy BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
 
     Context mContext;
     BluetoothPbapVcardManager mManager;
@@ -81,7 +80,7 @@ public class BluetoothPbapVcardManagerTest {
     public void testGetOwnerPhoneNumberVcard_whenUseProfileForOwnerVcard() {
         BluetoothPbapConfig.setIncludePhotosInVcard(true);
 
-        assertThat(mManager.getOwnerPhoneNumberVcard(/*vcardType21=*/true, /*filter=*/null))
+        assertThat(mManager.getOwnerPhoneNumberVcard(/* vcardType21= */ true, /* filter= */ null))
                 .isNotNull();
     }
 
@@ -89,14 +88,15 @@ public class BluetoothPbapVcardManagerTest {
     public void testGetOwnerPhoneNumberVcard_whenNotUseProfileForOwnerVcard() {
         BluetoothPbapConfig.setIncludePhotosInVcard(false);
 
-        assertThat(mManager.getOwnerPhoneNumberVcard(/*vcardType21=*/true, /*filter=*/null))
+        assertThat(mManager.getOwnerPhoneNumberVcard(/* vcardType21= */ true, /* filter= */ null))
                 .isNotNull();
     }
 
     @Test
     public void testGetPhonebookSize_whenTypeIsPhonebook() {
         Cursor cursor = mock(Cursor.class);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
         // 5 distinct contact IDs.
@@ -105,18 +105,28 @@ public class BluetoothPbapVcardManagerTest {
         // Implement Cursor iteration
         final int size = contactIdsWithDuplicates.size();
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToPosition(anyInt())).then((Answer) i -> {
-            int position = i.getArgument(0);
-            currentPosition.set(position);
-            return true;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < size;
-        });
-        when(cursor.getLong(anyInt())).then((Answer) i -> {
-            return (long) contactIdsWithDuplicates.get(currentPosition.get());
-        });
+        when(cursor.moveToPosition(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    int position = i.getArgument(0);
+                                    currentPosition.set(position);
+                                    return true;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < size;
+                                });
+        when(cursor.getLong(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return (long)
+                                            contactIdsWithDuplicates.get(currentPosition.get());
+                                });
 
         // 5 distinct contact IDs + self (which is only included for phonebook)
         final int expectedSize = 5 + 1;
@@ -128,30 +138,49 @@ public class BluetoothPbapVcardManagerTest {
     @Test
     public void testGetPhonebookSize_whenTypeIsFavorites() {
         Cursor cursor = mock(Cursor.class);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
         // 5 distinct contact IDs.
-        final List contactIdsWithDuplicates = Arrays.asList(
-                0, 1, 1, 2,     // starred
-                2, 3, 3, 4, 4   // not starred
-        );
+        final List contactIdsWithDuplicates =
+                Arrays.asList(
+                        0,
+                        1,
+                        1,
+                        2, // starred
+                        2,
+                        3,
+                        3,
+                        4,
+                        4 // not starred
+                        );
 
         // Implement Cursor iteration
         final int starredSize = 4;
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToPosition(anyInt())).then((Answer) i -> {
-            int position = i.getArgument(0);
-            currentPosition.set(position);
-            return true;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < starredSize;
-        });
-        when(cursor.getLong(anyInt())).then((Answer) i -> {
-            return (long) contactIdsWithDuplicates.get(currentPosition.get());
-        });
+        when(cursor.moveToPosition(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    int position = i.getArgument(0);
+                                    currentPosition.set(position);
+                                    return true;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < starredSize;
+                                });
+        when(cursor.getLong(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return (long)
+                                            contactIdsWithDuplicates.get(currentPosition.get());
+                                });
 
         // Among 4 starred contact Ids, there are 3 distinct contact IDs
         final int expectedSize = 3;
@@ -163,14 +192,17 @@ public class BluetoothPbapVcardManagerTest {
     @Test
     public void testGetPhonebookSize_whenTypeIsSimPhonebook() {
         Cursor cursor = mock(Cursor.class);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
         final int expectedSize = 10;
         when(cursor.getCount()).thenReturn(expectedSize);
         BluetoothPbapSimVcardManager simVcardManager = mock(BluetoothPbapSimVcardManager.class);
 
-        assertThat(mManager.getPhonebookSize(BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK,
-                simVcardManager)).isEqualTo(expectedSize);
+        assertThat(
+                        mManager.getPhonebookSize(
+                                BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK, simVcardManager))
+                .isEqualTo(expectedSize);
         verify(simVcardManager).getSIMContactsSize();
     }
 
@@ -179,60 +211,81 @@ public class BluetoothPbapVcardManagerTest {
         final int historySize = 10;
         Cursor cursor = mock(Cursor.class);
         when(cursor.getCount()).thenReturn(historySize);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
-        assertThat(mManager.getPhonebookSize(
-                BluetoothPbapObexServer.ContentType.INCOMING_CALL_HISTORY, null))
+        assertThat(
+                        mManager.getPhonebookSize(
+                                BluetoothPbapObexServer.ContentType.INCOMING_CALL_HISTORY, null))
                 .isEqualTo(historySize);
     }
 
     @Test
     public void testLoadCallHistoryList() {
         Cursor cursor = mock(Cursor.class);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
         List nameList = Arrays.asList("A", "B", "", "");
         List numberList = Arrays.asList("0000", "1111", "2222", "3333");
-        List presentationAllowedList = Arrays.asList(
-                CallLog.Calls.PRESENTATION_ALLOWED,
-                CallLog.Calls.PRESENTATION_ALLOWED,
-                CallLog.Calls.PRESENTATION_ALLOWED,
-                CallLog.Calls.PRESENTATION_UNKNOWN); // The number "3333" should not be shown.
+        List presentationAllowedList =
+                Arrays.asList(
+                        CallLog.Calls.PRESENTATION_ALLOWED,
+                        CallLog.Calls.PRESENTATION_ALLOWED,
+                        CallLog.Calls.PRESENTATION_ALLOWED,
+                        CallLog.Calls
+                                .PRESENTATION_UNKNOWN); // The number "3333" should not be shown.
 
-        List expectedResult = Arrays.asList(
-                "A", "B", "2222", mContext.getString(R.string.unknownNumber));
+        List expectedResult =
+                Arrays.asList("A", "B", "2222", mContext.getString(R.string.unknownNumber));
 
         // Implement Cursor iteration
         final int size = nameList.size();
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToFirst()).then((Answer) i -> {
-            currentPosition.set(0);
-            return true;
-        });
-        when(cursor.isAfterLast()).then((Answer) i -> {
-            return currentPosition.get() >= size;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < size;
-        });
+        when(cursor.moveToFirst())
+                .then(
+                        (Answer)
+                                i -> {
+                                    currentPosition.set(0);
+                                    return true;
+                                });
+        when(cursor.isAfterLast())
+                .then(
+                        (Answer)
+                                i -> {
+                                    return currentPosition.get() >= size;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < size;
+                                });
         when(cursor.getString(BluetoothPbapVcardManager.CALLS_NAME_COLUMN_INDEX))
-                .then((Answer) i -> {
-            return nameList.get(currentPosition.get());
-        });
+                .then(
+                        (Answer)
+                                i -> {
+                                    return nameList.get(currentPosition.get());
+                                });
         when(cursor.getString(BluetoothPbapVcardManager.CALLS_NUMBER_COLUMN_INDEX))
-                .then((Answer) i -> {
-            return numberList.get(currentPosition.get());
-        });
+                .then(
+                        (Answer)
+                                i -> {
+                                    return numberList.get(currentPosition.get());
+                                });
         when(cursor.getInt(BluetoothPbapVcardManager.CALLS_NUMBER_PRESENTATION_COLUMN_INDEX))
-                .then((Answer) i -> {
-            return presentationAllowedList.get(currentPosition.get());
-        });
-
-        assertThat(mManager.loadCallHistoryList(
-                BluetoothPbapObexServer.ContentType.INCOMING_CALL_HISTORY))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return presentationAllowedList.get(currentPosition.get());
+                                });
+
+        assertThat(
+                        mManager.loadCallHistoryList(
+                                BluetoothPbapObexServer.ContentType.INCOMING_CALL_HISTORY))
                 .isEqualTo(expectedResult);
     }
 
@@ -242,43 +295,57 @@ public class BluetoothPbapVcardManagerTest {
         BluetoothPbapService.setLocalPhoneName(localPhoneName);
 
         Cursor cursor = mock(Cursor.class);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
         List nameList = Arrays.asList("A", "B", "C", "");
         List contactIdList = Arrays.asList(0, 1, 2, 3);
 
-        List expectedResult = Arrays.asList(
-                localPhoneName,
-                "A,0",
-                "B,1",
-                "C,2",
-                mContext.getString(android.R.string.unknownName) + ",3");
+        List expectedResult =
+                Arrays.asList(
+                        localPhoneName,
+                        "A,0",
+                        "B,1",
+                        "C,2",
+                        mContext.getString(android.R.string.unknownName) + ",3");
 
         // Implement Cursor iteration
         final int size = nameList.size();
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToPosition(anyInt())).then((Answer) i -> {
-            int position = i.getArgument(0);
-            currentPosition.set(position);
-            return true;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < size;
-        });
+        when(cursor.moveToPosition(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    int position = i.getArgument(0);
+                                    currentPosition.set(position);
+                                    return true;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < size;
+                                });
 
         final int contactIdColumn = 0;
         final int nameColumn = 1;
         when(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID)).thenReturn(contactIdColumn);
         when(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)).thenReturn(nameColumn);
 
-        when(cursor.getLong(contactIdColumn)).then((Answer) i -> {
-            return (long) contactIdList.get(currentPosition.get());
-        });
-        when(cursor.getString(nameColumn)).then((Answer) i -> {
-            return nameList.get(currentPosition.get());
-        });
+        when(cursor.getLong(contactIdColumn))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return (long) contactIdList.get(currentPosition.get());
+                                });
+        when(cursor.getString(nameColumn))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return nameList.get(currentPosition.get());
+                                });
 
         assertThat(mManager.getPhonebookNameList(BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL))
                 .isEqualTo(expectedResult);
@@ -287,45 +354,58 @@ public class BluetoothPbapVcardManagerTest {
     @Test
     public void testGetContactNamesByNumber_whenNumberIsNull() {
         Cursor cursor = mock(Cursor.class);
-        doReturn(cursor).when(mPbapMethodProxy)
+        doReturn(cursor)
+                .when(mPbapMethodProxy)
                 .contentResolverQuery(any(), any(), any(), any(), any(), any());
 
         List nameList = Arrays.asList("A", "B", "C", "");
         List contactIdList = Arrays.asList(0, 1, 2, 3);
 
-        List expectedResult = Arrays.asList(
-                "A,0",
-                "B,1",
-                "C,2",
-                mContext.getString(android.R.string.unknownName) + ",3");
+        List expectedResult =
+                Arrays.asList(
+                        "A,0",
+                        "B,1",
+                        "C,2",
+                        mContext.getString(android.R.string.unknownName) + ",3");
 
         // Implement Cursor iteration
         final int size = nameList.size();
         AtomicInteger currentPosition = new AtomicInteger(0);
-        when(cursor.moveToPosition(anyInt())).then((Answer) i -> {
-            int position = i.getArgument(0);
-            currentPosition.set(position);
-            return true;
-        });
-        when(cursor.moveToNext()).then((Answer) i -> {
-            int pos = currentPosition.addAndGet(1);
-            return pos < size;
-        });
+        when(cursor.moveToPosition(anyInt()))
+                .then(
+                        (Answer)
+                                i -> {
+                                    int position = i.getArgument(0);
+                                    currentPosition.set(position);
+                                    return true;
+                                });
+        when(cursor.moveToNext())
+                .then(
+                        (Answer)
+                                i -> {
+                                    int pos = currentPosition.addAndGet(1);
+                                    return pos < size;
+                                });
 
         final int contactIdColumn = 0;
         final int nameColumn = 1;
         when(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID)).thenReturn(contactIdColumn);
         when(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)).thenReturn(nameColumn);
 
-        when(cursor.getLong(contactIdColumn)).then((Answer) i -> {
-            return (long) contactIdList.get(currentPosition.get());
-        });
-        when(cursor.getString(nameColumn)).then((Answer) i -> {
-            return nameList.get(currentPosition.get());
-        });
-
-        assertThat(mManager.getContactNamesByNumber(null))
-                .isEqualTo(expectedResult);
+        when(cursor.getLong(contactIdColumn))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return (long) contactIdList.get(currentPosition.get());
+                                });
+        when(cursor.getString(nameColumn))
+                .then(
+                        (Answer)
+                                i -> {
+                                    return nameList.get(currentPosition.get());
+                                });
+
+        assertThat(mManager.getContactNamesByNumber(null)).isEqualTo(expectedResult);
     }
 
     @Test
@@ -340,9 +420,13 @@ public class BluetoothPbapVcardManagerTest {
     @Test
     public void getNameFromVCard() {
         final String separator = System.getProperty("line.separator");
-        String vCard = "N:Test Name" + separator
-                + "FN:Test Full Name" + separator
-                + "EMAIL:android@android.com:" + separator;
+        String vCard =
+                "N:Test Name"
+                        + separator
+                        + "FN:Test Full Name"
+                        + separator
+                        + "EMAIL:android@android.com:"
+                        + separator;
 
         assertThat(BluetoothPbapVcardManager.getNameFromVCard(vCard)).isEqualTo("Test Name");
     }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java
index 6c1e252aabf..9c9ee8967f8 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java
@@ -46,11 +46,9 @@ public class HandlerForStringBufferTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private Operation mOperation;
+    @Mock private Operation mOperation;
 
-    @Mock
-    private OutputStream mOutputStream;
+    @Mock private OutputStream mOutputStream;
 
     @Before
     public void setUp() throws Exception {
@@ -110,7 +108,8 @@ public class HandlerForStringBufferTest {
     @Test
     public void writeVCard_withIOExceptionWhenWritingToStream_returnsFalse() throws Exception {
         doThrow(new IOException()).when(mOutputStream).write(any(byte[].class));
-        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, /*ownerVcard=*/null);
+        HandlerForStringBuffer buffer =
+                new HandlerForStringBuffer(mOperation, /* ownerVcard= */ null);
         buffer.init();
 
         String newVCard = "newVCard";
@@ -128,4 +127,4 @@ public class HandlerForStringBufferTest {
 
         verify(mOutputStream).close();
     }
-}
\ No newline at end of file
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java
index 068cb864595..16cc324c37b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java
@@ -98,60 +98,57 @@ public class PbapStateMachineTest {
         TestUtils.clearAdapterService(mAdapterService);
     }
 
-    /**
-     * Test that initial state is WaitingForAuth
-     */
+    /** Test that initial state is WaitingForAuth */
     @Test
     public void testInitialState() {
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
-                mPbapStateMachine.getConnectionState());
-        Assert.assertThat(mPbapStateMachine.getCurrentState(),
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING, mPbapStateMachine.getConnectionState());
+        Assert.assertThat(
+                mPbapStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(PbapStateMachine.WaitingForAuth.class));
     }
 
-    /**
-     * Test state transition from WaitingForAuth to Finished when the user rejected
-     */
+    /** Test state transition from WaitingForAuth to Finished when the user rejected */
     @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.")
     @Test
     public void testStateTransition_WaitingForAuthToFinished() throws Exception {
         mPbapStateMachine.sendMessage(PbapStateMachine.REJECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mPbapStateMachine.getConnectionState());
-        Assert.assertThat(mPbapStateMachine.getCurrentState(),
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mPbapStateMachine.getConnectionState());
+        Assert.assertThat(
+                mPbapStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(PbapStateMachine.Finished.class));
     }
 
-    /**
-     * Test state transition from WaitingForAuth to Finished when the user rejected
-     */
+    /** Test state transition from WaitingForAuth to Finished when the user rejected */
     @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.")
     @Test
     public void testStateTransition_WaitingForAuthToConnected() throws Exception {
         mPbapStateMachine.sendMessage(PbapStateMachine.AUTHORIZED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mPbapStateMachine.getConnectionState());
-        Assert.assertThat(mPbapStateMachine.getCurrentState(),
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTED, mPbapStateMachine.getConnectionState());
+        Assert.assertThat(
+                mPbapStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(PbapStateMachine.Connected.class));
     }
 
-    /**
-     * Test state transition from Connected to Finished when the OBEX server is done
-     */
+    /** Test state transition from Connected to Finished when the OBEX server is done */
     @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.")
     @Test
     public void testStateTransition_ConnectedToFinished() throws Exception {
         mPbapStateMachine.sendMessage(PbapStateMachine.AUTHORIZED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mPbapStateMachine.getConnectionState());
-        Assert.assertThat(mPbapStateMachine.getCurrentState(),
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTED, mPbapStateMachine.getConnectionState());
+        Assert.assertThat(
+                mPbapStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(PbapStateMachine.Connected.class));
 
         // PBAP OBEX transport is done.
         mPbapStateMachine.sendMessage(PbapStateMachine.DISCONNECT);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mPbapStateMachine.getConnectionState());
-        Assert.assertThat(mPbapStateMachine.getCurrentState(),
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mPbapStateMachine.getConnectionState());
+        Assert.assertThat(
+                mPbapStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(PbapStateMachine.Finished.class));
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticationServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticationServiceTest.java
index e07a9c8abb5..54645313bb9 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticationServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticationServiceTest.java
@@ -42,8 +42,7 @@ public class AuthenticationServiceTest {
 
     Context mTargetContext;
 
-    @Rule
-    public final ServiceTestRule mServiceRule = new ServiceTestRule();
+    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
 
     @Before
     public void setUp() {
@@ -65,11 +64,11 @@ public class AuthenticationServiceTest {
     }
 
     private void enableService(boolean enable) {
-        int enabledState = enable ? COMPONENT_ENABLED_STATE_ENABLED
-                : COMPONENT_ENABLED_STATE_DEFAULT;
-        ComponentName serviceName = new ComponentName(
-                mTargetContext, AuthenticationService.class);
-        mTargetContext.getPackageManager().setComponentEnabledSetting(
-                serviceName, enabledState, DONT_KILL_APP);
+        int enabledState =
+                enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT;
+        ComponentName serviceName = new ComponentName(mTargetContext, AuthenticationService.class);
+        mTargetContext
+                .getPackageManager()
+                .setComponentEnabledSetting(serviceName, enabledState, DONT_KILL_APP);
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticatorTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticatorTest.java
index dd332ac85b6..8ebce0a69e5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticatorTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/AuthenticatorTest.java
@@ -42,11 +42,9 @@ public class AuthenticatorTest {
     private Context mTargetContext;
     private Authenticator mAuthenticator;
 
-    @Mock
-    AccountAuthenticatorResponse mResponse;
+    @Mock AccountAuthenticatorResponse mResponse;
 
-    @Mock
-    Account mAccount;
+    @Mock Account mAccount;
 
     @Before
     public void setUp() throws Exception {
@@ -56,13 +54,15 @@ public class AuthenticatorTest {
 
     @Test
     public void editProperties_throwsUnsupportedOperationException() {
-        assertThrows(UnsupportedOperationException.class,
+        assertThrows(
+                UnsupportedOperationException.class,
                 () -> mAuthenticator.editProperties(mResponse, null));
     }
 
     @Test
     public void addAccount_throwsUnsupportedOperationException() {
-        assertThrows(UnsupportedOperationException.class,
+        assertThrows(
+                UnsupportedOperationException.class,
                 () -> mAuthenticator.addAccount(mResponse, null, null, null, null));
     }
 
@@ -73,7 +73,8 @@ public class AuthenticatorTest {
 
     @Test
     public void getAuthToken_throwsUnsupportedOperationException() {
-        assertThrows(UnsupportedOperationException.class,
+        assertThrows(
+                UnsupportedOperationException.class,
                 () -> mAuthenticator.getAuthToken(mResponse, mAccount, null, null));
     }
 
@@ -92,4 +93,4 @@ public class AuthenticatorTest {
         Bundle result = mAuthenticator.hasFeatures(mResponse, mAccount, null);
         assertThat(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)).isFalse();
     }
-}
\ No newline at end of file
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticatorTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticatorTest.java
index 1fefeaf4ab8..64711da3558 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticatorTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticatorTest.java
@@ -41,8 +41,11 @@ public class BluetoothPbapObexAuthenticatorTest {
     @Test
     public void onAuthenticationChallenge() {
         // Note: onAuthenticationChallenge() does not use any arguments
-        PasswordAuthentication passwordAuthentication = mAuthenticator.onAuthenticationChallenge(
-                /*description=*/ null, /*isUserIdRequired=*/ false, /*isFullAccess=*/ false);
+        PasswordAuthentication passwordAuthentication =
+                mAuthenticator.onAuthenticationChallenge(
+                        /* description= */ null,
+                        /* isUserIdRequired= */ false,
+                        /* isFullAccess= */ false);
 
         assertThat(passwordAuthentication.getPassword())
                 .isEqualTo(mAuthenticator.mSessionKey.getBytes());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSizeTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSizeTest.java
index 68be55dbdbf..35209b8b3b9 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSizeTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSizeTest.java
@@ -36,7 +36,9 @@ public class BluetoothPbapRequestPullPhoneBookSizeTest {
 
     @Before
     public void setUp() {
-        mRequest = new BluetoothPbapRequestPullPhoneBookSize(/*pbName=*/"phonebook", /*filter=*/1);
+        mRequest =
+                new BluetoothPbapRequestPullPhoneBookSize(
+                        /* pbName= */ "phonebook", /* filter= */ 1);
     }
 
     @Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookTest.java
index 35d14027836..c2ef8ceac32 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookTest.java
@@ -50,9 +50,16 @@ public class BluetoothPbapRequestPullPhoneBookTest {
 
         final int wrongMaxListCount = -1;
 
-        assertThrows(IllegalArgumentException.class, () ->
-                new BluetoothPbapRequestPullPhoneBook(PB_NAME, ACCOUNT, filter, format,
-                        wrongMaxListCount, listStartOffset));
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        new BluetoothPbapRequestPullPhoneBook(
+                                PB_NAME,
+                                ACCOUNT,
+                                filter,
+                                format,
+                                wrongMaxListCount,
+                                listStartOffset));
     }
 
     @Test
@@ -63,9 +70,16 @@ public class BluetoothPbapRequestPullPhoneBookTest {
 
         final int wrongListStartOffset = -1;
 
-        assertThrows(IllegalArgumentException.class, () ->
-                new BluetoothPbapRequestPullPhoneBook(PB_NAME, ACCOUNT, filter, format,
-                        maxListCount, wrongListStartOffset));
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        new BluetoothPbapRequestPullPhoneBook(
+                                PB_NAME,
+                                ACCOUNT,
+                                filter,
+                                format,
+                                maxListCount,
+                                wrongListStartOffset));
     }
 
     @Test
@@ -74,25 +88,27 @@ public class BluetoothPbapRequestPullPhoneBookTest {
         final byte format = 0; // Will be properly handled as VCARD_TYPE_21.
         final int maxListCount = 0; // Will be specially handled as 65535.
         final int listStartOffset = 10;
-        BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(
-                PB_NAME, ACCOUNT, filter, format, maxListCount, listStartOffset);
-
-        final InputStream is = new InputStream() {
-            @Override
-            public int read() throws IOException {
-                throw new IOException();
-            }
-
-            @Override
-            public int read(byte[] b) throws IOException {
-                throw new IOException();
-            }
-
-            @Override
-            public int read(byte[] b, int off, int len) throws IOException {
-                throw new IOException();
-            }
-        };
+        BluetoothPbapRequestPullPhoneBook request =
+                new BluetoothPbapRequestPullPhoneBook(
+                        PB_NAME, ACCOUNT, filter, format, maxListCount, listStartOffset);
+
+        final InputStream is =
+                new InputStream() {
+                    @Override
+                    public int read() throws IOException {
+                        throw new IOException();
+                    }
+
+                    @Override
+                    public int read(byte[] b) throws IOException {
+                        throw new IOException();
+                    }
+
+                    @Override
+                    public int read(byte[] b, int off, int len) throws IOException {
+                        throw new IOException();
+                    }
+                };
 
         assertThrows(IOException.class, () -> request.readResponse(is));
     }
@@ -103,8 +119,9 @@ public class BluetoothPbapRequestPullPhoneBookTest {
         final byte format = 0; // Will be properly handled as VCARD_TYPE_21.
         final int maxListCount = 0; // Will be specially handled as 65535.
         final int listStartOffset = 10;
-        BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(
-                PB_NAME, ACCOUNT, filter, format, maxListCount, listStartOffset);
+        BluetoothPbapRequestPullPhoneBook request =
+                new BluetoothPbapRequestPullPhoneBook(
+                        PB_NAME, ACCOUNT, filter, format, maxListCount, listStartOffset);
 
         try {
             HeaderSet headerSet = new HeaderSet();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java
index b947c62dc2a..8a5a5d515f5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java
@@ -47,8 +47,7 @@ public class BluetoothPbapRequestTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private ObexTransport mObexTransport;
+    @Mock private ObexTransport mObexTransport;
 
     @Before
     public void setUp() throws Exception {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardListTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardListTest.java
index 3dd2e20abf3..38825604004 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardListTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardListTest.java
@@ -49,60 +49,75 @@ public class BluetoothPbapVcardListTest {
     @Test
     public void constructor_withInputStreamThatThrowsIoeWhenRead_throwsIOException() {
 
-        final InputStream is = new InputStream() {
-            @Override
-            public int read() throws IOException {
-                throw new IOException();
-            }
-
-            @Override
-            public int read(byte[] b) throws IOException {
-                throw new IOException();
-            }
-
-            @Override
-            public int read(byte[] b, int off, int len) throws IOException {
-                throw new IOException();
-            }
-        };
-
-        assertThrows(IOException.class, () ->
-                new BluetoothPbapVcardList(ACCOUNT, is, PbapClientConnectionHandler.VCARD_TYPE_30));
-        assertThrows(IOException.class, () ->
-                new BluetoothPbapVcardList(ACCOUNT, is, PbapClientConnectionHandler.VCARD_TYPE_21));
+        final InputStream is =
+                new InputStream() {
+                    @Override
+                    public int read() throws IOException {
+                        throw new IOException();
+                    }
+
+                    @Override
+                    public int read(byte[] b) throws IOException {
+                        throw new IOException();
+                    }
+
+                    @Override
+                    public int read(byte[] b, int off, int len) throws IOException {
+                        throw new IOException();
+                    }
+                };
+
+        assertThrows(
+                IOException.class,
+                () ->
+                        new BluetoothPbapVcardList(
+                                ACCOUNT, is, PbapClientConnectionHandler.VCARD_TYPE_30));
+        assertThrows(
+                IOException.class,
+                () ->
+                        new BluetoothPbapVcardList(
+                                ACCOUNT, is, PbapClientConnectionHandler.VCARD_TYPE_21));
     }
 
     @Test
     public void constructor_withInvalidVcardType_throwsIllegalArgumentException() {
-        assertThrows(IllegalArgumentException.class, () ->
-                new BluetoothPbapVcardList(ACCOUNT,
-                new ByteArrayInputStream("Hello world".getBytes()), (byte) -1));
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        new BluetoothPbapVcardList(
+                                ACCOUNT,
+                                new ByteArrayInputStream("Hello world".getBytes()),
+                                (byte) -1));
     }
 
     @Test
     public void test30ParserWith21Vcard_parsingSucceeds() throws IOException {
-        InputStream fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.v21_simple);
-        BluetoothPbapVcardList result = new BluetoothPbapVcardList(ACCOUNT, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_30);
+        InputStream fileStream =
+                mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.v21_simple);
+        BluetoothPbapVcardList result =
+                new BluetoothPbapVcardList(
+                        ACCOUNT, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
         assertThat(result.getCount()).isEqualTo(1);
     }
 
     @Test
     public void test21ParserWith30Vcard_parsingSucceeds() throws IOException {
-        InputStream fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.v30_simple);
-        BluetoothPbapVcardList result = new BluetoothPbapVcardList(ACCOUNT, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_21);
+        InputStream fileStream =
+                mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.v30_simple);
+        BluetoothPbapVcardList result =
+                new BluetoothPbapVcardList(
+                        ACCOUNT, fileStream, PbapClientConnectionHandler.VCARD_TYPE_21);
         assertThat(result.getCount()).isEqualTo(1);
     }
 
     @Test
     public void test30ParserWithUnsupportedVcardVersion_parsingFails() throws IOException {
-        InputStream fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.unsupported_version);
-        BluetoothPbapVcardList result = new BluetoothPbapVcardList(ACCOUNT, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_30);
+        InputStream fileStream =
+                mTestResources.openRawResource(
+                        com.android.bluetooth.tests.R.raw.unsupported_version);
+        BluetoothPbapVcardList result =
+                new BluetoothPbapVcardList(
+                        ACCOUNT, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
         assertThat(result.getCount()).isEqualTo(0);
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java
index 6a5440ad740..a7331606e17 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java
@@ -60,8 +60,7 @@ public class CallLogPullRequestTest {
     private Context mTargetContext;
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Spy
-    private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance();
+    @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance();
 
     @Before
     public void setUp() {
@@ -77,8 +76,8 @@ public class CallLogPullRequestTest {
     @Test
     public void testToString() {
         final String path = PbapClientConnectionHandler.ICH_PATH;
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, path, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
 
         assertThat(request.toString()).isNotEmpty();
     }
@@ -86,8 +85,8 @@ public class CallLogPullRequestTest {
     @Test
     public void onPullComplete_whenResultsAreNull() {
         final String path = PbapClientConnectionHandler.ICH_PATH;
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, path, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
         request.setResults(null);
 
         request.onPullComplete();
@@ -99,8 +98,8 @@ public class CallLogPullRequestTest {
     @Test
     public void onPullComplete_whenPathIsInvalid() {
         final String invalidPath = "invalidPath";
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, invalidPath, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, invalidPath, mCallCounter, mAccount);
         List results = new ArrayList<>();
         request.setResults(results);
 
@@ -113,8 +112,8 @@ public class CallLogPullRequestTest {
     @Test
     public void onPullComplete_whenResultsAreEmpty() {
         final String path = PbapClientConnectionHandler.ICH_PATH;
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, path, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
         List results = new ArrayList<>();
         request.setResults(results);
 
@@ -127,8 +126,8 @@ public class CallLogPullRequestTest {
     @Test
     public void onPullComplete_whenThereIsNoPhoneProperty() {
         final String path = PbapClientConnectionHandler.MCH_PATH;
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, path, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
 
         // Add some property which is NOT a phone number
         VCardProperty property = new VCardProperty();
@@ -151,8 +150,8 @@ public class CallLogPullRequestTest {
     @Test
     public void onPullComplete_success() {
         final String path = PbapClientConnectionHandler.OCH_PATH;
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, path, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
         List results = new ArrayList<>();
 
         final String phoneNum = "tel:0123456789";
@@ -180,15 +179,16 @@ public class CallLogPullRequestTest {
     @Test
     public void updateTimesContacted_cursorIsClosed() {
         final String path = PbapClientConnectionHandler.OCH_PATH;
-        final CallLogPullRequest request = new CallLogPullRequest(
-                mTargetContext, path, mCallCounter, mAccount);
+        final CallLogPullRequest request =
+                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
         mCallCounter.put("key", 1);
 
-        MatrixCursor cursor = new MatrixCursor(
-                new String[] {ContactsContract.PhoneLookup.CONTACT_ID});
+        MatrixCursor cursor =
+                new MatrixCursor(new String[] {ContactsContract.PhoneLookup.CONTACT_ID});
         cursor.addRow(new Object[] {"contact_id"});
-        doReturn(cursor).when(mMapMethodProxy).contentResolverQuery(any(), any(), eq(null),
-                eq(null), eq(null));
+        doReturn(cursor)
+                .when(mMapMethodProxy)
+                .contentResolverQuery(any(), any(), eq(null), eq(null), eq(null));
         assertThat(cursor.isClosed()).isFalse();
 
         request.updateTimesContacted();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java
index fd9932d67b2..04626d5591b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java
@@ -65,11 +65,9 @@ public class PbapClientConnectionHandlerTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private AdapterService mAdapterService;
+    @Mock private AdapterService mAdapterService;
 
-    @Mock
-    private DatabaseManager mDatabaseManager;
+    @Mock private DatabaseManager mDatabaseManager;
 
     private BluetoothAdapter mAdapter;
 
@@ -81,8 +79,10 @@ public class PbapClientConnectionHandlerTest {
 
     @Before
     public void setUp() throws Exception {
-        mTargetContext = spy(new ContextWrapper(
-                InstrumentationRegistry.getInstrumentation().getTargetContext()));
+        mTargetContext =
+                spy(
+                        new ContextWrapper(
+                                InstrumentationRegistry.getInstrumentation().getTargetContext()));
 
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -102,12 +102,13 @@ public class PbapClientConnectionHandlerTest {
 
         when(mStateMachine.getContext()).thenReturn(mTargetContext);
 
-        mHandler = new PbapClientConnectionHandler.Builder()
-                .setLooper(mLooper)
-                .setClientSM(mStateMachine)
-                .setContext(mTargetContext)
-                .setRemoteDevice(mRemoteDevice)
-                .build();
+        mHandler =
+                new PbapClientConnectionHandler.Builder()
+                        .setLooper(mLooper)
+                        .setClientSM(mStateMachine)
+                        .setContext(mTargetContext)
+                        .setRemoteDevice(mRemoteDevice)
+                        .build();
     }
 
     @After
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java
index e495bd119f8..fec23ebad97 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java
@@ -128,15 +128,19 @@ public class PbapClientServiceTest {
 
     @Test
     public void testSetConnectionPolicy_withNullDevice_throwsIAE() {
-        assertThrows(IllegalArgumentException.class, () -> mService.setConnectionPolicy(
-                null, BluetoothProfile.CONNECTION_POLICY_ALLOWED));
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        mService.setConnectionPolicy(
+                                null, BluetoothProfile.CONNECTION_POLICY_ALLOWED));
     }
 
     @Test
     public void testSetConnectionPolicy() {
         int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
         when(mDatabaseManager.setProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PBAP_CLIENT, connectionPolicy)).thenReturn(true);
+                        mRemoteDevice, BluetoothProfile.PBAP_CLIENT, connectionPolicy))
+                .thenReturn(true);
 
         assertThat(mService.setConnectionPolicy(mRemoteDevice, connectionPolicy)).isTrue();
     }
@@ -150,7 +154,8 @@ public class PbapClientServiceTest {
     public void testGetConnectionPolicy() {
         int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED;
         when(mDatabaseManager.getProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PBAP_CLIENT)).thenReturn(connectionPolicy);
+                        mRemoteDevice, BluetoothProfile.PBAP_CLIENT))
+                .thenReturn(connectionPolicy);
 
         assertThat(mService.getConnectionPolicy(mRemoteDevice)).isEqualTo(connectionPolicy);
     }
@@ -164,7 +169,8 @@ public class PbapClientServiceTest {
     public void testConnect_whenPolicyIsForbidden_returnsFalse() {
         int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         when(mDatabaseManager.getProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PBAP_CLIENT)).thenReturn(connectionPolicy);
+                        mRemoteDevice, BluetoothProfile.PBAP_CLIENT))
+                .thenReturn(connectionPolicy);
 
         assertThat(mService.connect(mRemoteDevice)).isFalse();
     }
@@ -173,7 +179,8 @@ public class PbapClientServiceTest {
     public void testConnect_whenPolicyIsAllowed_returnsTrue() {
         int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED;
         when(mDatabaseManager.getProfileConnectionPolicy(
-                mRemoteDevice, BluetoothProfile.PBAP_CLIENT)).thenReturn(connectionPolicy);
+                        mRemoteDevice, BluetoothProfile.PBAP_CLIENT))
+                .thenReturn(connectionPolicy);
 
         assertThat(mService.connect(mRemoteDevice)).isTrue();
     }
@@ -361,8 +368,12 @@ public class PbapClientServiceTest {
                 BluetoothProfile.STATE_DISCONNECTED);
 
         ArgumentCaptor selectionArgsCaptor = ArgumentCaptor.forClass(Object.class);
-        verify(methodProxy).contentResolverDelete(any(), eq(CallLog.Calls.CONTENT_URI), any(),
-                (String[]) selectionArgsCaptor.capture());
+        verify(methodProxy)
+                .contentResolverDelete(
+                        any(),
+                        eq(CallLog.Calls.CONTENT_URI),
+                        any(),
+                        (String[]) selectionArgsCaptor.capture());
 
         assertThat(((String[]) selectionArgsCaptor.getValue())[0])
                 .isEqualTo(mRemoteDevice.getAddress());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java
index d40aa8d5d10..beb817402ad 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java
@@ -49,26 +49,22 @@ import org.mockito.junit.MockitoRule;
 
 @MediumTest
 @RunWith(AndroidJUnit4.class)
-public class PbapClientStateMachineTest{
+public class PbapClientStateMachineTest {
     private static final String TAG = "PbapClientStateMachineTest";
 
     private PbapClientStateMachine mPbapClientStateMachine = null;
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private PbapClientService mMockPbapClientService;
-    @Mock
-    private UserManager mMockUserManager;
-    @Mock
-    private PbapClientConnectionHandler mMockHandler;
+    @Mock private PbapClientService mMockPbapClientService;
+    @Mock private UserManager mMockUserManager;
+    @Mock private PbapClientConnectionHandler mMockHandler;
 
     private BluetoothDevice mTestDevice;
     private BluetoothAdapter mAdapter;
 
     private ArgumentCaptor mIntentArgument = ArgumentCaptor.forClass(Intent.class);
 
-
     static final int DISCONNECT_TIMEOUT = 5000;
 
     @Before
@@ -82,8 +78,8 @@ public class PbapClientStateMachineTest{
                 .thenReturn(Context.USER_SERVICE);
         when(mMockPbapClientService.getSystemService(UserManager.class))
                 .thenReturn(mMockUserManager);
-        mPbapClientStateMachine = new PbapClientStateMachine(mMockPbapClientService, mTestDevice,
-                mMockHandler);
+        mPbapClientStateMachine =
+                new PbapClientStateMachine(mMockPbapClientService, mTestDevice, mMockHandler);
         mPbapClientStateMachine.start();
     }
 
@@ -94,23 +90,21 @@ public class PbapClientStateMachineTest{
         }
     }
 
-    /**
-     * Test that default state is STATE_CONNECTING
-     */
+    /** Test that default state is STATE_CONNECTING */
     @Test
     public void testDefaultConnectingState() {
         Log.i(TAG, "in testDefaultConnectingState");
         // it appears that enter and exit can overlap sometimes when calling doQuit()
         // currently solved by waiting for looper to finish task
-        TestUtils.waitForLooperToFinishScheduledTask(mPbapClientStateMachine.getHandler()
-                .getLooper());
+        TestUtils.waitForLooperToFinishScheduledTask(
+                mPbapClientStateMachine.getHandler().getLooper());
         assertThat(mPbapClientStateMachine.getConnectionState())
                 .isEqualTo(BluetoothProfile.STATE_CONNECTING);
     }
 
     /**
-     * Test transition from STATE_CONNECTING to STATE_DISCONNECTING
-     * and then to STATE_DISCONNECTED after timeout.
+     * Test transition from STATE_CONNECTING to STATE_DISCONNECTING and then to STATE_DISCONNECTED
+     * after timeout.
      */
     @Test
     public void testStateTransitionFromConnectingToDisconnected() {
@@ -119,15 +113,17 @@ public class PbapClientStateMachineTest{
 
         mPbapClientStateMachine.disconnect(mTestDevice);
 
-        TestUtils.waitForLooperToFinishScheduledTask(mPbapClientStateMachine.getHandler()
-                .getLooper());
+        TestUtils.waitForLooperToFinishScheduledTask(
+                mPbapClientStateMachine.getHandler().getLooper());
         assertThat(mPbapClientStateMachine.getConnectionState())
                 .isEqualTo(BluetoothProfile.STATE_DISCONNECTING);
 
-        //wait until timeout occurs
+        // wait until timeout occurs
         Mockito.clearInvocations(mMockPbapClientService);
         verify(mMockPbapClientService, timeout(DISCONNECT_TIMEOUT))
-                .sendBroadcastMultiplePermissions(mIntentArgument.capture(), any(String[].class),
+                .sendBroadcastMultiplePermissions(
+                        mIntentArgument.capture(),
+                        any(String[].class),
                         any(BroadcastOptions.class));
         assertThat(mPbapClientStateMachine.getConnectionState())
                 .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapParserTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapParserTest.java
index d86f8bede96..09a40840569 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapParserTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapParserTest.java
@@ -51,8 +51,10 @@ public class PbapParserTest {
     @Before
     public void setUp() {
         mTargetContext = InstrumentationRegistry.getTargetContext();
-        mAccount = new Account(TEST_ACCOUNT_NAME,
-                mTargetContext.getString(com.android.bluetooth.R.string.pbap_account_type));
+        mAccount =
+                new Account(
+                        TEST_ACCOUNT_NAME,
+                        mTargetContext.getString(com.android.bluetooth.R.string.pbap_account_type));
         mTestResources = TestUtils.getTestApplicationResources(mTargetContext);
         cleanupCallLog();
         cleanupPhonebook();
@@ -62,14 +64,19 @@ public class PbapParserTest {
     @Test
     public void testNoTimestamp() throws IOException {
         InputStream fileStream;
-        fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.no_timestamp_call_log);
-        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_30);
+        fileStream =
+                mTestResources.openRawResource(
+                        com.android.bluetooth.tests.R.raw.no_timestamp_call_log);
+        BluetoothPbapVcardList pbapVCardList =
+                new BluetoothPbapVcardList(
+                        mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
         Assert.assertEquals(1, pbapVCardList.getCount());
         CallLogPullRequest processor =
-                new CallLogPullRequest(mTargetContext, PbapClientConnectionHandler.MCH_PATH,
-                    new HashMap<>(), mAccount);
+                new CallLogPullRequest(
+                        mTargetContext,
+                        PbapClientConnectionHandler.MCH_PATH,
+                        new HashMap<>(),
+                        mAccount);
         processor.setResults(pbapVCardList.getList());
 
         // Verify that these entries aren't in the call log to start.
@@ -84,14 +91,19 @@ public class PbapParserTest {
     @Test
     public void testMissedCall() throws IOException {
         InputStream fileStream;
-        fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.single_missed_call);
-        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_30);
+        fileStream =
+                mTestResources.openRawResource(
+                        com.android.bluetooth.tests.R.raw.single_missed_call);
+        BluetoothPbapVcardList pbapVCardList =
+                new BluetoothPbapVcardList(
+                        mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
         Assert.assertEquals(1, pbapVCardList.getCount());
         CallLogPullRequest processor =
-                new CallLogPullRequest(mTargetContext, PbapClientConnectionHandler.MCH_PATH,
-                    new HashMap<>(), mAccount);
+                new CallLogPullRequest(
+                        mTargetContext,
+                        PbapClientConnectionHandler.MCH_PATH,
+                        new HashMap<>(),
+                        mAccount);
         processor.setResults(pbapVCardList.getList());
 
         // Verify that these entries aren't in the call log to start.
@@ -105,14 +117,19 @@ public class PbapParserTest {
     @Test
     public void testUnknownCall() throws IOException {
         InputStream fileStream;
-        fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.unknown_number_call);
-        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_30);
+        fileStream =
+                mTestResources.openRawResource(
+                        com.android.bluetooth.tests.R.raw.unknown_number_call);
+        BluetoothPbapVcardList pbapVCardList =
+                new BluetoothPbapVcardList(
+                        mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
         Assert.assertEquals(2, pbapVCardList.getCount());
         CallLogPullRequest processor =
-                new CallLogPullRequest(mTargetContext, PbapClientConnectionHandler.MCH_PATH,
-                    new HashMap<>(), mAccount);
+                new CallLogPullRequest(
+                        mTargetContext,
+                        PbapClientConnectionHandler.MCH_PATH,
+                        new HashMap<>(),
+                        mAccount);
         processor.setResults(pbapVCardList.getList());
 
         // Verify that these entries aren't in the call log to start.
@@ -128,10 +145,10 @@ public class PbapParserTest {
     @Test
     public void testPullPhoneBook() throws IOException {
         InputStream fileStream;
-        fileStream = mTestResources.openRawResource(
-                com.android.bluetooth.tests.R.raw.v30_simple);
-        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
-                PbapClientConnectionHandler.VCARD_TYPE_30);
+        fileStream = mTestResources.openRawResource(com.android.bluetooth.tests.R.raw.v30_simple);
+        BluetoothPbapVcardList pbapVCardList =
+                new BluetoothPbapVcardList(
+                        mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
         Assert.assertEquals(1, pbapVCardList.getCount());
         PhonebookPullRequest processor = new PhonebookPullRequest(mTargetContext);
         processor.setResults(pbapVCardList.getList());
@@ -145,17 +162,24 @@ public class PbapParserTest {
     }
 
     private void cleanupPhonebook() {
-        mTargetContext.getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI,
-                null, null);
+        mTargetContext
+                .getContentResolver()
+                .delete(ContactsContract.RawContacts.CONTENT_URI, null, null);
     }
 
     // Find Entries in call log with type matching number and date.
     // If number or date is null it will match any number or date respectively.
     private boolean verifyCallLog(String number, String date, String type) {
-        String[] query = new String[]{Calls.NUMBER, Calls.DATE, Calls.TYPE};
-        Cursor cursor = mTargetContext.getContentResolver()
-                .query(Calls.CONTENT_URI, query, Calls.TYPE + "= " + type, null,
-                        Calls.DATE + ", " + Calls.NUMBER);
+        String[] query = new String[] {Calls.NUMBER, Calls.DATE, Calls.TYPE};
+        Cursor cursor =
+                mTargetContext
+                        .getContentResolver()
+                        .query(
+                                Calls.CONTENT_URI,
+                                query,
+                                Calls.TYPE + "= " + type,
+                                null,
+                                Calls.DATE + ", " + Calls.NUMBER);
         if (date != null) {
             date = adjDate(date);
         }
@@ -163,8 +187,8 @@ public class PbapParserTest {
             while (cursor.moveToNext()) {
                 String foundNumber = cursor.getString(cursor.getColumnIndex(Calls.NUMBER));
                 String foundDate = cursor.getString(cursor.getColumnIndex(Calls.DATE));
-                if ((number == null || number.equals(foundNumber)) && (date == null || date.equals(
-                        foundDate))) {
+                if ((number == null || number.equals(foundNumber))
+                        && (date == null || date.equals(foundDate))) {
                     return true;
                 }
             }
@@ -181,18 +205,18 @@ public class PbapParserTest {
     }
 
     private boolean verifyPhonebook(String name, String number) {
-        Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
-                Uri.encode(number));
+        Uri uri =
+                Uri.withAppendedPath(
+                        ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
         Cursor c = mTargetContext.getContentResolver().query(uri, null, null, null);
         if (c != null && c.getCount() > 0) {
             c.moveToNext();
-            String displayName = c.getString(
-                    c.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
+            String displayName =
+                    c.getString(c.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
             if (displayName.equals(name)) {
                 return true;
             }
         }
         return false;
     }
-
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java
index 3b0b7114597..e7ef894ffa4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java
@@ -76,10 +76,10 @@ public class SapMessageTest {
         int cardReaderStatus = STATUS_CARD_INSERTED;
         int statusChange = 1;
         int transportProtocol = TRANS_PROTO_T0;
-        byte[] apdu = new byte[]{0x01, 0x02};
-        byte[] apdu7816 = new byte[]{0x03, 0x04};
-        byte[] apduResp = new byte[]{0x05, 0x06};
-        byte[] atr = new byte[]{0x07, 0x08};
+        byte[] apdu = new byte[] {0x01, 0x02};
+        byte[] apdu7816 = new byte[] {0x03, 0x04};
+        byte[] apduResp = new byte[] {0x05, 0x06};
+        byte[] atr = new byte[] {0x07, 0x08};
         boolean sendToRil = true;
         boolean clearRilQueue = true;
         int testMode = TEST_MODE_ENABLE;
@@ -130,7 +130,7 @@ public class SapMessageTest {
 
     @Test
     public void getNumPendingRilMessages() {
-        SapMessage.sOngoingRequests.put(/*rilSerial=*/10000, ID_CONNECT_REQ);
+        SapMessage.sOngoingRequests.put(/* rilSerial= */ 10000, ID_CONNECT_REQ);
         assertThat(SapMessage.getNumPendingRilMessages()).isEqualTo(1);
 
         SapMessage.resetPendingRilMessages();
@@ -147,10 +147,10 @@ public class SapMessageTest {
         int cardReaderStatus = STATUS_CARD_INSERTED;
         int statusChange = 1;
         int transportProtocol = TRANS_PROTO_T0;
-        byte[] apdu = new byte[]{0x01, 0x02};
-        byte[] apdu7816 = new byte[]{0x03, 0x04};
-        byte[] apduResp = new byte[]{0x05, 0x06};
-        byte[] atr = new byte[]{0x07, 0x08};
+        byte[] apdu = new byte[] {0x01, 0x02};
+        byte[] apdu7816 = new byte[] {0x03, 0x04};
+        byte[] apduResp = new byte[] {0x05, 0x06};
+        byte[] atr = new byte[] {0x07, 0x08};
 
         mMessage.setMsgType(msgType);
         mMessage.setMaxMsgSize(maxMsgSize);
@@ -195,8 +195,8 @@ public class SapMessageTest {
     @Test
     public void send() throws Exception {
         int maxMsgSize = 512;
-        byte[] apdu = new byte[]{0x01, 0x02};
-        byte[] apdu7816 = new byte[]{0x03, 0x04};
+        byte[] apdu = new byte[] {0x01, 0x02};
+        byte[] apdu7816 = new byte[] {0x03, 0x04};
 
         ISapRilReceiver sapProxy = mock(ISapRilReceiver.class);
         mMessage.setClearRilQueue(true);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java
index 42fc15d7a06..094b9d67ec4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java
@@ -81,16 +81,13 @@ public class SapRilReceiverHidlTest {
     private HandlerThread mHandlerThread;
     private Handler mServerMsgHandler;
 
-    @Spy
-    private TestHandlerCallback mCallback = new TestHandlerCallback();
+    @Spy private TestHandlerCallback mCallback = new TestHandlerCallback();
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private Handler mServiceHandler;
+    @Mock private Handler mServiceHandler;
 
-    @Mock
-    private ISap mSapProxy;
+    @Mock private ISap mSapProxy;
 
     private SapRilReceiverHidl mReceiver;
 
@@ -144,9 +141,9 @@ public class SapRilReceiverHidlTest {
         mReceiver.mSapProxyDeathRecipient.serviceDied(cookie);
 
         verify(mCallback, timeout(ISAP_GET_SERVICE_DELAY_MILLIS + TIMEOUT_MS))
-                .receiveMessage(eq(SAP_PROXY_DEAD), argThat(
-                        arg -> (arg instanceof Long) && ((Long) arg == cookie)
-                ));
+                .receiveMessage(
+                        eq(SAP_PROXY_DEAD),
+                        argThat(arg -> (arg instanceof Long) && ((Long) arg == cookie)));
     }
 
     @Test
@@ -156,19 +153,21 @@ public class SapRilReceiverHidlTest {
         int maxMsgSize = 512;
         mReceiver.mSapCallback.connectResponse(token, sapConnectRsp, maxMsgSize);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_CONNECT_RESP
-                                && sapMsg.getConnectionStatus() == sapConnectRsp;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_CONNECT_RESP
+                                                && sapMsg.getConnectionStatus() == sapConnectRsp;
+                                    }
+                                }));
     }
 
     @Test
@@ -176,18 +175,20 @@ public class SapRilReceiverHidlTest {
         int token = 1;
         mReceiver.mSapCallback.disconnectResponse(token);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_DISCONNECT_RESP;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_DISCONNECT_RESP;
+                                    }
+                                }));
     }
 
     @Test
@@ -196,26 +197,28 @@ public class SapRilReceiverHidlTest {
         int disconnectType = DISC_GRACEFULL;
         mReceiver.mSapCallback.disconnectIndication(token, disconnectType);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_RIL_UNSOL_DISCONNECT_IND
-                                && sapMsg.getDisconnectionType() == disconnectType;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RIL_IND),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_RIL_UNSOL_DISCONNECT_IND
+                                                && sapMsg.getDisconnectionType() == disconnectType;
+                                    }
+                                }));
     }
 
     @Test
     public void callback_apduResponse() throws Exception {
         int token = 1;
         int resultCode = RESULT_OK;
-        byte[] apduRsp = new byte[]{0x03, 0x04};
+        byte[] apduRsp = new byte[] {0x03, 0x04};
         ArrayList apduRspList = new ArrayList<>();
         for (byte b : apduRsp) {
             apduRspList.add(b);
@@ -223,27 +226,29 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.apduResponse(token, resultCode, apduRspList);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_TRANSFER_APDU_RESP
-                                && sapMsg.getResultCode() == resultCode
-                                && Arrays.equals(sapMsg.getApduResp(), apduRsp);
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_TRANSFER_APDU_RESP
+                                                && sapMsg.getResultCode() == resultCode
+                                                && Arrays.equals(sapMsg.getApduResp(), apduRsp);
+                                    }
+                                }));
     }
 
     @Test
     public void callback_transferAtrResponse() throws Exception {
         int token = 1;
         int resultCode = RESULT_OK;
-        byte[] atr = new byte[]{0x03, 0x04};
+        byte[] atr = new byte[] {0x03, 0x04};
         ArrayList atrList = new ArrayList<>();
         for (byte b : atr) {
             atrList.add(b);
@@ -251,20 +256,22 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.transferAtrResponse(token, resultCode, atrList);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_TRANSFER_ATR_RESP
-                                && sapMsg.getResultCode() == resultCode
-                                && Arrays.equals(sapMsg.getAtr(), atr);
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_TRANSFER_ATR_RESP
+                                                && sapMsg.getResultCode() == resultCode
+                                                && Arrays.equals(sapMsg.getAtr(), atr);
+                                    }
+                                }));
     }
 
     @Test
@@ -277,19 +284,21 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.powerResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_POWER_SIM_OFF_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_POWER_SIM_OFF_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -302,19 +311,21 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.powerResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_POWER_SIM_ON_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_POWER_SIM_ON_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -324,19 +335,21 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.resetSimResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_RESET_SIM_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_RESET_SIM_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -346,19 +359,21 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.statusIndication(token, statusChange);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_STATUS_IND
-                                && sapMsg.getStatusChange() == statusChange;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_STATUS_IND
+                                                && sapMsg.getStatusChange() == statusChange;
+                                    }
+                                }));
     }
 
     @Test
@@ -370,19 +385,22 @@ public class SapRilReceiverHidlTest {
         mReceiver.mSapCallback.transferCardReaderStatusResponse(
                 token, resultCode, cardReaderStatus);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_TRANSFER_CARD_READER_STATUS_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType()
+                                                        == ID_TRANSFER_CARD_READER_STATUS_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -391,18 +409,20 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.errorResponse(token);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_RIL_UNKNOWN;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RIL_IND),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_RIL_UNKNOWN;
+                                    }
+                                }));
     }
 
     @Test
@@ -412,19 +432,21 @@ public class SapRilReceiverHidlTest {
 
         mReceiver.mSapCallback.transferProtocolResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_SET_TRANSPORT_PROTOCOL_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_SET_TRANSPORT_PROTOCOL_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     public static class TestHandlerCallback implements Handler.Callback {
@@ -435,7 +457,6 @@ public class SapRilReceiverHidlTest {
             return true;
         }
 
-        public void receiveMessage(int what, Object obj) {
-        }
+        public void receiveMessage(int what, Object obj) {}
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java
index 293b892a7d1..50199e4fd37 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java
@@ -83,16 +83,13 @@ public class SapRilReceiverTest {
     private HandlerThread mHandlerThread;
     private Handler mServerMsgHandler;
 
-    @Spy
-    private TestHandlerCallback mCallback = new TestHandlerCallback();
+    @Spy private TestHandlerCallback mCallback = new TestHandlerCallback();
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private Handler mServiceHandler;
+    @Mock private Handler mServiceHandler;
 
-    @Mock
-    private ISap mSapProxy;
+    @Mock private ISap mSapProxy;
 
     private SapRilReceiver mReceiver;
 
@@ -149,9 +146,9 @@ public class SapRilReceiverTest {
         mReceiver.mSapProxyDeathRecipient.binderDied();
 
         verify(mCallback, timeout(ISAP_GET_SERVICE_DELAY_MILLIS + TIMEOUT_MS))
-                .receiveMessage(eq(SAP_PROXY_DEAD), argThat(
-                        arg -> (arg instanceof Long) && ((Long) arg == 0)
-                ));
+                .receiveMessage(
+                        eq(SAP_PROXY_DEAD),
+                        argThat(arg -> (arg instanceof Long) && ((Long) arg == 0)));
     }
 
     @Test
@@ -161,19 +158,21 @@ public class SapRilReceiverTest {
         int maxMsgSize = 512;
         mReceiver.mSapCallback.connectResponse(token, sapConnectRsp, maxMsgSize);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_CONNECT_RESP
-                                && sapMsg.getConnectionStatus() == sapConnectRsp;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_CONNECT_RESP
+                                                && sapMsg.getConnectionStatus() == sapConnectRsp;
+                                    }
+                                }));
     }
 
     @Test
@@ -181,18 +180,20 @@ public class SapRilReceiverTest {
         int token = 1;
         mReceiver.mSapCallback.disconnectResponse(token);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_DISCONNECT_RESP;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_DISCONNECT_RESP;
+                                    }
+                                }));
     }
 
     @Test
@@ -201,67 +202,73 @@ public class SapRilReceiverTest {
         int disconnectType = DISC_GRACEFULL;
         mReceiver.mSapCallback.disconnectIndication(token, disconnectType);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_RIL_UNSOL_DISCONNECT_IND
-                                && sapMsg.getDisconnectionType() == disconnectType;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RIL_IND),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_RIL_UNSOL_DISCONNECT_IND
+                                                && sapMsg.getDisconnectionType() == disconnectType;
+                                    }
+                                }));
     }
 
     @Test
     public void callback_apduResponse() throws Exception {
         int token = 1;
         int resultCode = RESULT_OK;
-        byte[] apduRsp = new byte[]{0x03, 0x04};
+        byte[] apduRsp = new byte[] {0x03, 0x04};
 
         mReceiver.mSapCallback.apduResponse(token, resultCode, apduRsp);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_TRANSFER_APDU_RESP
-                                && sapMsg.getResultCode() == resultCode
-                                && Arrays.equals(sapMsg.getApduResp(), apduRsp);
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_TRANSFER_APDU_RESP
+                                                && sapMsg.getResultCode() == resultCode
+                                                && Arrays.equals(sapMsg.getApduResp(), apduRsp);
+                                    }
+                                }));
     }
 
     @Test
     public void callback_transferAtrResponse() throws Exception {
         int token = 1;
         int resultCode = RESULT_OK;
-        byte[] atr = new byte[]{0x03, 0x04};
+        byte[] atr = new byte[] {0x03, 0x04};
 
         mReceiver.mSapCallback.transferAtrResponse(token, resultCode, atr);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_TRANSFER_ATR_RESP
-                                && sapMsg.getResultCode() == resultCode
-                                && Arrays.equals(sapMsg.getAtr(), atr);
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_TRANSFER_ATR_RESP
+                                                && sapMsg.getResultCode() == resultCode
+                                                && Arrays.equals(sapMsg.getAtr(), atr);
+                                    }
+                                }));
     }
 
     @Test
@@ -274,19 +281,21 @@ public class SapRilReceiverTest {
 
         mReceiver.mSapCallback.powerResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_POWER_SIM_OFF_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_POWER_SIM_OFF_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -299,19 +308,21 @@ public class SapRilReceiverTest {
 
         mReceiver.mSapCallback.powerResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_POWER_SIM_ON_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_POWER_SIM_ON_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -321,19 +332,21 @@ public class SapRilReceiverTest {
 
         mReceiver.mSapCallback.resetSimResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_RESET_SIM_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_RESET_SIM_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -343,19 +356,21 @@ public class SapRilReceiverTest {
 
         mReceiver.mSapCallback.statusIndication(token, statusChange);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_STATUS_IND
-                                && sapMsg.getStatusChange() == statusChange;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_STATUS_IND
+                                                && sapMsg.getStatusChange() == statusChange;
+                                    }
+                                }));
     }
 
     @Test
@@ -367,19 +382,22 @@ public class SapRilReceiverTest {
         mReceiver.mSapCallback.transferCardReaderStatusResponse(
                 token, resultCode, cardReaderStatus);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_TRANSFER_CARD_READER_STATUS_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType()
+                                                        == ID_TRANSFER_CARD_READER_STATUS_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     @Test
@@ -388,18 +406,20 @@ public class SapRilReceiverTest {
 
         mReceiver.mSapCallback.errorResponse(token);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_RIL_UNKNOWN;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RIL_IND),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_RIL_UNKNOWN;
+                                    }
+                                }));
     }
 
     @Test
@@ -409,19 +429,21 @@ public class SapRilReceiverTest {
 
         mReceiver.mSapCallback.transferProtocolResponse(token, resultCode);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        if (!(arg instanceof SapMessage)) {
-                            return false;
-                        }
-                        SapMessage sapMsg = (SapMessage) arg;
-                        return sapMsg.getMsgType() == ID_SET_TRANSPORT_PROTOCOL_RESP
-                                && sapMsg.getResultCode() == resultCode;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        if (!(arg instanceof SapMessage)) {
+                                            return false;
+                                        }
+                                        SapMessage sapMsg = (SapMessage) arg;
+                                        return sapMsg.getMsgType() == ID_SET_TRANSPORT_PROTOCOL_RESP
+                                                && sapMsg.getResultCode() == resultCode;
+                                    }
+                                }));
     }
 
     public static class TestHandlerCallback implements Handler.Callback {
@@ -432,7 +454,6 @@ public class SapRilReceiverTest {
             return true;
         }
 
-        public void receiveMessage(int what, Object obj) {
-        }
+        public void receiveMessage(int what, Object obj) {}
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java
index 0de1343d3a9..819ff6cfcd8 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java
@@ -97,16 +97,13 @@ public class SapServerTest {
     private Context mTargetContext =
             new ContextWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
 
-    @Spy
-    private TestHandlerCallback mCallback = new TestHandlerCallback();
+    @Spy private TestHandlerCallback mCallback = new TestHandlerCallback();
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private InputStream mInputStream;
+    @Mock private InputStream mInputStream;
 
-    @Mock
-    private OutputStream mOutputStream;
+    @Mock private OutputStream mOutputStream;
 
     private SapServer mSapServer;
 
@@ -182,9 +179,13 @@ public class SapServerTest {
         mSapServer.changeState(SapServer.SAP_STATE.CONNECTED);
         mSapServer.onConnectRequest(mock(SapMessage.class));
 
-        verify(mSapServer).sendClientMessage(argThat(
-                sapMsg -> sapMsg.getMsgType() == ID_CONNECT_RESP
-                        && sapMsg.getConnectionStatus() == CON_STATUS_ERROR_CONNECTION));
+        verify(mSapServer)
+                .sendClientMessage(
+                        argThat(
+                                sapMsg ->
+                                        sapMsg.getMsgType() == ID_CONNECT_RESP
+                                                && sapMsg.getConnectionStatus()
+                                                        == CON_STATUS_ERROR_CONNECTION));
     }
 
     @Test
@@ -194,9 +195,13 @@ public class SapServerTest {
         mSapServer.changeState(SapServer.SAP_STATE.CONNECTING_CALL_ONGOING);
         mSapServer.onConnectRequest(mock(SapMessage.class));
 
-        verify(mSapServer, atLeastOnce()).sendClientMessage(argThat(
-                sapMsg -> sapMsg.getMsgType() == ID_CONNECT_RESP
-                        && sapMsg.getConnectionStatus() == CON_STATUS_ERROR_CONNECTION));
+        verify(mSapServer, atLeastOnce())
+                .sendClientMessage(
+                        argThat(
+                                sapMsg ->
+                                        sapMsg.getMsgType() == ID_CONNECT_RESP
+                                                && sapMsg.getConnectionStatus()
+                                                        == CON_STATUS_ERROR_CONNECTION));
     }
 
     @Test
@@ -243,8 +248,8 @@ public class SapServerTest {
         SapMessage msg = mock(SapMessage.class);
         mSapServer.sendRilMessage(msg);
 
-        verify(mSapServer).sendClientMessage(
-                argThat(sapMsg -> sapMsg.getMsgType() == ID_ERROR_RESP));
+        verify(mSapServer)
+                .sendClientMessage(argThat(sapMsg -> sapMsg.getMsgType() == ID_ERROR_RESP));
     }
 
     @Test
@@ -259,8 +264,8 @@ public class SapServerTest {
         doThrow(new IllegalArgumentException()).when(msg).send(any());
         mSapServer.sendRilMessage(msg);
 
-        verify(mSapServer).sendClientMessage(
-                argThat(sapMsg -> sapMsg.getMsgType() == ID_ERROR_RESP));
+        verify(mSapServer)
+                .sendClientMessage(argThat(sapMsg -> sapMsg.getMsgType() == ID_ERROR_RESP));
     }
 
     @Test
@@ -277,8 +282,8 @@ public class SapServerTest {
         doThrow(new RemoteException()).when(msg).send(any());
         mSapServer.sendRilMessage(msg);
 
-        verify(mSapServer).sendClientMessage(
-                argThat(sapMsg -> sapMsg.getMsgType() == ID_ERROR_RESP));
+        verify(mSapServer)
+                .sendClientMessage(argThat(sapMsg -> sapMsg.getMsgType() == ID_ERROR_RESP));
         verify(mockReceiver).notifyShutdown();
         verify(mockReceiver).resetSapProxy();
     }
@@ -303,9 +308,13 @@ public class SapServerTest {
         mSapServer.changeState(SapServer.SAP_STATE.CONNECTED);
         mSapServer.handleRilInd(msg);
 
-        verify(mSapServer).sendClientMessage(argThat(
-                sapMsg -> sapMsg.getMsgType() == ID_DISCONNECT_IND
-                        && sapMsg.getDisconnectionType() == disconnectionType));
+        verify(mSapServer)
+                .sendClientMessage(
+                        argThat(
+                                sapMsg ->
+                                        sapMsg.getMsgType() == ID_DISCONNECT_IND
+                                                && sapMsg.getDisconnectionType()
+                                                        == disconnectionType));
     }
 
     @Test
@@ -479,14 +488,16 @@ public class SapServerTest {
         SapMessage msg = new SapMessage(ID_STATUS_IND);
         mSapServer.sendRilThreadMessage(msg);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_REQ), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        return msg == arg;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RIL_REQ),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        return msg == arg;
+                                    }
+                                }));
     }
 
     @Test
@@ -496,14 +507,16 @@ public class SapServerTest {
         SapMessage msg = new SapMessage(ID_STATUS_IND);
         mSapServer.sendClientMessage(msg);
 
-        verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat(
-                new ArgumentMatcher() {
-                    @Override
-                    public boolean matches(Object arg) {
-                        return msg == arg;
-                    }
-                }
-        ));
+        verify(mCallback, timeout(TIMEOUT_MS))
+                .receiveMessage(
+                        eq(SAP_MSG_RFC_REPLY),
+                        argThat(
+                                new ArgumentMatcher() {
+                                    @Override
+                                    public boolean matches(Object arg) {
+                                        return msg == arg;
+                                    }
+                                }));
     }
 
     // TODO: Find a good way to run() method.
@@ -553,8 +566,8 @@ public class SapServerTest {
         try {
             mSapServer.handleMessage(message);
 
-            verify(mSapServer).sendRilMessage(
-                    argThat(sapMsg -> sapMsg.getMsgType() == ID_CONNECT_REQ));
+            verify(mSapServer)
+                    .sendRilMessage(argThat(sapMsg -> sapMsg.getMsgType() == ID_CONNECT_REQ));
         } finally {
             message.recycle();
         }
@@ -652,8 +665,8 @@ public class SapServerTest {
         assertThat(mSapServer.mState).isEqualTo(SapServer.SAP_STATE.CONNECTING_CALL_ONGOING);
         mSapServer.mIntentReceiver.onReceive(mTargetContext, intent);
 
-        verify(mSapServer).onConnectRequest(
-                argThat(sapMsg -> sapMsg.getMsgType() == ID_CONNECT_REQ));
+        verify(mSapServer)
+                .onConnectRequest(argThat(sapMsg -> sapMsg.getMsgType() == ID_CONNECT_REQ));
     }
 
     @Test
@@ -701,8 +714,6 @@ public class SapServerTest {
             return true;
         }
 
-        public void receiveMessage(int what, Object obj) {
-        }
+        public void receiveMessage(int what, Object obj) {}
     }
 }
-
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java
index 6e3071ea4ee..48ca06618f6 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java
@@ -85,9 +85,7 @@ public class SapServiceTest {
         assertThat(mService.getConnectedDevices()).isEmpty();
     }
 
-    /**
-     * Test stop SAP Service
-     */
+    /** Test stop SAP Service */
     @Test
     public void testStopSapService() throws Exception {
         // SAP Service is already running: test stop(). Note: must be done on the main thread
@@ -108,14 +106,12 @@ public class SapServiceTest {
         assertThat(mService.getConnectionPolicy(mDevice))
                 .isEqualTo(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
 
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         assertThat(mService.getConnectionPolicy(mDevice))
                 .isEqualTo(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
 
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
 
         assertThat(mService.getConnectionPolicy(mDevice))
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java b/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java
index 95812204101..f7cd7f86d58 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java
@@ -91,19 +91,26 @@ public class DipTest {
         SdpManagerNativeInterface.setInstance(null);
     }
 
-    private void verifyDipSdpRecordIntent(ArgumentCaptor intentArgument,
-            int status, BluetoothDevice device,
-            byte[] uuid,  int specificationId,
-            int vendorId, int vendorIdSource,
-            int productId, int version,
+    private void verifyDipSdpRecordIntent(
+            ArgumentCaptor intentArgument,
+            int status,
+            BluetoothDevice device,
+            byte[] uuid,
+            int specificationId,
+            int vendorId,
+            int vendorIdSource,
+            int productId,
+            int version,
             boolean primaryRecord) {
         Intent intent = intentArgument.getValue();
 
         assertThat(intent).isNotEqualTo(null);
         assertThat(intent.getAction()).isEqualTo(BluetoothDevice.ACTION_SDP_RECORD);
         assertThat(device).isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
-        assertThat(Utils.byteArrayToUuid(uuid)[0]).isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID));
-        assertThat(status).isEqualTo(intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS, -1));
+        assertThat(Utils.byteArrayToUuid(uuid)[0])
+                .isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID));
+        assertThat(status)
+                .isEqualTo(intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS, -1));
 
         SdpDipRecord record = intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD);
         assertThat(record).isNotEqualTo(null);
@@ -115,9 +122,7 @@ public class DipTest {
         assertThat(primaryRecord).isEqualTo(record.getPrimaryRecord());
     }
 
-    /**
-     * Test that an outgoing connection/disconnection succeeds
-     */
+    /** Test that an outgoing connection/disconnection succeeds */
     @Test
     @SmallTest
     public void testDipCallbackSuccess() {
@@ -132,12 +137,32 @@ public class DipTest {
         boolean moreResults = false;
 
         mSdpManager.sdpSearch(mTestDevice, BluetoothUuid.DIP);
-        mSdpManager.sdpDipRecordFoundCallback(AbstractionLayer.BT_STATUS_SUCCESS,
-                Utils.getByteAddress(mTestDevice), uuid, specificationId,
-                vendorId, vendorIdSource, productId, version, primaryRecord, moreResults);
-        verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(),
-                mBundleArgument.capture());
-        verifyDipSdpRecordIntent(mIntentArgument, AbstractionLayer.BT_STATUS_SUCCESS, mTestDevice,
-                uuid, specificationId, vendorId, vendorIdSource, productId, version, primaryRecord);
+        mSdpManager.sdpDipRecordFoundCallback(
+                AbstractionLayer.BT_STATUS_SUCCESS,
+                Utils.getByteAddress(mTestDevice),
+                uuid,
+                specificationId,
+                vendorId,
+                vendorIdSource,
+                productId,
+                version,
+                primaryRecord,
+                moreResults);
+        verify(mAdapterService)
+                .sendBroadcast(
+                        mIntentArgument.capture(),
+                        mStringArgument.capture(),
+                        mBundleArgument.capture());
+        verifyDipSdpRecordIntent(
+                mIntentArgument,
+                AbstractionLayer.BT_STATUS_SUCCESS,
+                mTestDevice,
+                uuid,
+                specificationId,
+                vendorId,
+                vendorIdSource,
+                productId,
+                version,
+                primaryRecord);
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java
index d619b6136ff..564fc2f4b94 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java
@@ -75,20 +75,14 @@ public class TbsGattTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private AdapterService mAdapterService;
-    @Mock
-    private BluetoothGattServerProxy mMockGattServer;
-    @Mock
-    private TbsGatt.Callback mMockTbsGattCallback;
-    @Mock
-    private TbsService mMockTbsService;
+    @Mock private AdapterService mAdapterService;
+    @Mock private BluetoothGattServerProxy mMockGattServer;
+    @Mock private TbsGatt.Callback mMockTbsGattCallback;
+    @Mock private TbsService mMockTbsService;
 
-    @Rule
-    public final ServiceTestRule mServiceRule = new ServiceTestRule();
+    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
 
-    @Captor
-    private ArgumentCaptor mGattServiceCaptor;
+    @Captor private ArgumentCaptor mGattServiceCaptor;
 
     @Before
     public void setUp() throws Exception {
@@ -98,13 +92,13 @@ public class TbsGattTest {
 
         getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
 
-
         TestUtils.setAdapterService(mAdapterService);
         mAdapter = BluetoothAdapter.getDefaultAdapter();
 
         doReturn(true).when(mMockGattServer).addService(any(BluetoothGattService.class));
         doReturn(true).when(mMockGattServer).open(any(BluetoothGattServerCallback.class));
-        doReturn(BluetoothDevice.ACCESS_ALLOWED).when(mMockTbsService)
+        doReturn(BluetoothDevice.ACCESS_ALLOWED)
+                .when(mMockTbsService)
                 .getDeviceAuthorization(any(BluetoothDevice.class));
 
         mTbsGatt = new TbsGatt(mMockTbsService);
@@ -113,8 +107,8 @@ public class TbsGattTest {
         mFirstDevice = TestUtils.getTestDevice(mAdapter, 0);
         mSecondDevice = TestUtils.getTestDevice(mAdapter, 1);
 
-        when(mMockTbsService.getDeviceAuthorization(any(BluetoothDevice.class))).thenReturn(
-                BluetoothDevice.ACCESS_ALLOWED);
+        when(mMockTbsService.getDeviceAuthorization(any(BluetoothDevice.class)))
+                .thenReturn(BluetoothDevice.ACCESS_ALLOWED);
     }
 
     @After
@@ -132,8 +126,16 @@ public class TbsGattTest {
         mCurrentProviderName = "unknown";
         mCurrentTechnology = 0x00;
 
-        Assert.assertTrue(mTbsGatt.init(mCurrentCcid, mCurrentUci, mCurrentUriSchemes, true, true,
-                mCurrentProviderName, mCurrentTechnology, mMockTbsGattCallback));
+        Assert.assertTrue(
+                mTbsGatt.init(
+                        mCurrentCcid,
+                        mCurrentUci,
+                        mCurrentUriSchemes,
+                        true,
+                        true,
+                        mCurrentProviderName,
+                        mCurrentTechnology,
+                        mMockTbsGattCallback));
         Assert.assertNotNull(mMockGattServer);
 
         verify(mMockGattServer).addService(mGattServiceCaptor.capture());
@@ -149,22 +151,33 @@ public class TbsGattTest {
         return characteristic;
     }
 
-    private void configureNotifications(BluetoothDevice device,
-            BluetoothGattCharacteristic characteristic, boolean enable) {
+    private void configureNotifications(
+            BluetoothDevice device, BluetoothGattCharacteristic characteristic, boolean enable) {
         BluetoothGattDescriptor descriptor =
                 characteristic.getDescriptor(TbsGatt.UUID_CLIENT_CHARACTERISTIC_CONFIGURATION);
         Assert.assertNotNull(descriptor);
 
-        mTbsGatt.mGattServerCallback.onDescriptorWriteRequest(device, 1, descriptor, false, true, 0,
-                enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
+        mTbsGatt.mGattServerCallback.onDescriptorWriteRequest(
+                device,
+                1,
+                descriptor,
+                false,
+                true,
+                0,
+                enable
+                        ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
                         : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
-        verify(mMockGattServer).sendResponse(eq(device), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0), any());
+        verify(mMockGattServer)
+                .sendResponse(eq(device), eq(1), eq(BluetoothGatt.GATT_SUCCESS), eq(0), any());
         reset(mMockGattServer);
     }
 
-    private void verifySetValue(BluetoothGattCharacteristic characteristic, Object value,
-            boolean shouldNotify, BluetoothDevice device, boolean clearGattMock) {
+    private void verifySetValue(
+            BluetoothGattCharacteristic characteristic,
+            Object value,
+            boolean shouldNotify,
+            BluetoothDevice device,
+            boolean clearGattMock) {
         boolean notifyWithValue = false;
 
         if (characteristic.getUuid().equals(TbsGatt.UUID_BEARER_PROVIDER_NAME)) {
@@ -178,10 +191,12 @@ public class TbsGattTest {
 
         } else if (characteristic.getUuid().equals(TbsGatt.UUID_BEARER_TECHNOLOGY)) {
             Assert.assertTrue(mTbsGatt.setBearerTechnology((Integer) value));
-            Assert.assertEquals((Integer) value,
+            Assert.assertEquals(
+                    (Integer) value,
                     characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0));
 
-        } else if (characteristic.getUuid()
+        } else if (characteristic
+                .getUuid()
                 .equals(TbsGatt.UUID_BEARER_URI_SCHEMES_SUPPORTED_LIST)) {
             String valueString = String.join(",", (List) value);
             boolean valueChanged = !characteristic.getStringValue(0).equals(valueString);
@@ -236,8 +251,10 @@ public class TbsGattTest {
                     mTbsGatt.setTerminationReason(indexReasonPair.first, indexReasonPair.second));
             Assert.assertTrue(
                     Arrays.equals(
-                            new byte[] {(byte) indexReasonPair.first.byteValue(),
-                                    indexReasonPair.second.byteValue()},
+                            new byte[] {
+                                (byte) indexReasonPair.first.byteValue(),
+                                indexReasonPair.second.byteValue()
+                            },
                             characteristic.getValue()));
 
         } else if (characteristic.getUuid().equals(TbsGatt.UUID_INCOMING_CALL)) {
@@ -248,10 +265,12 @@ public class TbsGattTest {
                 Pair indexStrPair = (Pair) value;
                 Assert.assertTrue(
                         mTbsGatt.setIncomingCall(indexStrPair.first, indexStrPair.second));
-                Assert.assertTrue(Arrays.equals(
-                        Bytes.concat(new byte[] {(byte) indexStrPair.first.byteValue()},
-                                indexStrPair.second.getBytes(StandardCharsets.UTF_8)),
-                        characteristic.getValue()));
+                Assert.assertTrue(
+                        Arrays.equals(
+                                Bytes.concat(
+                                        new byte[] {(byte) indexStrPair.first.byteValue()},
+                                        indexStrPair.second.getBytes(StandardCharsets.UTF_8)),
+                                characteristic.getValue()));
             }
 
         } else if (characteristic.getUuid().equals(TbsGatt.UUID_CALL_FRIENDLY_NAME)) {
@@ -262,29 +281,33 @@ public class TbsGattTest {
                 Pair indexNamePair = (Pair) value;
                 Assert.assertTrue(
                         mTbsGatt.setCallFriendlyName(indexNamePair.first, indexNamePair.second));
-                Assert.assertTrue(Arrays.equals(
-                        Bytes.concat(new byte[] {(byte) indexNamePair.first.byteValue()},
-                                indexNamePair.second.getBytes(StandardCharsets.UTF_8)),
-                        characteristic.getValue()));
+                Assert.assertTrue(
+                        Arrays.equals(
+                                Bytes.concat(
+                                        new byte[] {(byte) indexNamePair.first.byteValue()},
+                                        indexNamePair.second.getBytes(StandardCharsets.UTF_8)),
+                                characteristic.getValue()));
             }
         }
 
         if (shouldNotify) {
-                if (notifyWithValue) {
-                        verify(mMockGattServer).notifyCharacteristicChanged(eq(device),
-                                eq(characteristic), eq(false), any());
-                } else {
-                        verify(mMockGattServer).notifyCharacteristicChanged(eq(device),
-                                eq(characteristic), eq(false));
-                }
+            if (notifyWithValue) {
+                verify(mMockGattServer)
+                        .notifyCharacteristicChanged(
+                                eq(device), eq(characteristic), eq(false), any());
+            } else {
+                verify(mMockGattServer)
+                        .notifyCharacteristicChanged(eq(device), eq(characteristic), eq(false));
+            }
         } else {
-                if (notifyWithValue) {
-                        verify(mMockGattServer, times(0)).notifyCharacteristicChanged(eq(device),
-                                eq(characteristic), anyBoolean(), any());
-                } else {
-                        verify(mMockGattServer, times(0)).notifyCharacteristicChanged(eq(device),
-                                eq(characteristic), anyBoolean());
-                }
+            if (notifyWithValue) {
+                verify(mMockGattServer, times(0))
+                        .notifyCharacteristicChanged(
+                                eq(device), eq(characteristic), anyBoolean(), any());
+            } else {
+                verify(mMockGattServer, times(0))
+                        .notifyCharacteristicChanged(eq(device), eq(characteristic), anyBoolean());
+            }
         }
 
         if (clearGattMock) {
@@ -330,13 +353,21 @@ public class TbsGattTest {
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
-        verifySetValue(characteristic, new ArrayList<>(Arrays.asList("uri2", "uri3")), true,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new ArrayList<>(Arrays.asList("uri2", "uri3")),
+                true,
+                mFirstDevice,
+                true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        verifySetValue(characteristic, new ArrayList<>(Arrays.asList("uri4", "uri5")), false,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new ArrayList<>(Arrays.asList("uri4", "uri5")),
+                false,
+                mFirstDevice,
+                true);
     }
 
     @Test
@@ -348,50 +379,104 @@ public class TbsGattTest {
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
         Map callsMap = new TreeMap<>();
-        callsMap.put(0x0A, TbsCall.create(
-                new BluetoothLeCall(UUID.randomUUID(), "tel:123456789", "John Doe", 0x03, 0x00)));
-        byte[] packetExpected = new byte[] {
-                // First call
-                (byte) 0x10, // Length of this entry (incl. URI length, excl. this length field
-                             // byte)
-                0x0A, // Call index
-                0x03, // Active call state
-                0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
-                      // Bit2:0-provided-by-netw.,1-withheld-by-netw.
-                0x74, 0x65, 0x6c, 0x3a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-                // URI: tel:123456789
-        };
-        verifySetValue(characteristic,
-                new Pair, byte[]>(callsMap, packetExpected), true,
-                mFirstDevice, true);
+        callsMap.put(
+                0x0A,
+                TbsCall.create(
+                        new BluetoothLeCall(
+                                UUID.randomUUID(), "tel:123456789", "John Doe", 0x03, 0x00)));
+        byte[] packetExpected =
+                new byte[] {
+                    // First call
+                    (byte) 0x10, // Length of this entry (incl. URI length, excl. this length field
+                    // byte)
+                    0x0A, // Call index
+                    0x03, // Active call state
+                    0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
+                    // Bit2:0-provided-by-netw.,1-withheld-by-netw.
+                    0x74,
+                    0x65,
+                    0x6c,
+                    0x3a,
+                    0x31,
+                    0x32,
+                    0x33,
+                    0x34,
+                    0x35,
+                    0x36,
+                    0x37,
+                    0x38,
+                    0x39,
+                    // URI: tel:123456789
+                };
+        verifySetValue(
+                characteristic,
+                new Pair, byte[]>(callsMap, packetExpected),
+                true,
+                mFirstDevice,
+                true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        callsMap.put(0x0B, TbsCall.create(new BluetoothLeCall(UUID.randomUUID(), "tel:987654321",
-                "Kate", 0x01, BluetoothLeCall.FLAG_OUTGOING_CALL)));
-        packetExpected = new byte[] {
-                // First call
-                (byte) 0x10, // Length of this entry (incl. URI length, excl. this length field
-                             // byte)
-                0x0A, // Call index
-                0x03, // Active call state
-                0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
-                      // Bit2:0-provided-by-netw.,1-withheld-by-netw.
-                0x74, 0x65, 0x6c, 0x3a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-                // URI: tel:123456789
-                // Second call
-                (byte) 0x10, // Length of this entry (incl. URI length, excl. this length field
-                             // byte)
-                0x0B, // Call index
-                0x01, // Dialing call state
-                0x01, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
-                      // Bit2:0-provided-by-netw.,1-withheld-by-netw.
-                0x74, 0x65, 0x6c, 0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
-                // URI: tel:987654321
-        };
-        verifySetValue(characteristic,
-                new Pair, byte[]>(callsMap, packetExpected), false,
-                mFirstDevice, true);
+        callsMap.put(
+                0x0B,
+                TbsCall.create(
+                        new BluetoothLeCall(
+                                UUID.randomUUID(),
+                                "tel:987654321",
+                                "Kate",
+                                0x01,
+                                BluetoothLeCall.FLAG_OUTGOING_CALL)));
+        packetExpected =
+                new byte[] {
+                    // First call
+                    (byte) 0x10, // Length of this entry (incl. URI length, excl. this length field
+                    // byte)
+                    0x0A, // Call index
+                    0x03, // Active call state
+                    0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
+                    // Bit2:0-provided-by-netw.,1-withheld-by-netw.
+                    0x74,
+                    0x65,
+                    0x6c,
+                    0x3a,
+                    0x31,
+                    0x32,
+                    0x33,
+                    0x34,
+                    0x35,
+                    0x36,
+                    0x37,
+                    0x38,
+                    0x39,
+                    // URI: tel:123456789
+                    // Second call
+                    (byte) 0x10, // Length of this entry (incl. URI length, excl. this length field
+                    // byte)
+                    0x0B, // Call index
+                    0x01, // Dialing call state
+                    0x01, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
+                    // Bit2:0-provided-by-netw.,1-withheld-by-netw.
+                    0x74,
+                    0x65,
+                    0x6c,
+                    0x3a,
+                    0x39,
+                    0x38,
+                    0x37,
+                    0x36,
+                    0x35,
+                    0x34,
+                    0x33,
+                    0x32,
+                    0x31,
+                    // URI: tel:987654321
+                };
+        verifySetValue(
+                characteristic,
+                new Pair, byte[]>(callsMap, packetExpected),
+                false,
+                mFirstDevice,
+                true);
     }
 
     @Test
@@ -401,18 +486,27 @@ public class TbsGattTest {
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
-        verifySetValue(characteristic,
+        verifySetValue(
+                characteristic,
                 new Pair(TbsGatt.STATUS_FLAG_INBAND_RINGTONE_ENABLED, true),
-                true, mFirstDevice, true);
-        verifySetValue(characteristic,
-                new Pair(TbsGatt.STATUS_FLAG_SILENT_MODE_ENABLED, true), true,
-                mFirstDevice, true);
+                true,
+                mFirstDevice,
+                true);
+        verifySetValue(
+                characteristic,
+                new Pair(TbsGatt.STATUS_FLAG_SILENT_MODE_ENABLED, true),
+                true,
+                mFirstDevice,
+                true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        verifySetValue(characteristic,
-                new Pair(TbsGatt.STATUS_FLAG_SILENT_MODE_ENABLED, false), false,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(TbsGatt.STATUS_FLAG_SILENT_MODE_ENABLED, false),
+                false,
+                mFirstDevice,
+                true);
     }
 
     @Test
@@ -422,34 +516,50 @@ public class TbsGattTest {
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
-        byte[] packetExpected = new byte[] {(byte) 0x0A, // Call index
-                0x03, // Active call state
-                0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
-                      // Bit2:0-provided-by-netw.,1-withheld-by-netw.
-        };
+        byte[] packetExpected =
+                new byte[] {
+                    (byte) 0x0A, // Call index
+                    0x03, // Active call state
+                    0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
+                    // Bit2:0-provided-by-netw.,1-withheld-by-netw.
+                };
         Map callsMap = new TreeMap<>();
-        callsMap.put(0x0A, TbsCall.create(
-                new BluetoothLeCall(UUID.randomUUID(), "tel:123456789", "John Doe", 0x03, 0x00)));
-        verifySetValue(characteristic,
-                new Pair, byte[]>(callsMap, packetExpected), true,
-                mFirstDevice, true);
+        callsMap.put(
+                0x0A,
+                TbsCall.create(
+                        new BluetoothLeCall(
+                                UUID.randomUUID(), "tel:123456789", "John Doe", 0x03, 0x00)));
+        verifySetValue(
+                characteristic,
+                new Pair, byte[]>(callsMap, packetExpected),
+                true,
+                mFirstDevice,
+                true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        packetExpected = new byte[] {(byte) 0x0A, // Call index
-                0x03, // Active call state
-                0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
-                      // Bit2:0-provided-by-netw.,1-withheld-by-netw.
-                (byte) 0x0B, // Call index
-                0x04, // Locally Held call state
-                0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
-                      // Bit2:0-provided-by-netw.,1-withheld-by-netw.
-        };
-        callsMap.put(0x0B, TbsCall.create(
-                new BluetoothLeCall(UUID.randomUUID(), "tel:987654321", "Kate", 0x04, 0x00)));
-        verifySetValue(characteristic,
-                new Pair, byte[]>(callsMap, packetExpected), false,
-                mFirstDevice, true);
+        packetExpected =
+                new byte[] {
+                    (byte) 0x0A, // Call index
+                    0x03, // Active call state
+                    0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
+                    // Bit2:0-provided-by-netw.,1-withheld-by-netw.
+                    (byte) 0x0B, // Call index
+                    0x04, // Locally Held call state
+                    0x00, // Bit0:0-incoming,1-outgoing | Bit1:0-not-withheld,1-withheld |
+                    // Bit2:0-provided-by-netw.,1-withheld-by-netw.
+                };
+        callsMap.put(
+                0x0B,
+                TbsCall.create(
+                        new BluetoothLeCall(
+                                UUID.randomUUID(), "tel:987654321", "Kate", 0x04, 0x00)));
+        verifySetValue(
+                characteristic,
+                new Pair, byte[]>(callsMap, packetExpected),
+                false,
+                mFirstDevice,
+                true);
     }
 
     @Test
@@ -465,11 +575,16 @@ public class TbsGattTest {
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
         mTbsGatt.setCallControlPointResult(mFirstDevice, requestedOpcode, callIndex, result);
-        Assert.assertTrue(Arrays.equals(characteristic.getValue(),
-                new byte[] {(byte) (requestedOpcode & 0xff), (byte) (callIndex & 0xff),
-                        (byte) (result & 0xff)}));
-        verify(mMockGattServer, after(2000)).notifyCharacteristicChanged(eq(mFirstDevice),
-                eq(characteristic), eq(false));
+        Assert.assertTrue(
+                Arrays.equals(
+                        characteristic.getValue(),
+                        new byte[] {
+                            (byte) (requestedOpcode & 0xff),
+                            (byte) (callIndex & 0xff),
+                            (byte) (result & 0xff)
+                        }));
+        verify(mMockGattServer, after(2000))
+                .notifyCharacteristicChanged(eq(mFirstDevice), eq(characteristic), eq(false));
         reset(mMockGattServer);
 
         callIndex = 0x02;
@@ -477,11 +592,16 @@ public class TbsGattTest {
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
         mTbsGatt.setCallControlPointResult(mFirstDevice, requestedOpcode, callIndex, result);
-        Assert.assertTrue(Arrays.equals(characteristic.getValue(),
-                new byte[] {(byte) (requestedOpcode & 0xff), (byte) (callIndex & 0xff),
-                        (byte) (result & 0xff)}));
-        verify(mMockGattServer, after(2000).times(0)).notifyCharacteristicChanged(any(), any(),
-                anyBoolean());
+        Assert.assertTrue(
+                Arrays.equals(
+                        characteristic.getValue(),
+                        new byte[] {
+                            (byte) (requestedOpcode & 0xff),
+                            (byte) (callIndex & 0xff),
+                            (byte) (result & 0xff)
+                        }));
+        verify(mMockGattServer, after(2000).times(0))
+                .notifyCharacteristicChanged(any(), any(), anyBoolean());
     }
 
     @Test
@@ -491,18 +611,18 @@ public class TbsGattTest {
                 getCharacteristic(TbsGatt.UUID_TERMINATION_REASON);
 
         // Check with no CCC configured
-        verifySetValue(characteristic, new Pair(0x0A, 0x01), false, mFirstDevice,
-                true);
+        verifySetValue(
+                characteristic, new Pair(0x0A, 0x01), false, mFirstDevice, true);
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
-        verifySetValue(characteristic, new Pair(0x0B, 0x02), true, mFirstDevice,
-                true);
+        verifySetValue(
+                characteristic, new Pair(0x0B, 0x02), true, mFirstDevice, true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        verifySetValue(characteristic, new Pair(0x0C, 0x02), false, mFirstDevice,
-                true);
+        verifySetValue(
+                characteristic, new Pair(0x0C, 0x02), false, mFirstDevice, true);
     }
 
     @Test
@@ -511,21 +631,33 @@ public class TbsGattTest {
         BluetoothGattCharacteristic characteristic = getCharacteristic(TbsGatt.UUID_INCOMING_CALL);
 
         // Check with no CCC configured
-        verifySetValue(characteristic, new Pair(0x0A, "tel:123456789"), false,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(0x0A, "tel:123456789"),
+                false,
+                mFirstDevice,
+                true);
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
-        verifySetValue(characteristic, new Pair(0x0A, "tel:987654321"), true,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(0x0A, "tel:987654321"),
+                true,
+                mFirstDevice,
+                true);
 
         // No incoming call (should not send any notification)
         verifySetValue(characteristic, null, false, mFirstDevice, true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        verifySetValue(characteristic, new Pair(0x0A, "tel:123456789"), false,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(0x0A, "tel:123456789"),
+                false,
+                mFirstDevice,
+                true);
     }
 
     @Test
@@ -535,21 +667,33 @@ public class TbsGattTest {
                 getCharacteristic(TbsGatt.UUID_CALL_FRIENDLY_NAME);
 
         // Check with no CCC configured
-        verifySetValue(characteristic, new Pair(0x0A, "PersonA"), false,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(0x0A, "PersonA"),
+                false,
+                mFirstDevice,
+                true);
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
-        verifySetValue(characteristic, new Pair(0x0B, "PersonB"), true,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(0x0B, "PersonB"),
+                true,
+                mFirstDevice,
+                true);
 
         // Clear freindly name (should not send any notification)
         verifySetValue(characteristic, null, false, mFirstDevice, true);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
-        verifySetValue(characteristic, new Pair(0x0C, "PersonC"), false,
-                mFirstDevice, true);
+        verifySetValue(
+                characteristic,
+                new Pair(0x0C, "PersonC"),
+                false,
+                mFirstDevice,
+                true);
     }
 
     @Test
@@ -560,15 +704,20 @@ public class TbsGattTest {
 
         // Call the internal GATT callback as if peer device accepts the call
         byte[] value = new byte[] {0x00 /* opcode */, 0x0A /* argument */};
-        mTbsGatt.mGattServerCallback.onCharacteristicWriteRequest(mFirstDevice, 1, characteristic,
-                false, true, 0, value);
+        mTbsGatt.mGattServerCallback.onCharacteristicWriteRequest(
+                mFirstDevice, 1, characteristic, false, true, 0, value);
 
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0), aryEq(new byte[] {0x00, 0x0A}));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        aryEq(new byte[] {0x00, 0x0A}));
 
         // Verify the higher layer callback call
-        verify(mMockTbsGattCallback).onCallControlPointRequest(eq(mFirstDevice), eq(0x00),
-                aryEq(new byte[] {0x0A}));
+        verify(mMockTbsGattCallback)
+                .onCallControlPointRequest(eq(mFirstDevice), eq(0x00), aryEq(new byte[] {0x0A}));
     }
 
     @Test
@@ -579,11 +728,16 @@ public class TbsGattTest {
 
         // Call the internal GATT callback as if peer device accepts the call
         byte[] value = new byte[] {0x00 /* opcode */};
-        mTbsGatt.mGattServerCallback.onCharacteristicWriteRequest(mFirstDevice, 1, characteristic,
-                false, true, 0, value);
+        mTbsGatt.mGattServerCallback.onCharacteristicWriteRequest(
+                mFirstDevice, 1, characteristic, false, true, 0, value);
 
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH), eq(0), aryEq(new byte[] {0x00}));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH),
+                        eq(0),
+                        aryEq(new byte[] {0x00}));
     }
 
     @Test
@@ -604,15 +758,17 @@ public class TbsGattTest {
         mTbsGatt.setInbandRingtoneFlag(mFirstDevice);
         mTbsGatt.setInbandRingtoneFlag(mFirstDevice);
 
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mFirstDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mFirstDevice), eq(characteristic), eq(false), eq(valueBytes));
 
         reset(mMockGattServer);
         mTbsGatt.setInbandRingtoneFlag(mSecondDevice);
         mTbsGatt.setInbandRingtoneFlag(mSecondDevice);
 
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mSecondDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mSecondDevice), eq(characteristic), eq(false), eq(valueBytes));
     }
 
     @Test
@@ -628,16 +784,17 @@ public class TbsGattTest {
         valueBytes[0] = (byte) (statusFlagValue & 0xFF);
         valueBytes[1] = (byte) ((statusFlagValue >> 8) & 0xFF);
 
-
         mTbsGatt.setInbandRingtoneFlag(mFirstDevice);
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mFirstDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mFirstDevice), eq(characteristic), eq(false), eq(valueBytes));
 
         reset(mMockGattServer);
 
         mTbsGatt.setInbandRingtoneFlag(mSecondDevice);
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mSecondDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mSecondDevice), eq(characteristic), eq(false), eq(valueBytes));
 
         reset(mMockGattServer);
 
@@ -648,14 +805,16 @@ public class TbsGattTest {
 
         mTbsGatt.clearInbandRingtoneFlag(mFirstDevice);
         mTbsGatt.clearInbandRingtoneFlag(mFirstDevice);
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mFirstDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mFirstDevice), eq(characteristic), eq(false), eq(valueBytes));
 
         reset(mMockGattServer);
         mTbsGatt.clearInbandRingtoneFlag(mSecondDevice);
         mTbsGatt.clearInbandRingtoneFlag(mSecondDevice);
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mSecondDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mSecondDevice), eq(characteristic), eq(false), eq(valueBytes));
     }
 
     @Test
@@ -675,26 +834,29 @@ public class TbsGattTest {
         mTbsGatt.setSilentModeFlag();
         mTbsGatt.setSilentModeFlag();
         mTbsGatt.setSilentModeFlag();
-        verify(mMockGattServer, times(2)).notifyCharacteristicChanged(any(),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(2))
+                .notifyCharacteristicChanged(any(), eq(characteristic), eq(false), eq(valueBytes));
 
         reset(mMockGattServer);
 
-        statusFlagValue = TbsGatt.STATUS_FLAG_INBAND_RINGTONE_ENABLED
-                                        | TbsGatt.STATUS_FLAG_SILENT_MODE_ENABLED;
+        statusFlagValue =
+                TbsGatt.STATUS_FLAG_INBAND_RINGTONE_ENABLED
+                        | TbsGatt.STATUS_FLAG_SILENT_MODE_ENABLED;
         valueBytes[0] = (byte) (statusFlagValue & 0xFF);
         valueBytes[1] = (byte) ((statusFlagValue >> 8) & 0xFF);
 
         mTbsGatt.setInbandRingtoneFlag(mFirstDevice);
 
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mFirstDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mFirstDevice), eq(characteristic), eq(false), eq(valueBytes));
 
         reset(mMockGattServer);
         mTbsGatt.setInbandRingtoneFlag(mSecondDevice);
 
-        verify(mMockGattServer, times(1)).notifyCharacteristicChanged(eq(mSecondDevice),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(1))
+                .notifyCharacteristicChanged(
+                        eq(mSecondDevice), eq(characteristic), eq(false), eq(valueBytes));
         reset(mMockGattServer);
 
         statusFlagValue = TbsGatt.STATUS_FLAG_INBAND_RINGTONE_ENABLED;
@@ -705,18 +867,17 @@ public class TbsGattTest {
         mTbsGatt.clearSilentModeFlag();
         mTbsGatt.clearSilentModeFlag();
         mTbsGatt.clearSilentModeFlag();
-        verify(mMockGattServer, times(2)).notifyCharacteristicChanged(any(),
-                                eq(characteristic), eq(false), eq(valueBytes));
+        verify(mMockGattServer, times(2))
+                .notifyCharacteristicChanged(any(), eq(characteristic), eq(false), eq(valueBytes));
     }
 
     @Test
     public void testHandleIsInbandRingtoneEnabled() {
         prepareDefaultService();
-        BluetoothGattCharacteristic characteristic =
-                getCharacteristic(TbsGatt.UUID_STATUS_FLAGS);
+        BluetoothGattCharacteristic characteristic = getCharacteristic(TbsGatt.UUID_STATUS_FLAGS);
 
-        mTbsGatt.mGattServerCallback.onCharacteristicReadRequest(mFirstDevice, 1, 0,
-                characteristic);
+        mTbsGatt.mGattServerCallback.onCharacteristicReadRequest(
+                mFirstDevice, 1, 0, characteristic);
         // Verify the higher layer callback call
         verify(mMockTbsGattCallback).isInbandRingtoneEnabled(eq(mFirstDevice));
     }
@@ -732,25 +893,37 @@ public class TbsGattTest {
 
         // Check with no configuration
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Check with notifications enabled
         configureNotifications(mFirstDevice, characteristic, true);
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Check with notifications disabled
         configureNotifications(mFirstDevice, characteristic, false);
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
     }
 
     @Test
@@ -764,67 +937,94 @@ public class TbsGattTest {
 
         // Check with no configuration
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
 
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mSecondDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mSecondDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mSecondDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Check with notifications enabled for first device
         configureNotifications(mFirstDevice, characteristic, true);
         verifySetValue(characteristic, 4, true, mFirstDevice, true);
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Check if second device is still not subscribed for notifications and will not get it
         verifySetValue(characteristic, 5, false, mSecondDevice, false);
-        verify(mMockGattServer).notifyCharacteristicChanged(eq(mFirstDevice),
-                                eq(characteristic), eq(false));
+        verify(mMockGattServer)
+                .notifyCharacteristicChanged(eq(mFirstDevice), eq(characteristic), eq(false));
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mSecondDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mSecondDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mSecondDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Check with notifications enabled for first and second device
         configureNotifications(mSecondDevice, characteristic, true);
         verifySetValue(characteristic, 6, true, mSecondDevice, false);
-        verify(mMockGattServer).notifyCharacteristicChanged(eq(mFirstDevice),
-                                eq(characteristic), eq(false));
+        verify(mMockGattServer)
+                .notifyCharacteristicChanged(eq(mFirstDevice), eq(characteristic), eq(false));
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mSecondDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mSecondDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mSecondDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Disable notification for first device, check if second will get notification
         configureNotifications(mFirstDevice, characteristic, false);
         verifySetValue(characteristic, 7, false, mFirstDevice, false);
-        verify(mMockGattServer).notifyCharacteristicChanged(eq(mSecondDevice),
-                                eq(characteristic), eq(false));
+        verify(mMockGattServer)
+                .notifyCharacteristicChanged(eq(mSecondDevice), eq(characteristic), eq(false));
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mFirstDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
         reset(mMockGattServer);
 
         // Check with notifications disabled of both device
         configureNotifications(mSecondDevice, characteristic, false);
         verifySetValue(characteristic, 4, false, mFirstDevice, false);
-        verify(mMockGattServer, times(0)).notifyCharacteristicChanged(eq(mSecondDevice),
-                                eq(characteristic), eq(false));
+        verify(mMockGattServer, times(0))
+                .notifyCharacteristicChanged(eq(mSecondDevice), eq(characteristic), eq(false));
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mSecondDevice, 1, 0, descriptor);
-        verify(mMockGattServer).sendResponse(eq(mSecondDevice), eq(1),
-                eq(BluetoothGatt.GATT_SUCCESS), eq(0),
-                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
-
+        verify(mMockGattServer)
+                .sendResponse(
+                        eq(mSecondDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_SUCCESS),
+                        eq(0),
+                        eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
     }
 
     @Test
@@ -842,8 +1042,12 @@ public class TbsGattTest {
                 mFirstDevice, 1, 0, characteristic);
 
         verify(mMockGattServer)
-                .sendResponse(eq(mFirstDevice), eq(1),
-                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any());
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION),
+                        eq(0),
+                        any());
     }
 
     @Test
@@ -919,14 +1123,21 @@ public class TbsGattTest {
                 .when(mMockTbsService)
                 .getDeviceAuthorization(any(BluetoothDevice.class));
 
-        byte[] value = new byte[] {0x00, /* opcode */ 0x0A, /* argument */ };
+        byte[] value =
+                new byte[] {
+                    0x00, /* opcode */ 0x0A, /* argument */
+                };
 
         mTbsGatt.mGattServerCallback.onCharacteristicWriteRequest(
                 mFirstDevice, 1, characteristic, false, true, 0, value);
 
         verify(mMockGattServer)
-                .sendResponse(eq(mFirstDevice), eq(1),
-                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any());
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION),
+                        eq(0),
+                        any());
     }
 
     @Test
@@ -940,7 +1151,10 @@ public class TbsGattTest {
                 .when(mMockTbsService)
                 .getDeviceAuthorization(any(BluetoothDevice.class));
 
-        byte[] value = new byte[] {0x00, /* opcode */ 0x0A, /* argument */ };
+        byte[] value =
+                new byte[] {
+                    0x00, /* opcode */ 0x0A, /* argument */
+                };
 
         mTbsGatt.mGattServerCallback.onCharacteristicWriteRequest(
                 mFirstDevice, 1, characteristic, false, true, 0, value);
@@ -964,8 +1178,12 @@ public class TbsGattTest {
         mTbsGatt.mGattServerCallback.onDescriptorReadRequest(mFirstDevice, 1, 0, descriptor);
 
         verify(mMockGattServer)
-                .sendResponse(eq(mFirstDevice), eq(1),
-                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any());
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION),
+                        eq(0),
+                        any());
     }
 
     @Test
@@ -999,14 +1217,21 @@ public class TbsGattTest {
                 .when(mMockTbsService)
                 .getDeviceAuthorization(any(BluetoothDevice.class));
 
-        byte[] value = new byte[] {0x00, /* opcode */ 0x0A, /* argument */ };
+        byte[] value =
+                new byte[] {
+                    0x00, /* opcode */ 0x0A, /* argument */
+                };
 
         mTbsGatt.mGattServerCallback.onDescriptorWriteRequest(
                 mFirstDevice, 1, descriptor, false, true, 0, value);
 
         verify(mMockGattServer)
-                .sendResponse(eq(mFirstDevice), eq(1),
-                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any());
+                .sendResponse(
+                        eq(mFirstDevice),
+                        eq(1),
+                        eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION),
+                        eq(0),
+                        any());
     }
 
     @Test
@@ -1022,7 +1247,10 @@ public class TbsGattTest {
                 .when(mMockTbsService)
                 .getDeviceAuthorization(any(BluetoothDevice.class));
 
-        byte[] value = new byte[] {0x00, /* opcode */ 0x0A, /* argument */ };
+        byte[] value =
+                new byte[] {
+                    0x00, /* opcode */ 0x0A, /* argument */
+                };
 
         mTbsGatt.mGattServerCallback.onDescriptorWriteRequest(
                 mFirstDevice, 1, descriptor, false, true, 0, value);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java
index 7d6b512f48e..3944a12b0cd 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java
@@ -81,10 +81,17 @@ public class TbsGenericTest {
         getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
 
         // Default TbsGatt mock behavior
-        doReturn(true).when(mTbsGatt).init(mGtbsCcidCaptor.capture(), mGtbsUciCaptor.capture(),
-                mDefaultGtbsUriSchemesCaptor.capture(), anyBoolean(), anyBoolean(),
-                mDefaultGtbsProviderNameCaptor.capture(), mDefaultGtbsTechnologyCaptor.capture(),
-                mTbsGattCallback.capture());
+        doReturn(true)
+                .when(mTbsGatt)
+                .init(
+                        mGtbsCcidCaptor.capture(),
+                        mGtbsUciCaptor.capture(),
+                        mDefaultGtbsUriSchemesCaptor.capture(),
+                        anyBoolean(),
+                        anyBoolean(),
+                        mDefaultGtbsProviderNameCaptor.capture(),
+                        mDefaultGtbsTechnologyCaptor.capture(),
+                        mTbsGattCallback.capture());
         doReturn(true).when(mTbsGatt).setBearerProviderName(anyString());
         doReturn(true).when(mTbsGatt).setBearerTechnology(anyInt());
         doReturn(true).when(mTbsGatt).setBearerUriSchemesSupportedList(any());
@@ -114,12 +121,21 @@ public class TbsGenericTest {
         String uci = "testUci";
         List uriSchemes = Arrays.asList("tel", "xmpp");
         Integer capabilities =
-                BluetoothLeCallControl.CAPABILITY_HOLD_CALL | BluetoothLeCallControl.CAPABILITY_JOIN_CALLS;
+                BluetoothLeCallControl.CAPABILITY_HOLD_CALL
+                        | BluetoothLeCallControl.CAPABILITY_JOIN_CALLS;
         String providerName = "testProviderName";
         int technology = 0x02;
 
-        assertThat(mTbsGeneric.addBearer("testBearer", mIBluetoothLeCallControlCallback, uci, uriSchemes,
-                capabilities, providerName, technology)).isTrue();
+        assertThat(
+                        mTbsGeneric.addBearer(
+                                "testBearer",
+                                mIBluetoothLeCallControlCallback,
+                                uci,
+                                uriSchemes,
+                                capabilities,
+                                providerName,
+                                technology))
+                .isTrue();
 
         ArgumentCaptor ccidCaptor = ArgumentCaptor.forClass(Integer.class);
         try {
@@ -180,8 +196,13 @@ public class TbsGenericTest {
         Integer ccid = prepareTestBearer();
         reset(mTbsGatt);
 
-        BluetoothLeCall tbsCall = new BluetoothLeCall(UUID.randomUUID(), "tel:987654321",
-                "aFriendlyCaller", BluetoothLeCall.STATE_INCOMING, 0);
+        BluetoothLeCall tbsCall =
+                new BluetoothLeCall(
+                        UUID.randomUUID(),
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_INCOMING,
+                        0);
         mTbsGeneric.callAdded(ccid, tbsCall);
 
         ArgumentCaptor callIndexCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -207,8 +228,13 @@ public class TbsGenericTest {
         reset(mTbsGatt);
 
         UUID callUuid = UUID.randomUUID();
-        BluetoothLeCall tbsCall = new BluetoothLeCall(callUuid, "tel:987654321",
-                "aFriendlyCaller", BluetoothLeCall.STATE_INCOMING, 0);
+        BluetoothLeCall tbsCall =
+                new BluetoothLeCall(
+                        callUuid,
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_INCOMING,
+                        0);
 
         mTbsGeneric.callAdded(ccid, tbsCall);
         ArgumentCaptor callIndexCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -236,8 +262,13 @@ public class TbsGenericTest {
         reset(mTbsGatt);
 
         UUID callUuid = UUID.randomUUID();
-        BluetoothLeCall tbsCall = new BluetoothLeCall(callUuid, "tel:987654321",
-                "aFriendlyCaller", BluetoothLeCall.STATE_INCOMING, 0);
+        BluetoothLeCall tbsCall =
+                new BluetoothLeCall(
+                        callUuid,
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_INCOMING,
+                        0);
 
         mTbsGeneric.callAdded(ccid, tbsCall);
         ArgumentCaptor callIndexCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -273,10 +304,20 @@ public class TbsGenericTest {
         reset(mTbsGatt);
 
         List tbsCalls = new ArrayList<>();
-        tbsCalls.add(new BluetoothLeCall(UUID.randomUUID(), "tel:987654321", "anIncomingCaller",
-                BluetoothLeCall.STATE_INCOMING, 0));
-        tbsCalls.add(new BluetoothLeCall(UUID.randomUUID(), "tel:123456789", "anOutgoingCaller",
-                BluetoothLeCall.STATE_ALERTING, BluetoothLeCall.FLAG_OUTGOING_CALL));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        UUID.randomUUID(),
+                        "tel:987654321",
+                        "anIncomingCaller",
+                        BluetoothLeCall.STATE_INCOMING,
+                        0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        UUID.randomUUID(),
+                        "tel:123456789",
+                        "anOutgoingCaller",
+                        BluetoothLeCall.STATE_ALERTING,
+                        BluetoothLeCall.FLAG_OUTGOING_CALL));
 
         mTbsGeneric.currentCallsList(ccid, tbsCalls);
         ArgumentCaptor currentCallsCaptor = ArgumentCaptor.forClass(Map.class);
@@ -299,8 +340,13 @@ public class TbsGenericTest {
         // Prepare the incoming call
         UUID callUuid = UUID.randomUUID();
         List tbsCalls = new ArrayList<>();
-        tbsCalls.add(new BluetoothLeCall(callUuid, "tel:987654321", "aFriendlyCaller",
-                BluetoothLeCall.STATE_INCOMING, 0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        callUuid,
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_INCOMING,
+                        0));
         mTbsGeneric.currentCallsList(ccid, tbsCalls);
 
         ArgumentCaptor currentCallsCaptor = ArgumentCaptor.forClass(Map.class);
@@ -312,14 +358,16 @@ public class TbsGenericTest {
 
         byte args[] = new byte[1];
         args[0] = (byte) (callIndex & 0xFF);
-        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
-                TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT, args);
+        mTbsGattCallback
+                .getValue()
+                .onCallControlPointRequest(
+                        mCurrentDevice, TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT, args);
 
         ArgumentCaptor requestIdCaptor = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor callUuidCaptor = ArgumentCaptor.forClass(ParcelUuid.class);
         try {
-            verify(mIBluetoothLeCallControlCallback).onAcceptCall(requestIdCaptor.capture(),
-                    callUuidCaptor.capture());
+            verify(mIBluetoothLeCallControlCallback)
+                    .onAcceptCall(requestIdCaptor.capture(), callUuidCaptor.capture());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -328,13 +376,17 @@ public class TbsGenericTest {
         verify(leAudioService).setActiveDevice(mCurrentDevice);
 
         // Respond with requestComplete...
-        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
+        mTbsGeneric.requestResult(
+                ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
         mTbsGeneric.callStateChanged(ccid, callUuid, BluetoothLeCall.STATE_ACTIVE);
 
         // ..and verify if GTBS control point is updated to notifier the peer about the result
-        verify(mTbsGatt).setCallControlPointResult(eq(mCurrentDevice),
-                eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT), eq(callIndex),
-                eq(BluetoothLeCallControl.RESULT_SUCCESS));
+        verify(mTbsGatt)
+                .setCallControlPointResult(
+                        eq(mCurrentDevice),
+                        eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT),
+                        eq(callIndex),
+                        eq(BluetoothLeCallControl.RESULT_SUCCESS));
     }
 
     @Test
@@ -346,8 +398,13 @@ public class TbsGenericTest {
         // Prepare the incoming call
         UUID callUuid = UUID.randomUUID();
         List tbsCalls = new ArrayList<>();
-        tbsCalls.add(new BluetoothLeCall(callUuid, "tel:987654321", "aFriendlyCaller",
-                BluetoothLeCall.STATE_ACTIVE, 0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        callUuid,
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_ACTIVE,
+                        0));
         mTbsGeneric.currentCallsList(ccid, tbsCalls);
 
         ArgumentCaptor currentCallsCaptor = ArgumentCaptor.forClass(Map.class);
@@ -359,27 +416,33 @@ public class TbsGenericTest {
 
         byte args[] = new byte[1];
         args[0] = (byte) (callIndex & 0xFF);
-        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
-                TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE, args);
+        mTbsGattCallback
+                .getValue()
+                .onCallControlPointRequest(
+                        mCurrentDevice, TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE, args);
 
         ArgumentCaptor requestIdCaptor = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor callUuidCaptor = ArgumentCaptor.forClass(ParcelUuid.class);
         try {
-            verify(mIBluetoothLeCallControlCallback).onTerminateCall(requestIdCaptor.capture(),
-                    callUuidCaptor.capture());
+            verify(mIBluetoothLeCallControlCallback)
+                    .onTerminateCall(requestIdCaptor.capture(), callUuidCaptor.capture());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
         assertThat(callUuidCaptor.getValue().getUuid()).isEqualTo(callUuid);
 
         // Respond with requestComplete...
-        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
+        mTbsGeneric.requestResult(
+                ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
         mTbsGeneric.callRemoved(ccid, callUuid, 0x01);
 
         // ..and verify if GTBS control point is updated to notifier the peer about the result
-        verify(mTbsGatt).setCallControlPointResult(eq(mCurrentDevice),
-                eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE), eq(callIndex),
-                eq(BluetoothLeCallControl.RESULT_SUCCESS));
+        verify(mTbsGatt)
+                .setCallControlPointResult(
+                        eq(mCurrentDevice),
+                        eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE),
+                        eq(callIndex),
+                        eq(BluetoothLeCallControl.RESULT_SUCCESS));
     }
 
     @Test
@@ -391,8 +454,13 @@ public class TbsGenericTest {
         // Prepare the incoming call
         UUID callUuid = UUID.randomUUID();
         List tbsCalls = new ArrayList<>();
-        tbsCalls.add(new BluetoothLeCall(callUuid, "tel:987654321", "aFriendlyCaller",
-                BluetoothLeCall.STATE_ACTIVE, 0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        callUuid,
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_ACTIVE,
+                        0));
         mTbsGeneric.currentCallsList(ccid, tbsCalls);
 
         ArgumentCaptor currentCallsCaptor = ArgumentCaptor.forClass(Map.class);
@@ -404,27 +472,33 @@ public class TbsGenericTest {
 
         byte args[] = new byte[1];
         args[0] = (byte) (callIndex & 0xFF);
-        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
-                TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD, args);
+        mTbsGattCallback
+                .getValue()
+                .onCallControlPointRequest(
+                        mCurrentDevice, TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD, args);
 
         ArgumentCaptor requestIdCaptor = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor callUuidCaptor = ArgumentCaptor.forClass(ParcelUuid.class);
         try {
-            verify(mIBluetoothLeCallControlCallback).onHoldCall(requestIdCaptor.capture(),
-                    callUuidCaptor.capture());
+            verify(mIBluetoothLeCallControlCallback)
+                    .onHoldCall(requestIdCaptor.capture(), callUuidCaptor.capture());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
         assertThat(callUuidCaptor.getValue().getUuid()).isEqualTo(callUuid);
 
         // Respond with requestComplete...
-        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
+        mTbsGeneric.requestResult(
+                ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
         mTbsGeneric.callStateChanged(ccid, callUuid, BluetoothLeCall.STATE_LOCALLY_HELD);
 
         // ..and verify if GTBS control point is updated to notifier the peer about the result
-        verify(mTbsGatt).setCallControlPointResult(eq(mCurrentDevice),
-                eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD), eq(callIndex),
-                eq(BluetoothLeCallControl.RESULT_SUCCESS));
+        verify(mTbsGatt)
+                .setCallControlPointResult(
+                        eq(mCurrentDevice),
+                        eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD),
+                        eq(callIndex),
+                        eq(BluetoothLeCallControl.RESULT_SUCCESS));
     }
 
     @Test
@@ -436,8 +510,13 @@ public class TbsGenericTest {
         // Prepare the incoming call
         UUID callUuid = UUID.randomUUID();
         List tbsCalls = new ArrayList<>();
-        tbsCalls.add(new BluetoothLeCall(callUuid, "tel:987654321", "aFriendlyCaller",
-                BluetoothLeCall.STATE_LOCALLY_HELD, 0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        callUuid,
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_LOCALLY_HELD,
+                        0));
         mTbsGeneric.currentCallsList(ccid, tbsCalls);
 
         ArgumentCaptor currentCallsCaptor = ArgumentCaptor.forClass(Map.class);
@@ -449,27 +528,33 @@ public class TbsGenericTest {
 
         byte args[] = new byte[1];
         args[0] = (byte) (callIndex & 0xFF);
-        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
-                TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE, args);
+        mTbsGattCallback
+                .getValue()
+                .onCallControlPointRequest(
+                        mCurrentDevice, TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE, args);
 
         ArgumentCaptor requestIdCaptor = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor callUuidCaptor = ArgumentCaptor.forClass(ParcelUuid.class);
         try {
-            verify(mIBluetoothLeCallControlCallback).onUnholdCall(requestIdCaptor.capture(),
-                    callUuidCaptor.capture());
+            verify(mIBluetoothLeCallControlCallback)
+                    .onUnholdCall(requestIdCaptor.capture(), callUuidCaptor.capture());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
         assertThat(callUuidCaptor.getValue().getUuid()).isEqualTo(callUuid);
 
         // Respond with requestComplete...
-        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
+        mTbsGeneric.requestResult(
+                ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
         mTbsGeneric.callStateChanged(ccid, callUuid, BluetoothLeCall.STATE_ACTIVE);
 
         // ..and verify if GTBS control point is updated to notifier the peer about the result
-        verify(mTbsGatt).setCallControlPointResult(eq(mCurrentDevice),
-                eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE), eq(callIndex),
-                eq(BluetoothLeCallControl.RESULT_SUCCESS));
+        verify(mTbsGatt)
+                .setCallControlPointResult(
+                        eq(mCurrentDevice),
+                        eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE),
+                        eq(callIndex),
+                        eq(BluetoothLeCallControl.RESULT_SUCCESS));
     }
 
     @Test
@@ -483,14 +568,18 @@ public class TbsGenericTest {
 
         // Act as if peer originates a call via Gtbs
         String uri = "xmpp:123456789";
-        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
-                TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE, uri.getBytes());
+        mTbsGattCallback
+                .getValue()
+                .onCallControlPointRequest(
+                        mCurrentDevice,
+                        TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE,
+                        uri.getBytes());
 
         ArgumentCaptor requestIdCaptor = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor callUuidCaptor = ArgumentCaptor.forClass(ParcelUuid.class);
         try {
-            verify(mIBluetoothLeCallControlCallback).onPlaceCall(requestIdCaptor.capture(),
-                    callUuidCaptor.capture(), eq(uri));
+            verify(mIBluetoothLeCallControlCallback)
+                    .onPlaceCall(requestIdCaptor.capture(), callUuidCaptor.capture(), eq(uri));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -499,15 +588,24 @@ public class TbsGenericTest {
         verify(leAudioService).setActiveDevice(mCurrentDevice);
 
         // Respond with requestComplete...
-        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
-        mTbsGeneric.callAdded(ccid,
-                new BluetoothLeCall(callUuidCaptor.getValue().getUuid(), uri, "anOutgoingCaller",
-                        BluetoothLeCall.STATE_ALERTING, BluetoothLeCall.FLAG_OUTGOING_CALL));
+        mTbsGeneric.requestResult(
+                ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
+        mTbsGeneric.callAdded(
+                ccid,
+                new BluetoothLeCall(
+                        callUuidCaptor.getValue().getUuid(),
+                        uri,
+                        "anOutgoingCaller",
+                        BluetoothLeCall.STATE_ALERTING,
+                        BluetoothLeCall.FLAG_OUTGOING_CALL));
 
         // ..and verify if GTBS control point is updated to notifier the peer about the result
-        verify(mTbsGatt).setCallControlPointResult(eq(mCurrentDevice),
-                eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE), anyInt(),
-                eq(BluetoothLeCallControl.RESULT_SUCCESS));
+        verify(mTbsGatt)
+                .setCallControlPointResult(
+                        eq(mCurrentDevice),
+                        eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE),
+                        anyInt(),
+                        eq(BluetoothLeCallControl.RESULT_SUCCESS));
     }
 
     @Test
@@ -519,10 +617,20 @@ public class TbsGenericTest {
         // Prepare the incoming call
         List callUuids = Arrays.asList(UUID.randomUUID(), UUID.randomUUID());
         List tbsCalls = new ArrayList<>();
-        tbsCalls.add(new BluetoothLeCall(callUuids.get(0), "tel:987654321", "aFriendlyCaller",
-                BluetoothLeCall.STATE_LOCALLY_HELD, 0));
-        tbsCalls.add(new BluetoothLeCall(callUuids.get(1), "tel:123456789", "a2ndFriendlyCaller",
-                BluetoothLeCall.STATE_ACTIVE, 0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        callUuids.get(0),
+                        "tel:987654321",
+                        "aFriendlyCaller",
+                        BluetoothLeCall.STATE_LOCALLY_HELD,
+                        0));
+        tbsCalls.add(
+                new BluetoothLeCall(
+                        callUuids.get(1),
+                        "tel:123456789",
+                        "a2ndFriendlyCaller",
+                        BluetoothLeCall.STATE_ACTIVE,
+                        0));
         mTbsGeneric.currentCallsList(ccid, tbsCalls);
 
         ArgumentCaptor currentCallsCaptor = ArgumentCaptor.forClass(Map.class);
@@ -536,14 +644,16 @@ public class TbsGenericTest {
         for (Integer callIndex : capturedCurrentCalls.keySet()) {
             args[i++] = (byte) (callIndex & 0xFF);
         }
-        mTbsGattCallback.getValue().onCallControlPointRequest(mCurrentDevice,
-                TbsGatt.CALL_CONTROL_POINT_OPCODE_JOIN, args);
+        mTbsGattCallback
+                .getValue()
+                .onCallControlPointRequest(
+                        mCurrentDevice, TbsGatt.CALL_CONTROL_POINT_OPCODE_JOIN, args);
 
         ArgumentCaptor requestIdCaptor = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor> callUuidCaptor = ArgumentCaptor.forClass(List.class);
         try {
-            verify(mIBluetoothLeCallControlCallback).onJoinCalls(requestIdCaptor.capture(),
-                    callUuidCaptor.capture());
+            verify(mIBluetoothLeCallControlCallback)
+                    .onJoinCalls(requestIdCaptor.capture(), callUuidCaptor.capture());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -554,12 +664,16 @@ public class TbsGenericTest {
         }
 
         // // Respond with requestComplete...
-        mTbsGeneric.requestResult(ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
+        mTbsGeneric.requestResult(
+                ccid, requestIdCaptor.getValue(), BluetoothLeCallControl.RESULT_SUCCESS);
         mTbsGeneric.callStateChanged(ccid, callUuids.get(0), BluetoothLeCall.STATE_ACTIVE);
 
         // ..and verify if GTBS control point is updated to notifier the peer about the result
-        verify(mTbsGatt).setCallControlPointResult(eq(mCurrentDevice),
-                eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_JOIN), anyInt(),
-                eq(BluetoothLeCallControl.RESULT_SUCCESS));
+        verify(mTbsGatt)
+                .setCallControlPointResult(
+                        eq(mCurrentDevice),
+                        eq(TbsGatt.CALL_CONTROL_POINT_OPCODE_JOIN),
+                        anyInt(),
+                        eq(BluetoothLeCallControl.RESULT_SUCCESS));
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java
index e06e2623b56..884b914a4f9 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java
@@ -80,8 +80,8 @@ public class BluetoothCallTest {
 
     @Test
     public void getRemainingPostDialSequence_whenInnerCallIsNull_throwsNPE() {
-        assertThrows(NullPointerException.class,
-                () -> mBluetoothCall.getRemainingPostDialSequence());
+        assertThrows(
+                NullPointerException.class, () -> mBluetoothCall.getRemainingPostDialSequence());
     }
 
     @Test
@@ -116,13 +116,14 @@ public class BluetoothCallTest {
 
     @Test
     public void enterBackgroundAudioProcessing_whenInnerCallIsNull_throwsNPE() {
-        assertThrows(NullPointerException.class,
-                () -> mBluetoothCall.enterBackgroundAudioProcessing());
+        assertThrows(
+                NullPointerException.class, () -> mBluetoothCall.enterBackgroundAudioProcessing());
     }
 
     @Test
     public void exitBackgroundAudioProcessing_whenInnerCallIsNull_throwsNPE() {
-        assertThrows(NullPointerException.class,
+        assertThrows(
+                NullPointerException.class,
                 () -> mBluetoothCall.exitBackgroundAudioProcessing(true));
     }
 
@@ -143,8 +144,8 @@ public class BluetoothCallTest {
 
     @Test
     public void phoneAccountSelected_whenInnerCallIsNull_throwsNPE() {
-        assertThrows(NullPointerException.class,
-                () -> mBluetoothCall.phoneAccountSelected(null, true));
+        assertThrows(
+                NullPointerException.class, () -> mBluetoothCall.phoneAccountSelected(null, true));
     }
 
     @Test
@@ -288,7 +289,8 @@ public class BluetoothCallTest {
 
     @Test
     public void getGenericConferenceActiveChildCallId_whenInnerCallIsNull_throwsNPE() {
-        assertThrows(NullPointerException.class,
+        assertThrows(
+                NullPointerException.class,
                 () -> mBluetoothCall.getGenericConferenceActiveChildCallId());
     }
 
@@ -366,8 +368,8 @@ public class BluetoothCallTest {
 
     @Test
     public void wasConferencePreviouslyMerged_whenInnerCallIsNull_throwsNPE() {
-        assertThrows(NullPointerException.class,
-                () -> mBluetoothCall.wasConferencePreviouslyMerged());
+        assertThrows(
+                NullPointerException.class, () -> mBluetoothCall.wasConferencePreviouslyMerged());
     }
 
     @Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java
index 060fdee686e..855bf0e81ec 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java
@@ -69,9 +69,7 @@ import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
-/**
- * Tests for {@link BluetoothInCallService}
- */
+/** Tests for {@link BluetoothInCallService} */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class BluetoothInCallServiceTest {
@@ -99,22 +97,17 @@ public class BluetoothInCallServiceTest {
     private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
 
     private TestableBluetoothInCallService mBluetoothInCallService;
+
     @Rule
-    public final ServiceTestRule mServiceRule
-            = ServiceTestRule.withTimeout(1, TimeUnit.SECONDS);
+    public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(1, TimeUnit.SECONDS);
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private BluetoothHeadsetProxy mMockBluetoothHeadset;
-    @Mock
-    private BluetoothLeCallControlProxy mMockBluetoothLeCallControl;
-    @Mock
-    private BluetoothInCallService.CallInfo mMockCallInfo;
-    @Mock
-    private TelephonyManager mMockTelephonyManager;
-    @Mock
-    private Context mContext = ApplicationProvider.getApplicationContext();
+    @Mock private BluetoothHeadsetProxy mMockBluetoothHeadset;
+    @Mock private BluetoothLeCallControlProxy mMockBluetoothLeCallControl;
+    @Mock private BluetoothInCallService.CallInfo mMockCallInfo;
+    @Mock private TelephonyManager mMockTelephonyManager;
+    @Mock private Context mContext = ApplicationProvider.getApplicationContext();
 
     public class TestableBluetoothInCallService extends BluetoothInCallService {
         @Override
@@ -129,8 +122,7 @@ public class BluetoothInCallServiceTest {
         }
 
         @Override
-        protected void enforceModifyPermission() {
-        }
+        protected void enforceModifyPermission() {}
 
         protected void setOnCreateCalled(boolean called) {
             mOnCreateCalled = called;
@@ -139,11 +131,14 @@ public class BluetoothInCallServiceTest {
 
     @Before
     public void setUp() throws Exception {
-        InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity();
 
         // Create the service Intent.
         Intent serviceIntent =
-                new Intent(ApplicationProvider.getApplicationContext(),
+                new Intent(
+                        ApplicationProvider.getApplicationContext(),
                         TestableBluetoothInCallService.class);
         // Bind the service
         mServiceRule.bindService(serviceIntent);
@@ -151,8 +146,7 @@ public class BluetoothInCallServiceTest {
         // Ensure initialization does not actually try to access any of the CallsManager fields.
         // This also works to return null if it is not overwritten later in the test.
         doReturn(null).when(mMockCallInfo).getActiveCall();
-        doReturn(null).when(mMockCallInfo)
-                .getRingingOrSimulatedRingingCall();
+        doReturn(null).when(mMockCallInfo).getRingingOrSimulatedRingingCall();
         doReturn(null).when(mMockCallInfo).getHeldCall();
         doReturn(null).when(mMockCallInfo).getOutgoingCall();
         doReturn(0).when(mMockCallInfo).getNumHeldCalls();
@@ -260,8 +254,7 @@ public class BluetoothInCallServiceTest {
     public void testGetSubscriberNumberFallbackToTelephony() throws Exception {
         String fakeNumber = "8675309";
         when(mMockCallInfo.getBestPhoneAccount()).thenReturn(null);
-        when(mMockTelephonyManager.getLine1Number())
-                .thenReturn(fakeNumber);
+        when(mMockTelephonyManager.getLine1Number()).thenReturn(fakeNumber);
         mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager;
 
         String subscriberNumber = mBluetoothInCallService.getSubscriberNumber();
@@ -282,8 +275,15 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
-        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
-                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(1),
+                        eq(0),
+                        eq(0),
+                        eq(0),
+                        eq(false),
+                        eq("555000"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -304,15 +304,17 @@ public class BluetoothInCallServiceTest {
                 40, // int retransmissionCount
                 50, // int packetsNotReceiveCount
                 60 // int negativeAcknowledgementCount
-        );
+                );
 
         ArgumentCaptor bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
-        verify(activeCall).sendCallEvent(
-                eq(BluetoothCallQualityReport.EVENT_BLUETOOTH_CALL_QUALITY_REPORT),
-                bundleCaptor.capture());
+        verify(activeCall)
+                .sendCallEvent(
+                        eq(BluetoothCallQualityReport.EVENT_BLUETOOTH_CALL_QUALITY_REPORT),
+                        bundleCaptor.capture());
         Bundle bundle = bundleCaptor.getValue();
-        BluetoothCallQualityReport report = (BluetoothCallQualityReport) bundle.get(
-                BluetoothCallQualityReport.EXTRA_BLUETOOTH_CALL_QUALITY_REPORT);
+        BluetoothCallQualityReport report =
+                (BluetoothCallQualityReport)
+                        bundle.get(BluetoothCallQualityReport.EXTRA_BLUETOOTH_CALL_QUALITY_REPORT);
         Assert.assertEquals(10, report.getSentTimestampMillis());
         Assert.assertEquals(20, report.getRssiDbm());
         Assert.assertEquals(30, report.getSnrDb());
@@ -338,8 +340,15 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
-        verify(mMockBluetoothHeadset, never()).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
-                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset, never())
+                .clccResponse(
+                        eq(1),
+                        eq(0),
+                        eq(0),
+                        eq(0),
+                        eq(false),
+                        eq("555000"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -365,46 +374,49 @@ public class BluetoothInCallServiceTest {
         when(confCall2.getState()).thenReturn(Call.STATE_ACTIVE);
         when(confCall1.isIncoming()).thenReturn(false);
         when(confCall2.isIncoming()).thenReturn(true);
-        when(confCall1.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
-        when(confCall2.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
+        when(confCall1.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
+        when(confCall2.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
         addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
         addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
         Integer confCall1Id = confCall1.getId();
-        when(parentCall.getGenericConferenceActiveChildCallId())
-                .thenReturn(confCall1Id);
+        when(parentCall.getGenericConferenceActiveChildCallId()).thenReturn(confCall1Id);
         when(parentCall.isConference()).thenReturn(true);
-        List childrenIds = Arrays.asList(confCall1.getId(),
-                confCall2.getId());
+        List childrenIds = Arrays.asList(confCall1.getId(), confCall2.getId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
-        //Add links from child calls to parent
+        // Add links from child calls to parent
         Integer parentId = parentCall.getId();
         when(confCall1.getParentId()).thenReturn(parentId);
         when(confCall2.getParentId()).thenReturn(parentId);
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.queryPhoneState();
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
 
         when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
         List children =
                 mBluetoothInCallService.getBluetoothCallsByIds(parentCall.getChildrenIds());
-        mBluetoothInCallService.getCallback(parentCall)
-                .onChildrenChanged(parentCall, children);
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        mBluetoothInCallService.getCallback(parentCall).onChildrenChanged(parentCall, children);
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
 
         when(mMockCallInfo.getHeldCall()).thenReturn(null);
         // Spurious BluetoothCall to onIsConferencedChanged.
-        mBluetoothInCallService.getCallback(parentCall)
-                .onChildrenChanged(parentCall, children);
+        mBluetoothInCallService.getCallback(parentCall).onChildrenChanged(parentCall, children);
         // Make sure the BluetoothCall has only occurred collectively 2 times (not on the third)
-        verify(mMockBluetoothHeadset, times(2)).phoneStateChanged(any(int.class),
-                any(int.class), any(int.class), nullable(String.class), any(int.class),
-                nullable(String.class));
+        verify(mMockBluetoothHeadset, times(2))
+                .phoneStateChanged(
+                        any(int.class),
+                        any(int.class),
+                        any(int.class),
+                        nullable(String.class),
+                        any(int.class),
+                        nullable(String.class));
     }
 
     @Test
@@ -429,10 +441,10 @@ public class BluetoothInCallServiceTest {
         when(heldCall.getState()).thenReturn(Call.STATE_ACTIVE);
         when(foregroundCall.isIncoming()).thenReturn(false);
         when(heldCall.isIncoming()).thenReturn(true);
-        when(foregroundCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
-        when(heldCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0002")));
+        when(foregroundCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
+        when(heldCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0002")));
         addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
         addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
@@ -440,10 +452,9 @@ public class BluetoothInCallServiceTest {
         Integer foregroundCallId = foregroundCall.getId();
         when(parentCall.getGenericConferenceActiveChildCallId()).thenReturn(foregroundCallId);
         when(parentCall.isConference()).thenReturn(true);
-        List childrenIds = Arrays.asList(foregroundCall.getId(),
-                heldCall.getId());
+        List childrenIds = Arrays.asList(foregroundCall.getId(), heldCall.getId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
-        //Add links from child calls to parent
+        // Add links from child calls to parent
         Integer parentId = parentCall.getId();
         when(foregroundCall.getParentId()).thenReturn(parentId);
         when(heldCall.getParentId()).thenReturn(parentId);
@@ -452,10 +463,24 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
-        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
-                eq(false), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
-        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
-                eq(false), eq("5550002"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(1),
+                        eq(0),
+                        eq(CALL_STATE_ACTIVE),
+                        eq(0),
+                        eq(false),
+                        eq("5550001"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(2),
+                        eq(1),
+                        eq(CALL_STATE_HELD),
+                        eq(0),
+                        eq(false),
+                        eq("5550002"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -481,19 +506,18 @@ public class BluetoothInCallServiceTest {
         when(confCall2.getState()).thenReturn(Call.STATE_ACTIVE);
         when(confCall1.isIncoming()).thenReturn(false);
         when(confCall2.isIncoming()).thenReturn(true);
-        when(confCall1.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
-        when(confCall2.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
+        when(confCall1.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
+        when(confCall2.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
         removeCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
         when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
-        //when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
+        // when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
         when(parentCall.isConference()).thenReturn(true);
-        List childrenIds = Arrays.asList(confCall1.getId(),
-                confCall2.getId());
+        List childrenIds = Arrays.asList(confCall1.getId(), confCall2.getId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
-        //Add links from child calls to parent
+        // Add links from child calls to parent
         Integer parentId = parentCall.getId();
         when(confCall1.getParentId()).thenReturn(parentId);
         when(confCall2.getParentId()).thenReturn(parentId);
@@ -502,10 +526,24 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
-        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
-                eq(true), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
-        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
-                eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(1),
+                        eq(0),
+                        eq(CALL_STATE_ACTIVE),
+                        eq(0),
+                        eq(true),
+                        eq("5550000"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(2),
+                        eq(1),
+                        eq(CALL_STATE_ACTIVE),
+                        eq(0),
+                        eq(true),
+                        eq("5550001"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -521,19 +559,33 @@ public class BluetoothInCallServiceTest {
         mBluetoothInCallService.onCallAdded(waitingCall);
 
         when(waitingCall.isIncoming()).thenReturn(true);
-        when(waitingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
+        when(waitingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
         when(waitingCall.getState()).thenReturn(Call.STATE_RINGING);
         when(waitingCall.isConference()).thenReturn(false);
         when(waitingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_WAITING, 0, false,
-                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        1,
+                        1,
+                        CALL_STATE_WAITING,
+                        0,
+                        false,
+                        "5550000",
+                        PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
-        verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+        verify(mMockBluetoothHeadset, times(2))
+                .clccResponse(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyBoolean(),
+                        nullable(String.class),
+                        anyInt());
     }
 
     @Test
@@ -550,8 +602,15 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
-        verify(mMockBluetoothHeadset, times(1)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+        verify(mMockBluetoothHeadset, times(1))
+                .clccResponse(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyBoolean(),
+                        nullable(String.class),
+                        anyInt());
     }
 
     @Test
@@ -613,16 +672,30 @@ public class BluetoothInCallServiceTest {
         when(ringingCall.isIncoming()).thenReturn(true);
         when(ringingCall.isConference()).thenReturn(false);
         when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
-        when(ringingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
+        when(ringingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
-                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        1,
+                        1,
+                        CALL_STATE_INCOMING,
+                        0,
+                        false,
+                        "5550000",
+                        PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
-        verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+        verify(mMockBluetoothHeadset, times(2))
+                .clccResponse(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyBoolean(),
+                        nullable(String.class),
+                        anyInt());
     }
 
     @Test
@@ -637,13 +710,20 @@ public class BluetoothInCallServiceTest {
         when(ringingCall.isIncoming()).thenReturn(true);
         when(ringingCall.isConference()).thenReturn(false);
         when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
-        when(ringingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:5550000")));
+        when(ringingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:5550000")));
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
-                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        1,
+                        1,
+                        CALL_STATE_INCOMING,
+                        0,
+                        false,
+                        "5550000",
+                        PhoneNumberUtils.TOA_Unknown);
 
         // Test Caching of old BluetoothCall indices in clcc
         when(ringingCall.getState()).thenReturn(Call.STATE_ACTIVE);
@@ -655,14 +735,16 @@ public class BluetoothInCallServiceTest {
         when(newHoldingCall.isIncoming()).thenReturn(true);
         when(newHoldingCall.isConference()).thenReturn(false);
         when(newHoldingCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
-        when(newHoldingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
+        when(newHoldingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
 
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_ACTIVE, 0, false,
-                "5550000", PhoneNumberUtils.TOA_Unknown);
-        verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
-                "5550001", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        1, 1, CALL_STATE_ACTIVE, 0, false, "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        2, 1, CALL_STATE_HELD, 0, false, "5550001", PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset, times(2)).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -678,16 +760,30 @@ public class BluetoothInCallServiceTest {
         when(dialingCall.isIncoming()).thenReturn(false);
         when(dialingCall.isConference()).thenReturn(false);
         when(dialingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
-        when(dialingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
+        when(dialingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
-                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        1,
+                        0,
+                        CALL_STATE_ALERTING,
+                        0,
+                        false,
+                        "5550000",
+                        PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
-        verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+        verify(mMockBluetoothHeadset, times(2))
+                .clccResponse(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyBoolean(),
+                        nullable(String.class),
+                        anyInt());
     }
 
     @Test
@@ -702,8 +798,8 @@ public class BluetoothInCallServiceTest {
         when(dialingCall.isIncoming()).thenReturn(false);
         when(dialingCall.isConference()).thenReturn(false);
         when(dialingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
-        when(dialingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
+        when(dialingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
         BluetoothCall holdingCall = createHeldCall(UUID.randomUUID());
         calls.add(holdingCall);
         mBluetoothInCallService.onCallAdded(holdingCall);
@@ -712,18 +808,33 @@ public class BluetoothInCallServiceTest {
         when(holdingCall.isIncoming()).thenReturn(true);
         when(holdingCall.isConference()).thenReturn(false);
         when(holdingCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
-        when(holdingCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
+        when(holdingCall.getGatewayInfo())
+                .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
-                "5550000", PhoneNumberUtils.TOA_Unknown);
-        verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
-                "5550001", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        1,
+                        0,
+                        CALL_STATE_ALERTING,
+                        0,
+                        false,
+                        "5550000",
+                        PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        2, 1, CALL_STATE_HELD, 0, false, "5550001", PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
-        verify(mMockBluetoothHeadset, times(3)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+        verify(mMockBluetoothHeadset, times(3))
+                .clccResponse(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyBoolean(),
+                        nullable(String.class),
+                        anyInt());
     }
 
     @Test
@@ -744,8 +855,15 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
-        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
-                eq(true), eq("5550000"), eq(129));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(1),
+                        eq(1),
+                        eq(CALL_STATE_ACTIVE),
+                        eq(0),
+                        eq(true),
+                        eq("5550000"),
+                        eq(129));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -770,8 +888,7 @@ public class BluetoothInCallServiceTest {
         Integer parentId = parentCall.getId();
         when(childCall1.getParentId()).thenReturn(parentId);
         when(childCall2.getParentId()).thenReturn(parentId);
-        List childrenIds = Arrays.asList(childCall1.getId(),
-                childCall2.getId());
+        List childrenIds = Arrays.asList(childCall1.getId(), childCall2.getId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
 
         when(parentCall.isConference()).thenReturn(true);
@@ -785,10 +902,24 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
-        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_HELD), eq(0),
-                eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
-        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(0), eq(CALL_STATE_HELD), eq(0),
-                eq(true), eq("5550002"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(1),
+                        eq(0),
+                        eq(CALL_STATE_HELD),
+                        eq(0),
+                        eq(true),
+                        eq("5550001"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(
+                        eq(2),
+                        eq(0),
+                        eq(CALL_STATE_HELD),
+                        eq(0),
+                        eq(true),
+                        eq("5550002"),
+                        eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -812,8 +943,8 @@ public class BluetoothInCallServiceTest {
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
-        verify(mMockBluetoothHeadset).clccResponse(
-                eq(1), eq(1), eq(0), eq(0), eq(true), eq("5551234"), eq(129));
+        verify(mMockBluetoothHeadset)
+                .clccResponse(eq(1), eq(1), eq(0), eq(0), eq(true), eq("5551234"), eq(129));
     }
 
     @Test
@@ -961,8 +1092,14 @@ public class BluetoothInCallServiceTest {
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.queryPhoneState();
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
-                eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_INCOMING),
+                        eq("5550000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
     }
 
     @Test
@@ -977,14 +1114,14 @@ public class BluetoothInCallServiceTest {
         removeCallCapability(parentConfCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
         when(parentConfCall.wasConferencePreviouslyMerged()).thenReturn(true);
         when(parentConfCall.isConference()).thenReturn(true);
-        List childrenIds = Arrays.asList(confCall1.getId(),
-                confCall2.getId());
+        List childrenIds = Arrays.asList(confCall1.getId(), confCall2.getId());
         when(parentConfCall.getChildrenIds()).thenReturn(childrenIds);
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.queryPhoneState();
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1012,8 +1149,8 @@ public class BluetoothInCallServiceTest {
         BluetoothCall activeCall = createActiveCall(UUID.randomUUID());
         BluetoothCall ringingCall = createRingingCall(UUID.randomUUID());
 
-        boolean didProcess = mBluetoothInCallService.processChld(
-                CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
+        boolean didProcess =
+                mBluetoothInCallService.processChld(CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
 
         verify(activeCall).disconnect();
         verify(ringingCall).answer(any(int.class));
@@ -1025,8 +1162,8 @@ public class BluetoothInCallServiceTest {
         BluetoothCall activeCall = createActiveCall(UUID.randomUUID());
         BluetoothCall heldCall = createHeldCall(UUID.randomUUID());
 
-        boolean didProcess = mBluetoothInCallService.processChld(
-                CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
+        boolean didProcess =
+                mBluetoothInCallService.processChld(CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
 
         verify(activeCall).disconnect();
         // BluetoothCall unhold will occur as part of CallsManager auto-unholding
@@ -1038,8 +1175,7 @@ public class BluetoothInCallServiceTest {
     public void testProcessChldHoldActiveRinging() throws Exception {
         BluetoothCall ringingCall = createRingingCall(UUID.randomUUID());
 
-        boolean didProcess = mBluetoothInCallService.processChld(
-                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+        boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
 
         verify(ringingCall).answer(any(int.class));
         Assert.assertTrue(didProcess);
@@ -1049,8 +1185,7 @@ public class BluetoothInCallServiceTest {
     public void testProcessChldHoldActiveUnhold() throws Exception {
         BluetoothCall heldCall = createHeldCall(UUID.randomUUID());
 
-        boolean didProcess = mBluetoothInCallService.processChld(
-                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+        boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
 
         verify(heldCall).unhold();
         Assert.assertTrue(didProcess);
@@ -1061,8 +1196,7 @@ public class BluetoothInCallServiceTest {
         BluetoothCall activeCall = createActiveCall(UUID.randomUUID());
         addCallCapability(activeCall, Connection.CAPABILITY_HOLD);
 
-        boolean didProcess = mBluetoothInCallService.processChld(
-                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+        boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
 
         verify(activeCall).hold();
         Assert.assertTrue(didProcess);
@@ -1110,17 +1244,16 @@ public class BluetoothInCallServiceTest {
         when(parentCall.isConference()).thenReturn(true);
         when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
         when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
-        List childrenIds = Arrays.asList(foregroundCall.getId(),
-                heldCall.getId());
+        List childrenIds = Arrays.asList(foregroundCall.getId(), heldCall.getId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
 
         clearInvocations(mMockBluetoothHeadset);
-        boolean didProcess = mBluetoothInCallService.processChld(
-                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+        boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
 
         verify(parentCall).swapConference();
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""),
-                eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
         Assert.assertTrue(didProcess);
     }
 
@@ -1132,8 +1265,14 @@ public class BluetoothInCallServiceTest {
 
         mBluetoothInCallService.onCallAdded(ringingCall);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
-                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_INCOMING),
+                        eq("555000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
     }
 
     @Test
@@ -1144,8 +1283,14 @@ public class BluetoothInCallServiceTest {
 
         mBluetoothInCallService.onCallAdded(ringingCall);
 
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
     }
 
     @Test
@@ -1159,14 +1304,14 @@ public class BluetoothInCallServiceTest {
         addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
         when(parentCall.isConference()).thenReturn(true);
-        List childrenIds = Arrays.asList(foregroundCall.getId(),
-                heldCall.getId());
+        List childrenIds = Arrays.asList(foregroundCall.getId(), heldCall.getId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
 
         mBluetoothInCallService.onCallAdded(parentCall);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1178,8 +1323,9 @@ public class BluetoothInCallServiceTest {
 
         mBluetoothInCallService.onCallRemoved(activeCall, true /* forceRemoveCallback */);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1192,8 +1338,9 @@ public class BluetoothInCallServiceTest {
         when(activeCall.isExternalCall()).thenReturn(true);
         mBluetoothInCallService.getCallback(activeCall).onDetailsChanged(activeCall, null);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1201,8 +1348,8 @@ public class BluetoothInCallServiceTest {
         BluetoothCall activeCall = createActiveCall(UUID.randomUUID());
         mBluetoothInCallService.onCallAdded(activeCall);
         when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
-        BluetoothInCallService.CallStateCallback callBack = mBluetoothInCallService.getCallback(
-                activeCall);
+        BluetoothInCallService.CallStateCallback callBack =
+                mBluetoothInCallService.getCallback(activeCall);
 
         when(activeCall.isExternalCall()).thenReturn(true);
         callBack.onDetailsChanged(activeCall, null);
@@ -1210,8 +1357,9 @@ public class BluetoothInCallServiceTest {
         when(activeCall.isExternalCall()).thenReturn(false);
         callBack.onDetailsChanged(activeCall, null);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1226,11 +1374,18 @@ public class BluetoothInCallServiceTest {
         mBluetoothInCallService.onCallAdded(activeCall);
         when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
 
-        mBluetoothInCallService.getCallback(activeCall)
+        mBluetoothInCallService
+                .getCallback(activeCall)
                 .onStateChanged(activeCall, Call.STATE_HOLDING);
 
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
     }
 
     @Test
@@ -1239,8 +1394,14 @@ public class BluetoothInCallServiceTest {
         when(call.getState()).thenReturn(Call.STATE_AUDIO_PROCESSING);
         mBluetoothInCallService.onCallAdded(call);
 
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
     }
 
     @Test
@@ -1250,17 +1411,25 @@ public class BluetoothInCallServiceTest {
 
         mBluetoothInCallService.onCallAdded(ringingCall);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
-                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_INCOMING),
+                        eq("555000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
 
         when(ringingCall.getState()).thenReturn(Call.STATE_AUDIO_PROCESSING);
         when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(null);
 
-        mBluetoothInCallService.getCallback(ringingCall)
+        mBluetoothInCallService
+                .getCallback(ringingCall)
                 .onStateChanged(ringingCall, Call.STATE_AUDIO_PROCESSING);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1268,11 +1437,18 @@ public class BluetoothInCallServiceTest {
         BluetoothCall ringingCall = createRingingCall(UUID.randomUUID());
         when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         mBluetoothInCallService.onCallAdded(ringingCall);
-        mBluetoothInCallService.getCallback(ringingCall)
+        mBluetoothInCallService
+                .getCallback(ringingCall)
                 .onStateChanged(ringingCall, Call.STATE_SIMULATED_RINGING);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
-                eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_INCOMING),
+                        eq("555-0000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
     }
 
     @Test
@@ -1280,11 +1456,13 @@ public class BluetoothInCallServiceTest {
         BluetoothCall activeCall = createActiveCall(UUID.randomUUID());
         when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE);
         mBluetoothInCallService.onCallAdded(activeCall);
-        mBluetoothInCallService.getCallback(activeCall)
+        mBluetoothInCallService
+                .getCallback(activeCall)
                 .onStateChanged(activeCall, Call.STATE_ACTIVE);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1294,27 +1472,47 @@ public class BluetoothInCallServiceTest {
         // make "mLastState" STATE_CONNECTING
         BluetoothInCallService.CallStateCallback callback =
                 mBluetoothInCallService.new CallStateCallback(Call.STATE_CONNECTING);
-        mBluetoothInCallService.mCallbacks.put(
-                activeCall.getId(), callback);
+        mBluetoothInCallService.mCallbacks.put(activeCall.getId(), callback);
 
-        mBluetoothInCallService.mCallbacks.get(activeCall.getId())
+        mBluetoothInCallService
+                .mCallbacks
+                .get(activeCall.getId())
                 .onStateChanged(activeCall, Call.STATE_DIALING);
 
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
     }
 
     @Test
     public void testOnCallStateChangedAlerting() throws Exception {
         BluetoothCall outgoingCall = createOutgoingCall(UUID.randomUUID());
         mBluetoothInCallService.onCallAdded(outgoingCall);
-        mBluetoothInCallService.getCallback(outgoingCall)
+        mBluetoothInCallService
+                .getCallback(outgoingCall)
                 .onStateChanged(outgoingCall, Call.STATE_DIALING);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DIALING),
-                eq(""), eq(128), nullable(String.class));
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_ALERTING),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_DIALING),
+                        eq(""),
+                        eq(128),
+                        nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_ALERTING),
+                        eq(""),
+                        eq(128),
+                        nullable(String.class));
     }
 
     @Test
@@ -1322,10 +1520,17 @@ public class BluetoothInCallServiceTest {
         BluetoothCall disconnectedCall = createDisconnectedCall(UUID.randomUUID());
         doReturn(true).when(mMockCallInfo).hasOnlyDisconnectedCalls();
         mBluetoothInCallService.onCallAdded(disconnectedCall);
-        mBluetoothInCallService.getCallback(disconnectedCall)
+        mBluetoothInCallService
+                .getCallback(disconnectedCall)
                 .onStateChanged(disconnectedCall, Call.STATE_DISCONNECTED);
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_DISCONNECTED),
+                        eq(""),
+                        eq(128),
+                        nullable(String.class));
     }
 
     @Test
@@ -1334,18 +1539,26 @@ public class BluetoothInCallServiceTest {
         when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         mBluetoothInCallService.onCallAdded(ringingCall);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
-                eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
-
-        //Switch to active
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_INCOMING),
+                        eq("555-0000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
+
+        // Switch to active
         doReturn(null).when(mMockCallInfo).getRingingOrSimulatedRingingCall();
         when(mMockCallInfo.getActiveCall()).thenReturn(ringingCall);
 
-        mBluetoothInCallService.getCallback(ringingCall)
+        mBluetoothInCallService
+                .getCallback(ringingCall)
                 .onStateChanged(ringingCall, Call.STATE_ACTIVE);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1356,11 +1569,16 @@ public class BluetoothInCallServiceTest {
         doReturn(2).when(mMockCallInfo).getNumHeldCalls();
 
         clearInvocations(mMockBluetoothHeadset);
-        mBluetoothInCallService.getCallback(heldCall)
-                .onStateChanged(heldCall, Call.STATE_HOLDING);
+        mBluetoothInCallService.getCallback(heldCall).onStateChanged(heldCall, Call.STATE_HOLDING);
 
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(eq(0), eq(2), eq(CALL_STATE_HELD),
-                eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        eq(0),
+                        eq(2),
+                        eq(CALL_STATE_HELD),
+                        eq("5550000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
     }
 
     @Test
@@ -1392,28 +1610,47 @@ public class BluetoothInCallServiceTest {
         // Be sure that onIsConferencedChanged rejects spurious changes during set up of
         // CDMA "conference"
         mBluetoothInCallService.getCallback(activeCall).onParentChanged(activeCall);
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
 
         mBluetoothInCallService.getCallback(heldCall).onParentChanged(heldCall);
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
 
-        mBluetoothInCallService.getCallback(parentCall)
+        mBluetoothInCallService
+                .getCallback(parentCall)
                 .onChildrenChanged(
-                        parentCall,
-                        mBluetoothInCallService.getBluetoothCallsByIds(calls));
-        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
-                anyString(), anyInt(), nullable(String.class));
+                        parentCall, mBluetoothInCallService.getBluetoothCallsByIds(calls));
+        verify(mMockBluetoothHeadset, never())
+                .phoneStateChanged(
+                        anyInt(),
+                        anyInt(),
+                        anyInt(),
+                        anyString(),
+                        anyInt(),
+                        nullable(String.class));
 
         calls.add(heldCall.getId());
         mBluetoothInCallService.onCallAdded(heldCall);
-        mBluetoothInCallService.getCallback(parentCall)
+        mBluetoothInCallService
+                .getCallback(parentCall)
                 .onChildrenChanged(
-                        parentCall,
-                        mBluetoothInCallService.getBluetoothCallsByIds(calls));
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
-                eq(""), eq(128), nullable(String.class));
+                        parentCall, mBluetoothInCallService.getBluetoothCallsByIds(calls));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class));
     }
 
     @Test
@@ -1424,22 +1661,29 @@ public class BluetoothInCallServiceTest {
         Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
         intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
         clearInvocations(mMockBluetoothHeadset);
-        mBluetoothInCallService.mBluetoothAdapterReceiver
-                = mBluetoothInCallService.new BluetoothAdapterReceiver();
-        mBluetoothInCallService.mBluetoothAdapterReceiver
-                .onReceive(mBluetoothInCallService, intent);
+        mBluetoothInCallService.mBluetoothAdapterReceiver =
+                mBluetoothInCallService.new BluetoothAdapterReceiver();
+        mBluetoothInCallService.mBluetoothAdapterReceiver.onReceive(
+                mBluetoothInCallService, intent);
 
-        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
-                eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+        verify(mMockBluetoothHeadset)
+                .phoneStateChanged(
+                        eq(0),
+                        eq(0),
+                        eq(CALL_STATE_INCOMING),
+                        eq("5550000"),
+                        eq(PhoneNumberUtils.TOA_Unknown),
+                        nullable(String.class));
     }
 
     @Test
     public void testClear() {
-        doNothing().when(mContext).unregisterReceiver(any(
-                BluetoothInCallService.BluetoothAdapterReceiver.class));
+        doNothing()
+                .when(mContext)
+                .unregisterReceiver(any(BluetoothInCallService.BluetoothAdapterReceiver.class));
         mBluetoothInCallService.attachBaseContext(mContext);
-        mBluetoothInCallService.mBluetoothAdapterReceiver
-                = mBluetoothInCallService.new BluetoothAdapterReceiver();
+        mBluetoothInCallService.mBluetoothAdapterReceiver =
+                mBluetoothInCallService.new BluetoothAdapterReceiver();
         Assert.assertNotNull(mBluetoothInCallService.mBluetoothAdapterReceiver);
         Assert.assertNotNull(mBluetoothInCallService.mBluetoothHeadset);
 
@@ -1453,54 +1697,64 @@ public class BluetoothInCallServiceTest {
     public void testGetBearerTechnology() {
         mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager;
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_GSM);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_GSM);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_GSM);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_GPRS);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_GPRS);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_2G);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_EVDO_B);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_EVDO_B);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_3G);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_TD_SCDMA);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_TD_SCDMA);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_WCDMA);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_LTE);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_LTE);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_1xRTT);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_1xRTT);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_CDMA);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_HSPAP);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_HSPAP);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_4G);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_IWLAN);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_IWLAN);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_WIFI);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_NR);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_NR);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_5G);
 
-        when(mMockTelephonyManager.getDataNetworkType()).thenReturn(
-                TelephonyManager.NETWORK_TYPE_LTE_CA);
-        Assert.assertEquals(mBluetoothInCallService.getBearerTechnology(),
+        when(mMockTelephonyManager.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_LTE_CA);
+        Assert.assertEquals(
+                mBluetoothInCallService.getBearerTechnology(),
                 BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_GSM);
     }
 
@@ -1509,45 +1763,54 @@ public class BluetoothInCallServiceTest {
         BluetoothCall call = getMockCall(UUID.randomUUID());
 
         when(call.getDisconnectCause()).thenReturn(null);
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_FAIL);
 
         DisconnectCause cause = new DisconnectCause(DisconnectCause.BUSY, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_LINE_BUSY);
 
         cause = new DisconnectCause(DisconnectCause.REJECTED, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_REMOTE_HANGUP);
 
         cause = new DisconnectCause(DisconnectCause.LOCAL, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
         mBluetoothInCallService.mIsTerminatedByClient = false;
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_SERVER_HANGUP);
 
         cause = new DisconnectCause(DisconnectCause.LOCAL, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
         mBluetoothInCallService.mIsTerminatedByClient = true;
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_CLIENT_HANGUP);
 
         cause = new DisconnectCause(DisconnectCause.ERROR, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_NETWORK_CONGESTION);
 
-        cause = new DisconnectCause(
-                DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED, null, null, null, 1);
+        cause =
+                new DisconnectCause(
+                        DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_INVALID_URI);
 
         cause = new DisconnectCause(DisconnectCause.ERROR, null, null, null, 1);
         when(call.getDisconnectCause()).thenReturn(cause);
-        Assert.assertEquals(mBluetoothInCallService.getTbsTerminationReason(call),
+        Assert.assertEquals(
+                mBluetoothInCallService.getTbsTerminationReason(call),
                 BluetoothLeCallControl.TERMINATION_REASON_NETWORK_CONGESTION);
     }
 
@@ -1586,8 +1849,8 @@ public class BluetoothInCallServiceTest {
         UUID unknownCallId = UUID.randomUUID();
         callback.onAcceptCall(requestId, unknownCallId);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
+        verify(callControlProxy)
+                .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
     }
 
     @Test
@@ -1601,8 +1864,8 @@ public class BluetoothInCallServiceTest {
         UUID unknownCallId = UUID.randomUUID();
         callback.onTerminateCall(requestId, unknownCallId);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
+        verify(callControlProxy)
+                .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
     }
 
     @Test
@@ -1616,8 +1879,8 @@ public class BluetoothInCallServiceTest {
         UUID unknownCallId = UUID.randomUUID();
         callback.onHoldCall(requestId, unknownCallId);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
+        verify(callControlProxy)
+                .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
     }
 
     @Test
@@ -1631,8 +1894,8 @@ public class BluetoothInCallServiceTest {
         UUID unknownCallId = UUID.randomUUID();
         callback.onUnholdCall(requestId, unknownCallId);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
+        verify(callControlProxy)
+                .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID);
     }
 
     @Test
@@ -1646,8 +1909,8 @@ public class BluetoothInCallServiceTest {
         UUID baseCallId = UUID.randomUUID();
         UUID firstJoiningCallId = UUID.randomUUID();
         UUID secondJoiningCallId = UUID.randomUUID();
-        List uuids = new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId,
-                secondJoiningCallId));
+        List uuids =
+                new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId, secondJoiningCallId));
         ArrayList calls = new ArrayList<>();
         BluetoothCall baseCall = createActiveCall(baseCallId);
         BluetoothCall firstCall = createRingingCall(firstJoiningCallId);
@@ -1672,8 +1935,7 @@ public class BluetoothInCallServiceTest {
 
         callback.onJoinCalls(requestId, uuids);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_SUCCESS);
+        verify(callControlProxy).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS);
         verify(baseCall, times(2)).conference(any(BluetoothCall.class));
     }
 
@@ -1687,8 +1949,8 @@ public class BluetoothInCallServiceTest {
         int requestId = 1;
         UUID baseCallId = UUID.randomUUID();
         UUID firstJoiningCallId = UUID.randomUUID();
-        List uuids = new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId,
-                firstJoiningCallId));
+        List uuids =
+                new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId, firstJoiningCallId));
         ArrayList calls = new ArrayList<>();
         BluetoothCall baseCall = createActiveCall(baseCallId);
         BluetoothCall firstCall = createRingingCall(firstJoiningCallId);
@@ -1707,8 +1969,7 @@ public class BluetoothInCallServiceTest {
 
         callback.onJoinCalls(requestId, uuids);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_SUCCESS);
+        verify(callControlProxy).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS);
         verify(baseCall, times(1)).conference(any(BluetoothCall.class));
     }
 
@@ -1723,8 +1984,8 @@ public class BluetoothInCallServiceTest {
         UUID baseCallId = UUID.randomUUID();
         UUID firstJoiningCallId = UUID.randomUUID();
         UUID secondJoiningCallId = UUID.randomUUID();
-        List uuids = new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId,
-                secondJoiningCallId));
+        List uuids =
+                new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId, secondJoiningCallId));
         ArrayList calls = new ArrayList<>();
         BluetoothCall baseCall = createActiveCall(baseCallId);
         BluetoothCall firstCall = createRingingCall(firstJoiningCallId);
@@ -1749,8 +2010,7 @@ public class BluetoothInCallServiceTest {
 
         callback.onJoinCalls(requestId, uuids);
 
-        verify(callControlProxy).requestResult(
-                requestId, BluetoothLeCallControl.RESULT_SUCCESS);
+        verify(callControlProxy).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS);
         verify(firstCall, times(1)).conference(any(BluetoothCall.class));
     }
 
@@ -1800,13 +2060,14 @@ public class BluetoothInCallServiceTest {
     }
 
     private static ComponentName makeQuickConnectionServiceComponentName() {
-        return new ComponentName("com.android.server.telecom.tests",
+        return new ComponentName(
+                "com.android.server.telecom.tests",
                 "com.android.server.telecom.tests.MockConnectionService");
     }
 
     private static PhoneAccountHandle makeQuickAccountHandle(String id) {
-        return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id,
-                Binder.getCallingUserHandle());
+        return new PhoneAccountHandle(
+                makeQuickConnectionServiceComponentName(), id, Binder.getCallingUserHandle());
     }
 
     private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java
index 102389c3640..a1796a4d127 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java
@@ -57,8 +57,7 @@ public class CallInfoTest {
 
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private TelecomManager mMockTelecomManager;
+    @Mock private TelecomManager mMockTelecomManager;
 
     private BluetoothInCallService mBluetoothInCallService;
     private BluetoothInCallService.CallInfo mMockCallInfo;
@@ -269,8 +268,8 @@ public class CallInfoTest {
         List handles = new ArrayList<>();
         PhoneAccountHandle testHandle = makeQuickAccountHandle(testId);
         handles.add(testHandle);
-        when(mMockTelecomManager.getPhoneAccountsSupportingScheme(
-                PhoneAccount.SCHEME_TEL)).thenReturn(handles);
+        when(mMockTelecomManager.getPhoneAccountsSupportingScheme(PhoneAccount.SCHEME_TEL))
+                .thenReturn(handles);
 
         PhoneAccount fakePhoneAccount = makeQuickAccount(testId, TEST_ACCOUNT_INDEX);
         when(mMockTelecomManager.getPhoneAccount(testHandle)).thenReturn(fakePhoneAccount);
@@ -280,13 +279,14 @@ public class CallInfoTest {
     }
 
     private static ComponentName makeQuickConnectionServiceComponentName() {
-        return new ComponentName("com.placeholder.connectionservice.package.name",
+        return new ComponentName(
+                "com.placeholder.connectionservice.package.name",
                 "com.placeholder.connectionservice.class.name");
     }
 
     private static PhoneAccountHandle makeQuickAccountHandle(String id) {
-        return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id,
-                Process.myUserHandle());
+        return new PhoneAccountHandle(
+                makeQuickConnectionServiceComponentName(), id, Process.myUserHandle());
     }
 
     private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
@@ -306,4 +306,4 @@ public class CallInfoTest {
     private BluetoothCall getMockCall() {
         return mock(BluetoothCall.class);
     }
-}
\ No newline at end of file
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/util/GsmAlphabetTest.java b/android/app/tests/unit/src/com/android/bluetooth/util/GsmAlphabetTest.java
index 8d271e851df..1cc1a925133 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/util/GsmAlphabetTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/util/GsmAlphabetTest.java
@@ -30,159 +30,180 @@ import org.junit.runners.JUnit4;
 @RunWith(JUnit4.class)
 public final class GsmAlphabetTest {
 
-  private static final String GSM_EXTENDED_CHARS = "{|}\\[~]\f\u20ac";
-
-  @Before
-  public void setUp() throws Exception {
-    InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
-  }
-
-  @Test
-  public void gsm7BitPackedToString() throws Exception {
-    byte[] packed;
-    StringBuilder testString = new StringBuilder(300);
-
-    packed = com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
-            testString.toString());
-    assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
-            .isEqualTo(testString.toString());
-
-    // Check all alignment cases
-    for (int i = 0; i < 9; i++, testString.append('@')) {
-      packed = com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
-              testString.toString());
-      assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
-              .isEqualTo(testString.toString());
+    private static final String GSM_EXTENDED_CHARS = "{|}\\[~]\f\u20ac";
+
+    @Before
+    public void setUp() throws Exception {
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity();
+    }
+
+    @Test
+    public void gsm7BitPackedToString() throws Exception {
+        byte[] packed;
+        StringBuilder testString = new StringBuilder(300);
+
+        packed =
+                com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
+                        testString.toString());
+        assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
+                .isEqualTo(testString.toString());
+
+        // Check all alignment cases
+        for (int i = 0; i < 9; i++, testString.append('@')) {
+            packed =
+                    com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
+                            testString.toString());
+            assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
+                    .isEqualTo(testString.toString());
+        }
+
+        // Test extended chars too
+        testString.append(GSM_EXTENDED_CHARS);
+        packed =
+                com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
+                        testString.toString());
+        assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
+                .isEqualTo(testString.toString());
+
+        // Try 254 septets with 127 extended chars
+        testString.setLength(0);
+        for (int i = 0; i < (255 / 2); i++) {
+            testString.append('{');
+        }
+        packed =
+                com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
+                        testString.toString());
+        assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
+                .isEqualTo(testString.toString());
+
+        // Reserved for extension to extension table (mapped to space)
+        packed = new byte[] {(byte) (0x1b | 0x80), 0x1b >> 1};
+        assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 0, 2, 0, 0, 0)).isEqualTo(" ");
+
+        // Unmappable (mapped to character in default alphabet table)
+        packed[0] = 0x1b;
+        packed[1] = 0x00;
+        assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 0, 2, 0, 0, 0)).isEqualTo("@");
+        packed[0] = (byte) (0x1b | 0x80);
+        packed[1] = (byte) (0x7f >> 1);
+        assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 0, 2, 0, 0, 0)).isEqualTo("\u00e0");
+    }
+
+    @Test
+    public void stringToGsm8BitPacked() throws Exception {
+        byte unpacked[];
+        unpacked = IccUtils.hexStringToBytes("566F696365204D61696C");
+        assertThat(IccUtils.bytesToHexString(GsmAlphabet.stringToGsm8BitPacked("Voice Mail")))
+                .isEqualTo(IccUtils.bytesToHexString(unpacked));
+
+        unpacked = GsmAlphabet.stringToGsm8BitPacked(GSM_EXTENDED_CHARS);
+        // two bytes for every extended char
+        assertThat(unpacked.length).isEqualTo(2 * GSM_EXTENDED_CHARS.length());
     }
 
-    // Test extended chars too
-    testString.append(GSM_EXTENDED_CHARS);
-    packed = com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
-            testString.toString());
-    assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
-            .isEqualTo(testString.toString());
-
-    // Try 254 septets with 127 extended chars
-    testString.setLength(0);
-    for (int i = 0; i < (255 / 2); i++) {
-      testString.append('{');
+    @Test
+    public void stringToGsm8BitUnpackedField() throws Exception {
+        byte unpacked[];
+        // Test truncation of unaligned extended chars
+        unpacked = new byte[3];
+        GsmAlphabet.stringToGsm8BitUnpackedField(GSM_EXTENDED_CHARS, unpacked, 0, unpacked.length);
+
+        // Should be one extended char and an 0xff at the end
+        assertThat(0xff & unpacked[2]).isEqualTo(0xff);
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, unpacked.length))
+                .isEqualTo(GSM_EXTENDED_CHARS.substring(0, 1));
+
+        // Test truncation of normal chars
+        unpacked = new byte[3];
+        GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, 0, unpacked.length);
+
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, unpacked.length))
+                .isEqualTo("abc");
+
+        // Test truncation of mixed normal and extended chars
+        unpacked = new byte[3];
+        GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked, 0, unpacked.length);
+
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, unpacked.length))
+                .isEqualTo("a{");
+
+        // Test padding after normal char
+        unpacked = new byte[3];
+        GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked, 0, unpacked.length);
+
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, unpacked.length))
+                .isEqualTo("a");
+
+        assertThat(0xff & unpacked[1]).isEqualTo(0xff);
+        assertThat(0xff & unpacked[2]).isEqualTo(0xff);
+
+        // Test malformed input -- escape char followed by end of field
+        unpacked[0] = 0;
+        unpacked[1] = 0;
+        unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE;
+
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, unpacked.length))
+                .isEqualTo("@@");
+
+        // non-zero offset
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 1, unpacked.length - 1))
+                .isEqualTo("@");
+
+        // test non-zero offset
+        unpacked[0] = 0;
+        GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, 1, unpacked.length - 1);
+
+        assertThat(unpacked[0]).isEqualTo(0);
+
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 1, unpacked.length - 1))
+                .isEqualTo("ab");
+
+        // test non-zero offset with truncated extended char
+        unpacked[0] = 0;
+
+        GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked, 1, unpacked.length - 1);
+
+        assertThat(unpacked[0]).isEqualTo(0);
+
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 1, unpacked.length - 1))
+                .isEqualTo("a");
+
+        // Reserved for extension to extension table (mapped to space)
+        unpacked[0] = 0x1b;
+        unpacked[1] = 0x1b;
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, 2))
+                .isEqualTo(" ");
+
+        // Unmappable (mapped to character in default or national locking shift table)
+        unpacked[1] = 0x00;
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, 2))
+                .isEqualTo("@");
+        unpacked[1] = 0x7f;
+        assertThat(
+                        com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
+                                unpacked, 0, 2))
+                .isEqualTo("\u00e0");
     }
-    packed = com.android.internal.telephony.GsmAlphabet.stringToGsm7BitPacked(
-            testString.toString());
-    assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0], 0, 0, 0))
-            .isEqualTo(testString.toString());
-
-    // Reserved for extension to extension table (mapped to space)
-    packed = new byte[]{(byte)(0x1b | 0x80), 0x1b >> 1};
-    assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 0, 2, 0, 0, 0)).isEqualTo(" ");
-
-    // Unmappable (mapped to character in default alphabet table)
-    packed[0] = 0x1b;
-    packed[1] = 0x00;
-    assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 0, 2, 0, 0, 0)).isEqualTo("@");
-    packed[0] = (byte)(0x1b | 0x80);
-    packed[1] = (byte)(0x7f >> 1);
-    assertThat(GsmAlphabet.gsm7BitPackedToString(packed, 0, 2, 0, 0, 0)).isEqualTo("\u00e0");
-  }
-
-  @Test
-  public void stringToGsm8BitPacked() throws Exception {
-    byte unpacked[];
-    unpacked = IccUtils.hexStringToBytes("566F696365204D61696C");
-    assertThat(IccUtils.bytesToHexString(GsmAlphabet.stringToGsm8BitPacked("Voice Mail")))
-            .isEqualTo(IccUtils.bytesToHexString(unpacked));
-
-    unpacked = GsmAlphabet.stringToGsm8BitPacked(GSM_EXTENDED_CHARS);
-    // two bytes for every extended char
-    assertThat(unpacked.length).isEqualTo(2 * GSM_EXTENDED_CHARS.length());
-  }
-
-  @Test
-  public void stringToGsm8BitUnpackedField() throws Exception {
-    byte unpacked[];
-    // Test truncation of unaligned extended chars
-    unpacked = new byte[3];
-    GsmAlphabet.stringToGsm8BitUnpackedField(GSM_EXTENDED_CHARS, unpacked,
-            0, unpacked.length);
-
-    // Should be one extended char and an 0xff at the end
-    assertThat(0xff & unpacked[2]).isEqualTo(0xff);
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, unpacked.length)).isEqualTo(GSM_EXTENDED_CHARS.substring(0, 1));
-
-    // Test truncation of normal chars
-    unpacked = new byte[3];
-    GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
-            0, unpacked.length);
-
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, unpacked.length)).isEqualTo("abc");
-
-    // Test truncation of mixed normal and extended chars
-    unpacked = new byte[3];
-    GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked,
-            0, unpacked.length);
-
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, unpacked.length)).isEqualTo("a{");
-
-    // Test padding after normal char
-    unpacked = new byte[3];
-    GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked,
-            0, unpacked.length);
-
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, unpacked.length)).isEqualTo("a");
-
-    assertThat(0xff & unpacked[1]).isEqualTo(0xff);
-    assertThat(0xff & unpacked[2]).isEqualTo(0xff);
-
-    // Test malformed input -- escape char followed by end of field
-    unpacked[0] = 0;
-    unpacked[1] = 0;
-    unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE;
-
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, unpacked.length)).isEqualTo("@@");
-
-    // non-zero offset
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 1, unpacked.length - 1)).isEqualTo("@");
-
-    // test non-zero offset
-    unpacked[0] = 0;
-    GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
-            1, unpacked.length - 1);
-
-
-    assertThat(unpacked[0]).isEqualTo(0);
-
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 1, unpacked.length - 1)).isEqualTo("ab");
-
-    // test non-zero offset with truncated extended char
-    unpacked[0] = 0;
-
-    GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked,
-            1, unpacked.length - 1);
-
-    assertThat(unpacked[0]).isEqualTo(0);
-
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 1, unpacked.length - 1)).isEqualTo("a");
-
-    // Reserved for extension to extension table (mapped to space)
-    unpacked[0] = 0x1b;
-    unpacked[1] = 0x1b;
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, 2)).isEqualTo(" ");
-
-    // Unmappable (mapped to character in default or national locking shift table)
-    unpacked[1] = 0x00;
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, 2)).isEqualTo("@");
-    unpacked[1] = 0x7f;
-    assertThat(com.android.internal.telephony.GsmAlphabet.gsm8BitUnpackedToString(
-            unpacked, 0, 2)).isEqualTo("\u00e0");
-  }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
index 7d19671151e..1ed290c8b93 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
@@ -37,8 +37,7 @@ import org.mockito.junit.MockitoRule;
 public class VolumeControlNativeInterfaceTest {
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private VolumeControlService mService;
+    @Mock private VolumeControlService mService;
 
     private VolumeControlNativeInterface mNativeInterface;
 
@@ -57,22 +56,22 @@ public class VolumeControlNativeInterfaceTest {
     @Test
     public void onConnectionStateChanged() {
         int state = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
-        byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
 
         mNativeInterface.onConnectionStateChanged(state, address);
 
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
     }
 
     @Test
     public void onVolumeStateChanged() {
         int volume = 3;
         boolean mute = false;
-        byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
         boolean isAutonomous = false;
 
         mNativeInterface.onVolumeStateChanged(volume, mute, address, isAutonomous);
@@ -80,8 +79,8 @@ public class VolumeControlNativeInterfaceTest {
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
     }
 
     @Test
@@ -96,66 +95,67 @@ public class VolumeControlNativeInterfaceTest {
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         assertThat(event.getValue().valueInt1).isEqualTo(groupId);
     }
 
     @Test
     public void onDeviceAvailable() {
         int numOfExternalOutputs = 3;
-        byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
 
         mNativeInterface.onDeviceAvailable(numOfExternalOutputs, address);
 
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_DEVICE_AVAILABLE);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_DEVICE_AVAILABLE);
     }
+
     @Test
     public void onExtAudioOutVolumeOffsetChanged() {
         int externalOutputId = 2;
         int offset = 0;
-        byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
 
         mNativeInterface.onExtAudioOutVolumeOffsetChanged(externalOutputId, offset, address);
 
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED);
     }
 
     @Test
     public void onExtAudioOutLocationChanged() {
         int externalOutputId = 2;
         int location = 100;
-        byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
 
         mNativeInterface.onExtAudioOutLocationChanged(externalOutputId, location, address);
 
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED);
     }
 
     @Test
     public void onExtAudioOutDescriptionChanged() {
         int externalOutputId = 2;
         String descr = "test-descr";
-        byte[] address = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
 
         mNativeInterface.onExtAudioOutDescriptionChanged(externalOutputId, descr, address);
 
         ArgumentCaptor event =
                 ArgumentCaptor.forClass(VolumeControlStackEvent.class);
         verify(mService).messageFromNative(event.capture());
-        assertThat(event.getValue().type).isEqualTo(
-                VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED);
+        assertThat(event.getValue().type)
+                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED);
     }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
index 2547d5ab0da..20712196893 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
@@ -113,13 +113,17 @@ public class VolumeControlServiceTest {
         mAdapter = BluetoothAdapter.getDefaultAdapter();
         mAttributionSource = mAdapter.getAttributionSource();
 
-        doReturn(MEDIA_MIN_VOL).when(mAudioManager)
+        doReturn(MEDIA_MIN_VOL)
+                .when(mAudioManager)
                 .getStreamMinVolume(eq(AudioManager.STREAM_MUSIC));
-        doReturn(MEDIA_MAX_VOL).when(mAudioManager)
+        doReturn(MEDIA_MAX_VOL)
+                .when(mAudioManager)
                 .getStreamMaxVolume(eq(AudioManager.STREAM_MUSIC));
-        doReturn(CALL_MIN_VOL).when(mAudioManager)
+        doReturn(CALL_MIN_VOL)
+                .when(mAudioManager)
                 .getStreamMinVolume(eq(AudioManager.STREAM_VOICE_CALL));
-        doReturn(CALL_MAX_VOL).when(mAudioManager)
+        doReturn(CALL_MAX_VOL)
+                .when(mAudioManager)
                 .getStreamMaxVolume(eq(AudioManager.STREAM_VOICE_CALL));
 
         VolumeControlNativeInterface.setInstance(mNativeInterface);
@@ -136,7 +140,7 @@ public class VolumeControlServiceTest {
         doReturn(mLeAudioService).when(mServiceFactory).getLeAudioService();
 
         // Override the timeout value to speed up the test
-        VolumeControlStateMachine.sConnectTimeoutMs = TIMEOUT_MS;    // 1s
+        VolumeControlStateMachine.sConnectTimeoutMs = TIMEOUT_MS; // 1s
 
         // Set up the Connection State Changed receiver
         IntentFilter filter = new IntentFilter();
@@ -152,9 +156,11 @@ public class VolumeControlServiceTest {
         mDeviceQueueMap = new HashMap<>();
         mDeviceQueueMap.put(mDevice, new LinkedBlockingQueue<>());
         mDeviceQueueMap.put(mDeviceTwo, new LinkedBlockingQueue<>());
-        doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService)
+        doReturn(BluetoothDevice.BOND_BONDED)
+                .when(mAdapterService)
                 .getBondState(any(BluetoothDevice.class));
-        doReturn(new ParcelUuid[]{BluetoothUuid.VOLUME_CONTROL}).when(mAdapterService)
+        doReturn(new ParcelUuid[] {BluetoothUuid.VOLUME_CONTROL})
+                .when(mAdapterService)
                 .getRemoteUuids(any(BluetoothDevice.class));
     }
 
@@ -176,29 +182,27 @@ public class VolumeControlServiceTest {
         @Override
         public void onReceive(Context context, Intent intent) {
             try {
-                BluetoothDevice device = intent.getParcelableExtra(
-                        BluetoothDevice.EXTRA_DEVICE);
+                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 Assert.assertNotNull(device);
                 LinkedBlockingQueue queue = mDeviceQueueMap.get(device);
                 Assert.assertNotNull(queue);
                 queue.put(intent);
             } catch (InterruptedException e) {
-                Assert.fail("Cannot add Intent to the Connection State queue: "
-                        + e.getMessage());
+                Assert.fail("Cannot add Intent to the Connection State queue: " + e.getMessage());
             }
         }
     }
 
-    private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device,
-            int newState, int prevState) {
+    private void verifyConnectionStateIntent(
+            int timeoutMs, BluetoothDevice device, int newState, int prevState) {
         Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device));
         Assert.assertNotNull(intent);
-        Assert.assertEquals(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED,
-                intent.getAction());
+        Assert.assertEquals(
+                BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED, intent.getAction());
         Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
         Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
-        Assert.assertEquals(prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
-                -1));
+        Assert.assertEquals(
+                prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1));
     }
 
     private void verifyNoConnectionStateIntent(int timeoutMs, BluetoothDevice device) {
@@ -206,17 +210,13 @@ public class VolumeControlServiceTest {
         Assert.assertNull(intent);
     }
 
-    /**
-     * Test getting VolumeControl Service: getVolumeControlService()
-     */
+    /** Test getting VolumeControl Service: getVolumeControlService() */
     @Test
     public void testGetVolumeControlService() {
         Assert.assertEquals(mService, VolumeControlService.getVolumeControlService());
     }
 
-    /**
-     * Test stop VolumeControl Service
-     */
+    /** Test stop VolumeControl Service */
     @Test
     public void testStopVolumeControlService() throws Exception {
         // Prepare: connect
@@ -232,83 +232,101 @@ public class VolumeControlServiceTest {
     @Test
     public void testGetSetPolicy() {
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
-        Assert.assertEquals("Initial device policy",
+        Assert.assertEquals(
+                "Initial device policy",
                 BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
                 mService.getConnectionPolicy(mDevice));
 
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
-        Assert.assertEquals("Setting device policy to POLICY_FORBIDDEN",
+        Assert.assertEquals(
+                "Setting device policy to POLICY_FORBIDDEN",
                 BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
                 mService.getConnectionPolicy(mDevice));
 
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
-        Assert.assertEquals("Setting device policy to POLICY_ALLOWED",
+        Assert.assertEquals(
+                "Setting device policy to POLICY_ALLOWED",
                 BluetoothProfile.CONNECTION_POLICY_ALLOWED,
                 mService.getConnectionPolicy(mDevice));
     }
 
-    /**
-     * Test if getProfileConnectionPolicy works after the service is stopped.
-     */
+    /** Test if getProfileConnectionPolicy works after the service is stopped. */
     @Test
     public void testGetPolicyAfterStopped() throws Exception {
         mService.stop();
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
         int policy = mServiceBinder.getConnectionPolicy(mDevice, mAttributionSource);
-        Assert.assertEquals("Initial device policy",
-                BluetoothProfile.CONNECTION_POLICY_UNKNOWN, policy);
+        Assert.assertEquals(
+                "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, policy);
     }
 
-    /**
-     *  Test okToConnect method using various test cases
-     */
+    /** Test okToConnect method using various test cases */
     @Test
     public void testOkToConnect() {
         int badPolicyValue = 1024;
         int badBondState = 42;
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_NONE, badPolicyValue, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDING, badPolicyValue, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true);
-        testOkToConnectCase(mDevice,
-                BluetoothDevice.BOND_BONDED, badPolicyValue, false);
-        testOkToConnectCase(mDevice,
-                badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false);
-        testOkToConnectCase(mDevice,
-                badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false);
-        testOkToConnectCase(mDevice,
-                badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false);
-        testOkToConnectCase(mDevice,
-                badBondState, badPolicyValue, false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_NONE,
+                BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
+                false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_NONE,
+                BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
+                false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_NONE,
+                BluetoothProfile.CONNECTION_POLICY_ALLOWED,
+                false);
+        testOkToConnectCase(mDevice, BluetoothDevice.BOND_NONE, badPolicyValue, false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_BONDING,
+                BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
+                false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_BONDING,
+                BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
+                false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_BONDING,
+                BluetoothProfile.CONNECTION_POLICY_ALLOWED,
+                false);
+        testOkToConnectCase(mDevice, BluetoothDevice.BOND_BONDING, badPolicyValue, false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_BONDED,
+                BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
+                true);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_BONDED,
+                BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
+                false);
+        testOkToConnectCase(
+                mDevice,
+                BluetoothDevice.BOND_BONDED,
+                BluetoothProfile.CONNECTION_POLICY_ALLOWED,
+                true);
+        testOkToConnectCase(mDevice, BluetoothDevice.BOND_BONDED, badPolicyValue, false);
+        testOkToConnectCase(
+                mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false);
+        testOkToConnectCase(
+                mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false);
+        testOkToConnectCase(
+                mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false);
+        testOkToConnectCase(mDevice, badBondState, badPolicyValue, false);
     }
 
     /**
@@ -318,35 +336,33 @@ public class VolumeControlServiceTest {
     public void testOutgoingConnectMissingVolumeControlUuid() {
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
         // Return No UUID
-        doReturn(new ParcelUuid[]{}).when(mAdapterService)
+        doReturn(new ParcelUuid[] {})
+                .when(mAdapterService)
                 .getRemoteUuids(any(BluetoothDevice.class));
 
         // Send a connect request
         Assert.assertFalse("Connect expected to fail", mService.connect(mDevice));
     }
 
-    /**
-     * Test that an outgoing connection to device that have Volume Control UUID is successful
-     */
+    /** Test that an outgoing connection to device that have Volume Control UUID is successful */
     @Test
     public void testOutgoingConnectDisconnectExistingVolumeControlUuid() throws Exception {
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
         // Return Volume Control UUID
-        doReturn(new ParcelUuid[]{BluetoothUuid.VOLUME_CONTROL}).when(mAdapterService)
+        doReturn(new ParcelUuid[] {BluetoothUuid.VOLUME_CONTROL})
+                .when(mAdapterService)
                 .getRemoteUuids(any(BluetoothDevice.class));
 
         // Send a connect request via binder
@@ -354,7 +370,10 @@ public class VolumeControlServiceTest {
                 "Connect expected to succeed", mServiceBinder.connect(mDevice, mAttributionSource));
 
         // Verify the connection state broadcast, and that we are in Connecting state
-        verifyConnectionStateIntent(TIMEOUT_MS, mDevice, BluetoothProfile.STATE_CONNECTING,
+        verifyConnectionStateIntent(
+                TIMEOUT_MS,
+                mDevice,
+                BluetoothProfile.STATE_CONNECTING,
                 BluetoothProfile.STATE_DISCONNECTED);
 
         // Send a disconnect request via binder
@@ -363,13 +382,14 @@ public class VolumeControlServiceTest {
                 mServiceBinder.disconnect(mDevice, mAttributionSource));
 
         // Verify the connection state broadcast, and that we are in Connecting state
-        verifyConnectionStateIntent(TIMEOUT_MS, mDevice, BluetoothProfile.STATE_DISCONNECTED,
+        verifyConnectionStateIntent(
+                TIMEOUT_MS,
+                mDevice,
+                BluetoothProfile.STATE_DISCONNECTED,
                 BluetoothProfile.STATE_CONNECTING);
     }
 
-    /**
-     * Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected
-     */
+    /** Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected */
     @Test
     public void testOutgoingConnectPolicyForbidden() {
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
@@ -377,23 +397,19 @@ public class VolumeControlServiceTest {
 
         // Set the device policy to POLICY_FORBIDDEN so connect() should fail
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
 
         // Send a connect request
         Assert.assertFalse("Connect expected to fail", mService.connect(mDevice));
     }
 
-    /**
-     * Test that an outgoing connection times out
-     */
+    /** Test that an outgoing connection times out */
     @Test
     public void testOutgoingConnectTimeout() throws Exception {
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
@@ -402,14 +418,19 @@ public class VolumeControlServiceTest {
         Assert.assertTrue("Connect failed", mService.connect(mDevice));
 
         // Verify the connection state broadcast, and that we are in Connecting state
-        verifyConnectionStateIntent(TIMEOUT_MS, mDevice, BluetoothProfile.STATE_CONNECTING,
+        verifyConnectionStateIntent(
+                TIMEOUT_MS,
+                mDevice,
+                BluetoothProfile.STATE_CONNECTING,
                 BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
-                mService.getConnectionState(mDevice));
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
 
         // Verify the connection state broadcast, and that we are in Disconnected state
-        verifyConnectionStateIntent(VolumeControlStateMachine.sConnectTimeoutMs * 2,
-                mDevice, BluetoothProfile.STATE_DISCONNECTED,
+        verifyConnectionStateIntent(
+                VolumeControlStateMachine.sConnectTimeoutMs * 2,
+                mDevice,
+                BluetoothProfile.STATE_DISCONNECTED,
                 BluetoothProfile.STATE_CONNECTING);
 
         int state = mServiceBinder.getConnectionState(mDevice, mAttributionSource);
@@ -424,58 +445,54 @@ public class VolumeControlServiceTest {
     public void testCreateStateMachineStackEvents() {
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
         // stack event: CONNECTION_STATE_CONNECTING - state machine should be created
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTING,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_DISCONNECTED,
-                BluetoothProfile.STATE_CONNECTING);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
         mService.bondStateChanged(mDevice, BluetoothDevice.BOND_NONE);
         Assert.assertFalse(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_CONNECTED - state machine should be created
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_DISCONNECTED,
-                BluetoothProfile.STATE_CONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
         mService.bondStateChanged(mDevice, BluetoothDevice.BOND_NONE);
         Assert.assertFalse(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_DISCONNECTING - state machine should not be created
-        generateUnexpectedConnectionMessageFromNative(mDevice,
-                BluetoothProfile.STATE_DISCONNECTING,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mService.getConnectionState(mDevice));
+        generateUnexpectedConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
         Assert.assertFalse(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_DISCONNECTED - state machine should not be created
-        generateUnexpectedConnectionMessageFromNative(mDevice,
-                BluetoothProfile.STATE_DISCONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mService.getConnectionState(mDevice));
+        generateUnexpectedConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
         Assert.assertFalse(mService.getDevices().contains(mDevice));
     }
 
@@ -487,49 +504,47 @@ public class VolumeControlServiceTest {
     public void testDeleteStateMachineDisconnectEvents() {
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
+        when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
         // stack event: CONNECTION_STATE_CONNECTING - state machine should be created
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTING,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_DISCONNECTED,
-                BluetoothProfile.STATE_CONNECTING);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_CONNECTING - state machine remains
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTING,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // device bond state marked as unbond - state machine is not removed
-        doReturn(BluetoothDevice.BOND_NONE).when(mAdapterService)
+        doReturn(BluetoothDevice.BOND_NONE)
+                .when(mAdapterService)
                 .getBondState(any(BluetoothDevice.class));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // stack event: CONNECTION_STATE_DISCONNECTED - state machine is removed
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_DISCONNECTED,
-                BluetoothProfile.STATE_CONNECTING);
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
         Assert.assertFalse(mService.getDevices().contains(mDevice));
     }
 
-    /**
-     * Test that various Volume Control stack events will broadcast related states.
-     */
+    /** Test that various Volume Control stack events will broadcast related states. */
     @Test
     public void testVolumeControlStackEvents() {
         int group_id = -1;
@@ -537,8 +552,9 @@ public class VolumeControlServiceTest {
         boolean mute = false;
 
         // Send a message to trigger volume state changed broadcast
-        VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         stackEvent.device = mDevice;
         stackEvent.valueInt1 = group_id;
         stackEvent.valueInt2 = volume;
@@ -553,23 +569,31 @@ public class VolumeControlServiceTest {
 
     void testVolumeCalculations(int streamType, int minIdx, int maxIdx) {
         // Send a message to trigger volume state changed broadcast
-        final VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        final VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         stackEvent.device = null;
-        stackEvent.valueInt1 = 1;       // groupId
-        stackEvent.valueBool1 = false;  // isMuted
-        stackEvent.valueBool2 = true;   // isAutonomous
-
-        IntStream.range(minIdx, maxIdx).forEach(idx -> {
-            // Given the reference volume index, set the LeAudio Volume
-            stackEvent.valueInt2 = getLeAudioVolume(idx,
-                            mAudioManager.getStreamMinVolume(streamType),
-                            mAudioManager.getStreamMaxVolume(streamType), streamType);
-            mService.messageFromNative(stackEvent);
-
-            // Verify that setting LeAudio Volume, sets the original volume index to Audio FW
-            verify(mAudioManager, times(1)).setStreamVolume(eq(streamType), eq(idx), anyInt());
-        });
+        stackEvent.valueInt1 = 1; // groupId
+        stackEvent.valueBool1 = false; // isMuted
+        stackEvent.valueBool2 = true; // isAutonomous
+
+        IntStream.range(minIdx, maxIdx)
+                .forEach(
+                        idx -> {
+                            // Given the reference volume index, set the LeAudio Volume
+                            stackEvent.valueInt2 =
+                                    getLeAudioVolume(
+                                            idx,
+                                            mAudioManager.getStreamMinVolume(streamType),
+                                            mAudioManager.getStreamMaxVolume(streamType),
+                                            streamType);
+                            mService.messageFromNative(stackEvent);
+
+                            // Verify that setting LeAudio Volume, sets the original volume index to
+                            // Audio FW
+                            verify(mAudioManager, times(1))
+                                    .setStreamVolume(eq(streamType), eq(idx), anyInt());
+                        });
     }
 
     @Test
@@ -585,9 +609,7 @@ public class VolumeControlServiceTest {
         testVolumeCalculations(AudioManager.STREAM_MUSIC, MEDIA_MIN_VOL, MEDIA_MAX_VOL);
     }
 
-    /**
-     * Test if autonomous Mute/Unmute propagates the event to audio manager.
-     */
+    /** Test if autonomous Mute/Unmute propagates the event to audio manager. */
     @Test
     public void testAutonomousMuteUnmute() {
         // TODO: b/329163385 - This test should be modified to run without having to set the flag to
@@ -598,36 +620,33 @@ public class VolumeControlServiceTest {
         int streamVol = getLeAudioVolume(19, MEDIA_MIN_VOL, MEDIA_MAX_VOL, streamType);
 
         // Send a message to trigger volume state changed broadcast
-        final VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        final VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         stackEvent.device = null;
-        stackEvent.valueInt1 = 1;       // groupId
+        stackEvent.valueInt1 = 1; // groupId
         stackEvent.valueInt2 = streamVol;
-        stackEvent.valueBool1 = false;  // isMuted
-        stackEvent.valueBool2 = true;   // isAutonomous
+        stackEvent.valueBool1 = false; // isMuted
+        stackEvent.valueBool2 = true; // isAutonomous
 
-        doReturn(false).when(mAudioManager)
-                .isStreamMute(eq(AudioManager.STREAM_MUSIC));
+        doReturn(false).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
 
         // Verify that muting LeAudio device, sets the mute state on the audio device
         stackEvent.valueBool1 = true;
         mService.messageFromNative(stackEvent);
-        verify(mAudioManager, times(1)).adjustStreamVolume(eq(streamType),
-                eq(AudioManager.ADJUST_MUTE), anyInt());
+        verify(mAudioManager, times(1))
+                .adjustStreamVolume(eq(streamType), eq(AudioManager.ADJUST_MUTE), anyInt());
 
-        doReturn(true).when(mAudioManager)
-                .isStreamMute(eq(AudioManager.STREAM_MUSIC));
+        doReturn(true).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
 
         // Verify that unmuting LeAudio device, unsets the mute state on the audio device
         stackEvent.valueBool1 = false;
         mService.messageFromNative(stackEvent);
-        verify(mAudioManager, times(1)).adjustStreamVolume(eq(streamType),
-                eq(AudioManager.ADJUST_UNMUTE), anyInt());
+        verify(mAudioManager, times(1))
+                .adjustStreamVolume(eq(streamType), eq(AudioManager.ADJUST_UNMUTE), anyInt());
     }
 
-    /**
-     * Test Volume Control cache.
-     */
+    /** Test Volume Control cache. */
     @Test
     public void testVolumeCache() throws Exception {
         int groupId = 1;
@@ -641,8 +660,9 @@ public class VolumeControlServiceTest {
 
         volume = 10;
         // Send autonomous volume change.
-        VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         stackEvent.device = null;
         stackEvent.valueInt1 = groupId;
         stackEvent.valueInt2 = volume;
@@ -686,9 +706,7 @@ public class VolumeControlServiceTest {
         verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedVol), anyInt());
     }
 
-    /**
-     * Test Volume Control Mute cache.
-     */
+    /** Test Volume Control Mute cache. */
     @Test
     public void testMuteCache() throws Exception {
         int groupId = 1;
@@ -697,8 +715,9 @@ public class VolumeControlServiceTest {
         Assert.assertEquals(false, mService.getGroupMute(groupId));
 
         // Send autonomous volume change
-        VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         stackEvent.device = null;
         stackEvent.valueInt1 = groupId;
         stackEvent.valueInt2 = volume;
@@ -720,9 +739,7 @@ public class VolumeControlServiceTest {
         Assert.assertEquals(false, mService.getGroupMute(groupId));
     }
 
-    /**
-     * Test Volume Control with muted stream.
-     */
+    /** Test Volume Control with muted stream. */
     @Test
     public void testVolumeChangeWhileMuted() throws Exception {
         int groupId = 1;
@@ -731,8 +748,9 @@ public class VolumeControlServiceTest {
         Assert.assertEquals(false, mService.getGroupMute(groupId));
 
         // Set the initial volume state
-        VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+        VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
         stackEvent.device = null;
         stackEvent.valueInt1 = groupId;
         stackEvent.valueInt2 = volume;
@@ -746,8 +764,7 @@ public class VolumeControlServiceTest {
         verify(mNativeInterface, times(1)).muteGroup(eq(groupId));
 
         // Make sure the volume is kept even when muted
-        doReturn(true).when(mAudioManager)
-                .isStreamMute(eq(AudioManager.STREAM_MUSIC));
+        doReturn(true).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
         Assert.assertEquals(volume, mService.getGroupVolume(groupId));
 
         // Lower the volume and keep it mute
@@ -764,8 +781,7 @@ public class VolumeControlServiceTest {
 
         // Raise the volume and unmute
         volume += 10; // avoid previous volume levels and simplify mock verification
-        doReturn(false).when(mAudioManager)
-                .isStreamMute(eq(AudioManager.STREAM_MUSIC));
+        doReturn(false).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
         mService.setGroupVolume(groupId, ++volume);
         Assert.assertEquals(false, mService.getGroupMute(groupId));
         verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(volume));
@@ -778,8 +794,8 @@ public class VolumeControlServiceTest {
     }
 
     /**
-     * Test setting volume for a group member who connects after the volume level
-     * for a group was already changed and cached.
+     * Test setting volume for a group member who connects after the volume level for a group was
+     * already changed and cached.
      */
     @Test
     public void testLateConnectingDevice() throws Exception {
@@ -792,17 +808,15 @@ public class VolumeControlServiceTest {
 
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(any(BluetoothDevice.class),
-                        eq(BluetoothProfile.VOLUME_CONTROL)))
+        when(mDatabaseManager.getProfileConnectionPolicy(
+                        any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         mService.setGroupVolume(groupId, groupVolume);
@@ -810,17 +824,17 @@ public class VolumeControlServiceTest {
         verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(groupVolume));
 
         // Verify that second device gets the proper group volume level when connected
-        generateConnectionMessageFromNative(mDeviceTwo, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDeviceTwo));
+        generateConnectionMessageFromNative(
+                mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
         Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
         verify(mNativeInterface, times(1)).setVolume(eq(mDeviceTwo), eq(groupVolume));
     }
 
     /**
-     * Test setting volume for a new group member who is discovered after the volume level
-     * for a group was already changed and cached.
+     * Test setting volume for a new group member who is discovered after the volume level for a
+     * group was already changed and cached.
      */
     @Test
     public void testLateDiscoveredGroupMember() throws Exception {
@@ -833,27 +847,25 @@ public class VolumeControlServiceTest {
 
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(any(BluetoothDevice.class),
-                        eq(BluetoothProfile.VOLUME_CONTROL)))
+        when(mDatabaseManager.getProfileConnectionPolicy(
+                        any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // Set the group volume
         mService.setGroupVolume(groupId, groupVolume);
 
         // Verify that second device will not get the group volume level if it is not a group member
-        generateConnectionMessageFromNative(mDeviceTwo, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDeviceTwo));
+        generateConnectionMessageFromNative(
+                mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
         Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
         verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(groupVolume));
 
@@ -864,10 +876,9 @@ public class VolumeControlServiceTest {
     }
 
     /**
-     * Test setting volume to 0 for a group member who connects after the volume level
-     * for a group was already changed and cached. LeAudio has no knowledge of mute
-     * for anything else than telephony, thus setting volume level to 0 is considered
-     * as muting.
+     * Test setting volume to 0 for a group member who connects after the volume level for a group
+     * was already changed and cached. LeAudio has no knowledge of mute for anything else than
+     * telephony, thus setting volume level to 0 is considered as muting.
      */
     @Test
     public void testMuteLateConnectingDevice() throws Exception {
@@ -880,17 +891,15 @@ public class VolumeControlServiceTest {
 
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(any(BluetoothDevice.class),
-                        eq(BluetoothProfile.VOLUME_CONTROL)))
+        when(mDatabaseManager.getProfileConnectionPolicy(
+                        any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // Set the initial volume and mute conditions
@@ -905,10 +914,10 @@ public class VolumeControlServiceTest {
         Assert.assertEquals(true, mService.getGroupMute(groupId));
 
         // Verify that second device gets the proper group volume level when connected
-        generateConnectionMessageFromNative(mDeviceTwo, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDeviceTwo));
+        generateConnectionMessageFromNative(
+                mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
         Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
         verify(mNativeInterface, times(1)).setVolume(eq(mDeviceTwo), eq(volume));
         // Check if new device was muted
@@ -916,10 +925,9 @@ public class VolumeControlServiceTest {
     }
 
     /**
-     * Test setting volume to 0 for a new group member who is discovered after the volume level
-     * for a group was already changed and cached. LeAudio has no knowledge of mute
-     * for anything else than telephony, thus setting volume level to 0 is considered
-     * as muting.
+     * Test setting volume to 0 for a new group member who is discovered after the volume level for
+     * a group was already changed and cached. LeAudio has no knowledge of mute for anything else
+     * than telephony, thus setting volume level to 0 is considered as muting.
      */
     @Test
     public void testMuteLateDiscoveredGroupMember() throws Exception {
@@ -932,17 +940,15 @@ public class VolumeControlServiceTest {
 
         // Update the device policy so okToConnect() returns true
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
-        when(mDatabaseManager
-                .getProfileConnectionPolicy(any(BluetoothDevice.class),
-                        eq(BluetoothProfile.VOLUME_CONTROL)))
+        when(mDatabaseManager.getProfileConnectionPolicy(
+                        any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
                 .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
         doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
 
-        generateConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDevice));
+        generateConnectionMessageFromNative(
+                mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
         Assert.assertTrue(mService.getDevices().contains(mDevice));
 
         // Set the initial volume and mute conditions
@@ -950,10 +956,10 @@ public class VolumeControlServiceTest {
         mService.setGroupVolume(groupId, volume);
 
         // Verify that second device will not get the group volume level if it is not a group member
-        generateConnectionMessageFromNative(mDeviceTwo, BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(mDeviceTwo));
+        generateConnectionMessageFromNative(
+                mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
         Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
         verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(volume));
         // Check if it was not muted
@@ -978,8 +984,11 @@ public class VolumeControlServiceTest {
         Assert.assertTrue(
                 mServiceBinder.setConnectionPolicy(
                         mDevice, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mAttributionSource));
-        verify(mDatabaseManager).setProfileConnectionPolicy(
-                mDevice, BluetoothProfile.VOLUME_CONTROL, BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
+        verify(mDatabaseManager)
+                .setProfileConnectionPolicy(
+                        mDevice,
+                        BluetoothProfile.VOLUME_CONTROL,
+                        BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
     }
 
     @Test
@@ -1410,23 +1419,28 @@ public class VolumeControlServiceTest {
         Assert.assertTrue("Connect failed", mService.connect(device));
 
         // Verify the connection state broadcast, and that we are in Connecting state
-        verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTING,
+        verifyConnectionStateIntent(
+                TIMEOUT_MS,
+                device,
+                BluetoothProfile.STATE_CONNECTING,
                 BluetoothProfile.STATE_DISCONNECTED);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
-                mService.getConnectionState(device));
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(device));
 
         // Send a message to trigger connection completed
-        connCompletedEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        connCompletedEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         connCompletedEvent.device = device;
         connCompletedEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
         mService.messageFromNative(connCompletedEvent);
 
         // Verify the connection state broadcast, and that we are in Connected state
-        verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTED,
+        verifyConnectionStateIntent(
+                TIMEOUT_MS,
+                device,
+                BluetoothProfile.STATE_CONNECTED,
                 BluetoothProfile.STATE_CONNECTING);
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
-                mService.getConnectionState(device));
+        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(device));
 
         // Verify that the device is in the list of connected devices
         List connectedDevices =
@@ -1438,8 +1452,8 @@ public class VolumeControlServiceTest {
         }
     }
 
-    private void generateConnectionMessageFromNative(BluetoothDevice device, int newConnectionState,
-            int oldConnectionState) {
+    private void generateConnectionMessageFromNative(
+            BluetoothDevice device, int newConnectionState, int oldConnectionState) {
         VolumeControlStackEvent stackEvent =
                 new VolumeControlStackEvent(
                         VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
@@ -1450,8 +1464,8 @@ public class VolumeControlServiceTest {
         verifyConnectionStateIntent(TIMEOUT_MS, device, newConnectionState, oldConnectionState);
     }
 
-    private void generateUnexpectedConnectionMessageFromNative(BluetoothDevice device,
-            int newConnectionState, int oldConnectionState) {
+    private void generateUnexpectedConnectionMessageFromNative(
+            BluetoothDevice device, int newConnectionState, int oldConnectionState) {
         VolumeControlStackEvent stackEvent =
                 new VolumeControlStackEvent(
                         VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
@@ -1509,15 +1523,15 @@ public class VolumeControlServiceTest {
     }
 
     /**
-     *  Helper function to test okToConnect() method
+     * Helper function to test okToConnect() method
      *
-     *  @param device test device
-     *  @param bondState bond state value, could be invalid
-     *  @param policy value, could be invalid
-     *  @param expected expected result from okToConnect()
+     * @param device test device
+     * @param bondState bond state value, could be invalid
+     * @param policy value, could be invalid
+     * @param expected expected result from okToConnect()
      */
-    private void testOkToConnectCase(BluetoothDevice device, int bondState, int policy,
-            boolean expected) {
+    private void testOkToConnectCase(
+            BluetoothDevice device, int bondState, int policy, boolean expected) {
         doReturn(bondState).when(mAdapterService).getBondState(device);
         when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
         when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.VOLUME_CONTROL))
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java
index 80d25bdb4f9..809742c2e37 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java
@@ -72,7 +72,9 @@ public class VolumeControlStateMachineTest {
     @Before
     public void setUp() throws Exception {
         mTargetContext = InstrumentationRegistry.getTargetContext();
-        InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity();
         TestUtils.setAdapterService(mAdapterService);
 
         mAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -83,10 +85,14 @@ public class VolumeControlStateMachineTest {
         // Set up thread and looper
         mHandlerThread = new HandlerThread("VolumeControlStateMachineTestHandlerThread");
         mHandlerThread.start();
-        mVolumeControlStateMachine = new VolumeControlStateMachine(mTestDevice,
-                mVolumeControlService, mVolumeControlNativeInterface, mHandlerThread.getLooper());
+        mVolumeControlStateMachine =
+                new VolumeControlStateMachine(
+                        mTestDevice,
+                        mVolumeControlService,
+                        mVolumeControlNativeInterface,
+                        mHandlerThread.getLooper());
         // Override the timeout value to speed up the test
-        mVolumeControlStateMachine.sConnectTimeoutMs = 1000;     // 1s
+        mVolumeControlStateMachine.sConnectTimeoutMs = 1000; // 1s
         mVolumeControlStateMachine.start();
     }
 
@@ -96,12 +102,11 @@ public class VolumeControlStateMachineTest {
         TestUtils.clearAdapterService(mAdapterService);
     }
 
-    /**
-     * Test that default state is disconnected
-     */
+    /** Test that default state is disconnected */
     @Test
     public void testDefaultDisconnectedState() {
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED,
                 mVolumeControlStateMachine.getConnectionState());
     }
 
@@ -114,9 +119,7 @@ public class VolumeControlStateMachineTest {
         doReturn(allow).when(mVolumeControlService).okToConnect(any(BluetoothDevice.class));
     }
 
-    /**
-     * Test that an incoming connection with policy forbidding connection is rejected
-     */
+    /** Test that an incoming connection with policy forbidding connection is rejected */
     @Test
     public void testIncomingPolicyReject() {
         allowConnection(false);
@@ -130,16 +133,15 @@ public class VolumeControlStateMachineTest {
         mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.STACK_EVENT, connStCh);
 
         // Verify that no connection state broadcast is executed
-        verify(mVolumeControlService, after(TIMEOUT_MS).never()).sendBroadcast(any(Intent.class),
-                anyString());
+        verify(mVolumeControlService, after(TIMEOUT_MS).never())
+                .sendBroadcast(any(Intent.class), anyString());
         // Check that we are in Disconnected state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
     }
 
-    /**
-     * Test that an incoming connection with policy allowing connection is accepted
-     */
+    /** Test that an incoming connection with policy allowing connection is accepted */
     @Test
     public void testIncomingPolicyAccept() {
         allowConnection(true);
@@ -154,82 +156,91 @@ public class VolumeControlStateMachineTest {
 
         // Verify that one connection state broadcast is executed
         ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class);
-        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
-                intentArgument1.capture(), anyString());
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
+        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
+                .sendBroadcast(intentArgument1.capture(), anyString());
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING,
                 intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
 
         // Check that we are in Connecting state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Connecting.class));
 
         // Send a message to trigger connection completed
         VolumeControlStackEvent connCompletedEvent =
-                new VolumeControlStackEvent(VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         connCompletedEvent.device = mTestDevice;
         connCompletedEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
-        mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.STACK_EVENT,
-                connCompletedEvent);
+        mVolumeControlStateMachine.sendMessage(
+                VolumeControlStateMachine.STACK_EVENT, connCompletedEvent);
 
         // Verify that the expected number of broadcasts are executed:
         // - two calls to broadcastConnectionState(): Disconnected -> Connecting -> Connected
         ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class);
-        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(2)).sendBroadcast(
-                intentArgument2.capture(), anyString());
+        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(2))
+                .sendBroadcast(intentArgument2.capture(), anyString());
         // Check that we are in Connected state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Connected.class));
     }
 
-    /**
-     * Test that an outgoing connection times out
-     */
+    /** Test that an outgoing connection times out */
     @Test
     public void testOutgoingTimeout() {
         allowConnection(true);
-        doReturn(true).when(mVolumeControlNativeInterface).connectVolumeControl(any(
-                BluetoothDevice.class));
-        doReturn(true).when(mVolumeControlNativeInterface).disconnectVolumeControl(any(
-                BluetoothDevice.class));
+        doReturn(true)
+                .when(mVolumeControlNativeInterface)
+                .connectVolumeControl(any(BluetoothDevice.class));
+        doReturn(true)
+                .when(mVolumeControlNativeInterface)
+                .disconnectVolumeControl(any(BluetoothDevice.class));
 
         // Send a connect request
         mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.CONNECT, mTestDevice);
 
         // Verify that one connection state broadcast is executed
         ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class);
-        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
-                intentArgument1.capture(),
-                anyString());
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
+        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
+                .sendBroadcast(intentArgument1.capture(), anyString());
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING,
                 intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
 
         // Check that we are in Connecting state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Connecting.class));
 
         // Verify that one connection state broadcast is executed
         ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class);
-        verify(mVolumeControlService, timeout(VolumeControlStateMachine.sConnectTimeoutMs * 2)
-                .times(2)).sendBroadcast(intentArgument2.capture(), anyString());
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
+        verify(
+                        mVolumeControlService,
+                        timeout(VolumeControlStateMachine.sConnectTimeoutMs * 2).times(2))
+                .sendBroadcast(intentArgument2.capture(), anyString());
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED,
                 intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
 
         // Check that we are in Disconnected state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
         verify(mVolumeControlNativeInterface).disconnectVolumeControl(eq(mTestDevice));
     }
 
-    /**
-     * Test that an incoming connection times out
-     */
+    /** Test that an incoming connection times out */
     @Test
     public void testIncomingTimeout() {
         allowConnection(true);
-        doReturn(true).when(mVolumeControlNativeInterface).connectVolumeControl(any(
-                BluetoothDevice.class));
-        doReturn(true).when(mVolumeControlNativeInterface).disconnectVolumeControl(any(
-                BluetoothDevice.class));
+        doReturn(true)
+                .when(mVolumeControlNativeInterface)
+                .connectVolumeControl(any(BluetoothDevice.class));
+        doReturn(true)
+                .when(mVolumeControlNativeInterface)
+                .disconnectVolumeControl(any(BluetoothDevice.class));
 
         // Inject an event for when incoming connection is requested
         VolumeControlStackEvent connStCh =
@@ -241,25 +252,30 @@ public class VolumeControlStateMachineTest {
 
         // Verify that one connection state broadcast is executed
         ArgumentCaptor intentArgument1 = ArgumentCaptor.forClass(Intent.class);
-        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
-                intentArgument1.capture(),
-                anyString());
-        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
+        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
+                .sendBroadcast(intentArgument1.capture(), anyString());
+        Assert.assertEquals(
+                BluetoothProfile.STATE_CONNECTING,
                 intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
 
         // Check that we are in Connecting state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Connecting.class));
 
         // Verify that one connection state broadcast is executed
         ArgumentCaptor intentArgument2 = ArgumentCaptor.forClass(Intent.class);
-        verify(mVolumeControlService, timeout(VolumeControlStateMachine.sConnectTimeoutMs * 2)
-                .times(2)).sendBroadcast(intentArgument2.capture(), anyString());
-        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
+        verify(
+                        mVolumeControlService,
+                        timeout(VolumeControlStateMachine.sConnectTimeoutMs * 2).times(2))
+                .sendBroadcast(intentArgument2.capture(), anyString());
+        Assert.assertEquals(
+                BluetoothProfile.STATE_DISCONNECTED,
                 intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
 
         // Check that we are in Disconnected state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
         verify(mVolumeControlNativeInterface).disconnectVolumeControl(eq(mTestDevice));
     }
@@ -267,18 +283,22 @@ public class VolumeControlStateMachineTest {
     @Test
     public void testStatesChangesWithMessages() {
         allowConnection(true);
-        doReturn(true).when(mVolumeControlNativeInterface).connectVolumeControl(any(
-                BluetoothDevice.class));
-        doReturn(true).when(mVolumeControlNativeInterface).disconnectVolumeControl(any(
-                BluetoothDevice.class));
+        doReturn(true)
+                .when(mVolumeControlNativeInterface)
+                .connectVolumeControl(any(BluetoothDevice.class));
+        doReturn(true)
+                .when(mVolumeControlNativeInterface)
+                .disconnectVolumeControl(any(BluetoothDevice.class));
 
         // Check that we are in Disconnected state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
 
         mVolumeControlStateMachine.sendMessage(mVolumeControlStateMachine.DISCONNECT);
         // Check that we are in Disconnected state
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(),
                 IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
 
         // disconnected -> connecting
@@ -291,8 +311,9 @@ public class VolumeControlStateMachineTest {
                 VolumeControlStateMachine.Disconnected.class);
 
         // disconnected -> connecting
-        VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        VolumeControlStackEvent stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTING;
         sendMessageAndVerifyTransition(
@@ -310,8 +331,9 @@ public class VolumeControlStateMachineTest {
                 mVolumeControlStateMachine.obtainMessage(mVolumeControlStateMachine.CONNECT),
                 VolumeControlStateMachine.Connecting.class);
         // connecting -> disconnecting
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING;
         sendMessageAndVerifyTransition(
@@ -319,8 +341,9 @@ public class VolumeControlStateMachineTest {
                         mVolumeControlStateMachine.STACK_EVENT, stackEvent),
                 VolumeControlStateMachine.Disconnecting.class);
         // disconnecting -> connecting
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTING;
         sendMessageAndVerifyTransition(
@@ -328,8 +351,9 @@ public class VolumeControlStateMachineTest {
                         mVolumeControlStateMachine.STACK_EVENT, stackEvent),
                 VolumeControlStateMachine.Connecting.class);
         // connecting -> connected
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
         sendMessageAndVerifyTransition(
@@ -337,8 +361,9 @@ public class VolumeControlStateMachineTest {
                         mVolumeControlStateMachine.STACK_EVENT, stackEvent),
                 VolumeControlStateMachine.Connected.class);
         // connected -> disconnecting
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING;
         sendMessageAndVerifyTransition(
@@ -351,8 +376,9 @@ public class VolumeControlStateMachineTest {
                 VolumeControlStateMachine.Disconnected.class);
 
         // disconnected -> connected
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
         sendMessageAndVerifyTransition(
@@ -361,13 +387,13 @@ public class VolumeControlStateMachineTest {
                 VolumeControlStateMachine.Connected.class);
         // connected -> disconnected
         sendMessageAndVerifyTransition(
-                mVolumeControlStateMachine.obtainMessage(
-                        mVolumeControlStateMachine.DISCONNECT),
+                mVolumeControlStateMachine.obtainMessage(mVolumeControlStateMachine.DISCONNECT),
                 VolumeControlStateMachine.Disconnecting.class);
 
         // disconnecting -> connected
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
         sendMessageAndVerifyTransition(
@@ -375,8 +401,9 @@ public class VolumeControlStateMachineTest {
                         mVolumeControlStateMachine.STACK_EVENT, stackEvent),
                 VolumeControlStateMachine.Connected.class);
         // connected -> disconnected
-        stackEvent = new VolumeControlStackEvent(
-                VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+        stackEvent =
+                new VolumeControlStackEvent(
+                        VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
         stackEvent.device = mTestDevice;
         stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED;
         sendMessageAndVerifyTransition(
@@ -389,9 +416,9 @@ public class VolumeControlStateMachineTest {
         Mockito.clearInvocations(mVolumeControlService);
         mVolumeControlStateMachine.sendMessage(msg);
         // Verify that one connection state broadcast is executed
-        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
-                any(Intent.class), anyString());
-        Assert.assertThat(mVolumeControlStateMachine.getCurrentState(),
-                IsInstanceOf.instanceOf(type));
+        verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
+                .sendBroadcast(any(Intent.class), anyString());
+        Assert.assertThat(
+                mVolumeControlStateMachine.getCurrentState(), IsInstanceOf.instanceOf(type));
     }
 }
-- 
GitLab


From fe2c86b638cc53f84c242d7a7856d6a4bc7d699d Mon Sep 17 00:00:00 2001
From: William Escande 
Date: Fri, 31 May 2024 11:55:12 -0700
Subject: [PATCH 3/3] Reformat java file in android/app

Bug: 311772251
Flag: Exempt refactor
Test: None
Change-Id: Ia8036b6c052a6595a7f70b5377c463631f857840
---
 .../mapapi/BluetoothMapContract.java          | 1163 ++++++-------
 .../mapapi/BluetoothMapEmailProvider.java     |  358 ++--
 .../mapapi/BluetoothMapIMProvider.java        |  378 +++--
 .../com/android/bluetooth/AlertActivity.java  |   21 +-
 .../bluetooth/BluetoothEventLogger.java       |    3 +-
 .../bluetooth/BluetoothMethodProxy.java       |  152 +-
 .../bluetooth/BluetoothObexTransport.java     |   50 +-
 .../com/android/bluetooth/BluetoothPrefs.java |    4 +-
 .../src/com/android/bluetooth/ChangeIds.java  |    4 +-
 .../bluetooth/IObexConnectionHandler.java     |   38 +-
 .../android/bluetooth/ObexRejectServer.java   |   39 +-
 .../android/bluetooth/ObexServerSockets.java  |  138 +-
 .../com/android/bluetooth/SignedLongLong.java |   37 +-
 .../bluetooth/a2dp/A2dpCodecConfig.java       |  162 +-
 .../bluetooth/a2dp/A2dpNativeInterface.java   |   51 +-
 .../android/bluetooth/a2dp/A2dpService.java   |  417 +++--
 .../bluetooth/a2dp/A2dpStackEvent.java        |    4 +-
 .../bluetooth/a2dp/A2dpStateMachine.java      |  314 ++--
 .../a2dpsink/A2dpSinkNativeInterface.java     |   51 +-
 .../bluetooth/a2dpsink/A2dpSinkService.java   |   98 +-
 .../a2dpsink/A2dpSinkStateMachine.java        |   44 +-
 .../a2dpsink/A2dpSinkStreamHandler.java       |  120 +-
 .../bluetooth/a2dpsink/StackEvent.java        |   10 +-
 .../audio_util/BrowsablePlayerConnector.java  |  143 +-
 .../audio_util/BrowsedPlayerWrapper.java      |  118 +-
 .../bluetooth/audio_util/GPMWrapper.java      |    4 +-
 .../bluetooth/audio_util/MediaPlayerList.java |  607 ++++---
 .../audio_util/MediaPlayerWrapper.java        |   97 +-
 .../audio_util/PlayerSettingsManager.java     |   86 +-
 .../bluetooth/audio_util/helpers/Image.java   |   60 +-
 .../audio_util/helpers/Metadata.java          |   82 +-
 .../audio_util/helpers/PlayStatus.java        |    4 +-
 .../audio_util/helpers/PlayerInfo.java        |    4 +-
 .../bluetooth/audio_util/helpers/Util.java    |   37 +-
 .../audio_util/mockable/MediaBrowser.java     |  112 +-
 .../mockable/MediaBrowserFactory.java         |   14 +-
 .../audio_util/mockable/MediaController.java  |  212 +--
 .../mockable/MediaPlayerWrapperFactory.java   |    1 -
 .../bluetooth/avrcp/AvrcpBipObexServer.java   |   77 +-
 .../bluetooth/avrcp/AvrcpCoverArtService.java |   58 +-
 .../bluetooth/avrcp/AvrcpCoverArtStorage.java |   36 +-
 .../bluetooth/avrcp/AvrcpNativeInterface.java |   57 +-
 .../bluetooth/avrcp/AvrcpTargetService.java   |   16 +-
 .../bluetooth/avrcp/AvrcpVolumeManager.java   |   79 +-
 .../avrcp/helpers/AvrcpPassthrough.java       |    2 +-
 .../bluetooth/avrcp/helpers/AvrcpVersion.java |    4 +-
 .../bluetooth/avrcp/helpers/CoverArt.java     |   56 +-
 .../avrcpcontroller/AvrcpBipClient.java       |  112 +-
 .../AvrcpControllerService.java               |  109 +-
 .../AvrcpControllerStateMachine.java          |  414 ++---
 .../avrcpcontroller/AvrcpControllerUtils.java |   16 +-
 .../avrcpcontroller/AvrcpCoverArtManager.java |  106 +-
 .../AvrcpCoverArtProvider.java                |   55 +-
 .../avrcpcontroller/AvrcpCoverArtStorage.java |   12 +-
 .../bluetooth/avrcpcontroller/AvrcpItem.java  |   58 +-
 .../avrcpcontroller/AvrcpPlayer.java          |   61 +-
 .../BluetoothMediaBrowserService.java         |  148 +-
 .../bluetooth/avrcpcontroller/BrowseTree.java |   81 +-
 .../PlayerApplicationSettings.java            |   33 +-
 .../bluetooth/avrcpcontroller/StackEvent.java |    4 +-
 .../bip/BipAttachmentFormat.java              |   45 +-
 .../avrcpcontroller/bip/BipDateTime.java      |   65 +-
 .../avrcpcontroller/bip/BipEncoding.java      |   47 +-
 .../avrcpcontroller/bip/BipImage.java         |    2 +-
 .../bip/BipImageDescriptor.java               |   47 +-
 .../avrcpcontroller/bip/BipImageFormat.java   |   93 +-
 .../bip/BipImageProperties.java               |   85 +-
 .../avrcpcontroller/bip/BipPixel.java         |   74 +-
 .../avrcpcontroller/bip/BipRequest.java       |   26 +-
 .../bip/BipTransformation.java                |   48 +-
 .../avrcpcontroller/bip/ParseException.java   |    4 +-
 .../avrcpcontroller/bip/RequestGetImage.java  |    3 +-
 .../bip/RequestGetImageProperties.java        |    7 +-
 .../android/bluetooth/bas/BatteryService.java |  138 +-
 .../bluetooth/bas/BatteryStateMachine.java    |  145 +-
 .../bluetooth/bass_client/BaseData.java       |   82 +-
 .../bass_client/BassClientService.java        |  361 ++--
 .../bass_client/BassClientStateMachine.java   |  482 +++---
 .../bluetooth/bass_client/BassConstants.java  |    7 +-
 .../bass_client/BassObjectsFactory.java       |    4 +-
 .../bluetooth/bass_client/BassUtils.java      |    6 +-
 .../BluetoothLeScannerWrapper.java            |   16 +-
 .../PeriodicAdvertisementResult.java          |   85 +-
 .../bass_client/PublicBroadcastData.java      |    4 +-
 .../btservice/ActiveDeviceManager.java        |  282 ++--
 .../bluetooth/btservice/AdapterApp.java       |    2 +-
 .../btservice/AdapterProperties.java          |  359 ++--
 .../bluetooth/btservice/AdapterState.java     |   97 +-
 .../btservice/AudioRoutingManager.java        |   68 +-
 .../btservice/BluetoothAdapterProxy.java      |    6 +-
 ...BluetoothQualityReportNativeInterface.java |   12 +-
 .../bluetooth/btservice/BondStateMachine.java |  269 +--
 .../bluetooth/btservice/CompanionManager.java |  243 +--
 .../bluetooth/btservice/DataMigration.java    |   86 +-
 .../btservice/DeviceBloomfilterGenerator.java |   10 +-
 .../btservice/DiscoveringPackage.java         |    4 +-
 .../bluetooth/btservice/InteropUtil.java      |   99 +-
 .../bluetooth/btservice/JniCallbacks.java     |   22 +-
 .../bluetooth/btservice/PhonePolicy.java      |  195 ++-
 .../bluetooth/btservice/ProfileService.java   |   30 +-
 .../bluetooth/btservice/RemoteDevices.java    |  319 ++--
 .../btservice/SilenceDeviceManager.java       |   59 +-
 .../BluetoothKeystoreNativeInterface.java     |    5 +-
 .../BluetoothKeystoreService.java             |  157 +-
 .../btservice/storage/AudioPolicyEntity.java  |    2 +
 .../storage/BluetoothDatabaseMigration.java   |  194 ++-
 .../btservice/storage/DatabaseManager.java    |  645 +++----
 .../bluetooth/btservice/storage/Metadata.java |   23 +-
 .../btservice/storage/MetadataDao.java        |   16 +-
 .../storage/ProfilePrioritiesEntity.java      |   57 +-
 .../ContentProfileErrorReportUtils.java       |    4 +-
 .../CsipSetCoordinatorNativeInterface.java    |   50 +-
 .../csip/CsipSetCoordinatorService.java       |  201 ++-
 .../csip/CsipSetCoordinatorStackEvent.java    |    4 +-
 .../csip/CsipSetCoordinatorStateMachine.java  |  180 +-
 .../bluetooth/gatt/AdvertiseHelper.java       |    5 +-
 .../bluetooth/gatt/AdvertiseManager.java      |  121 +-
 .../bluetooth/gatt/AppAdvertiseStats.java     |  307 ++--
 .../android/bluetooth/gatt/ContextMap.java    |  106 +-
 .../gatt/DistanceMeasurementManager.java      |  111 +-
 .../DistanceMeasurementNativeInterface.java   |   38 +-
 .../gatt/DistanceMeasurementTracker.java      |   18 +-
 .../android/bluetooth/gatt/FilterParams.java  |   18 +-
 .../android/bluetooth/gatt/GattDbElement.java |    4 +-
 .../bluetooth/gatt/GattDebugUtils.java        |   44 +-
 .../bluetooth/gatt/GattNativeInterface.java   |  439 ++---
 .../bluetooth/gatt/GattObjectsFactory.java    |    7 +-
 .../android/bluetooth/gatt/GattService.java   | 1258 +++++++++-----
 .../bluetooth/gatt/GattServiceConfig.java     |    4 +-
 .../com/android/bluetooth/gatt/HandleMap.java |   39 +-
 .../hap/HapClientNativeInterface.java         |   75 +-
 .../bluetooth/hap/HapClientService.java       |  393 +++--
 .../bluetooth/hap/HapClientStateMachine.java  |  212 ++-
 .../hearingaid/HearingAidNativeInterface.java |   24 +-
 .../hearingaid/HearingAidService.java         |  234 +--
 .../hearingaid/HearingAidStackEvent.java      |    4 +-
 .../hearingaid/HearingAidStateMachine.java    |  183 +-
 .../android/bluetooth/hfp/AtPhonebook.java    |  153 +-
 .../bluetooth/hfp/BluetoothCmeError.java      |    1 -
 .../bluetooth/hfp/BluetoothHeadsetProxy.java  |   20 +-
 .../hfp/HeadsetAgIndicatorEnableState.java    |   12 +-
 .../bluetooth/hfp/HeadsetCallState.java       |   46 +-
 .../bluetooth/hfp/HeadsetClccResponse.java    |   51 +-
 .../bluetooth/hfp/HeadsetDeviceState.java     |   22 +-
 .../bluetooth/hfp/HeadsetMessageObject.java   |    4 +-
 .../bluetooth/hfp/HeadsetNativeInterface.java |  196 ++-
 .../bluetooth/hfp/HeadsetObjectsFactory.java  |   18 +-
 .../bluetooth/hfp/HeadsetPhoneState.java      |   75 +-
 .../android/bluetooth/hfp/HeadsetService.java |  766 +++++----
 .../bluetooth/hfp/HeadsetStackEvent.java      |   13 +-
 .../bluetooth/hfp/HeadsetStateMachine.java    |  788 +++++----
 .../bluetooth/hfp/HeadsetSystemInterface.java |   39 +-
 .../hfpclient/HeadsetClientService.java       |  283 ++--
 .../HeadsetClientServiceInterface.java        |    5 +-
 .../hfpclient/HeadsetClientStateMachine.java  |  600 ++++---
 .../HeadsetClientStateMachineFactory.java     |   13 +-
 .../bluetooth/hfpclient/HfpClientCall.java    |   88 +-
 .../hfpclient/HfpClientConference.java        |    9 +-
 .../hfpclient/HfpClientConnection.java        |   38 +-
 .../hfpclient/HfpClientConnectionService.java |   98 +-
 .../hfpclient/HfpClientDeviceBlock.java       |   56 +-
 .../bluetooth/hfpclient/NativeInterface.java  |   83 +-
 .../bluetooth/hfpclient/StackEvent.java       |    1 -
 .../VendorCommandResponseProcessor.java       |   66 +-
 .../hid/HidDeviceNativeInterface.java         |   84 +-
 .../bluetooth/hid/HidDeviceService.java       |  223 +--
 .../android/bluetooth/hid/HidHostService.java |   54 +-
 .../le_audio/ContentControlIdKeeper.java      |   12 +-
 .../LeAudioBroadcasterNativeInterface.java    |   67 +-
 .../le_audio/LeAudioCodecConfig.java          |   14 +-
 .../le_audio/LeAudioNativeInterface.java      |   79 +-
 .../le_audio/LeAudioObjectsFactory.java       |    4 +-
 .../bluetooth/le_audio/LeAudioService.java    |  774 +++++----
 .../bluetooth/le_audio/LeAudioStackEvent.java |   33 +-
 .../le_audio/LeAudioStateMachine.java         |  161 +-
 .../le_audio/LeAudioTmapGattServer.java       |  113 +-
 .../le_scan/AdvtFilterOnFoundOnLostInfo.java  |   19 +-
 .../bluetooth/le_scan/AppScanStats.java       |  210 ++-
 .../le_scan/PeriodicScanManager.java          |   97 +-
 .../le_scan/PeriodicScanNativeInterface.java  |    4 +-
 .../android/bluetooth/le_scan/ScanClient.java |   30 +-
 .../bluetooth/le_scan/ScanFilterQueue.java    |   64 +-
 .../bluetooth/le_scan/ScanManager.java        |  274 +--
 .../le_scan/ScanNativeInterface.java          |  117 +-
 .../le_scan/TransitionalScanHelper.java       |   11 +-
 .../map/BluetoothMapAccountItem.java          |   85 +-
 .../map/BluetoothMapAccountLoader.java        |  129 +-
 .../map/BluetoothMapAppObserver.java          |   54 +-
 .../bluetooth/map/BluetoothMapAppParams.java  |  403 +++--
 .../bluetooth/map/BluetoothMapContent.java    | 1372 +++++++++------
 .../map/BluetoothMapContentObserver.java      | 1498 +++++++++++------
 .../map/BluetoothMapConvoContactElement.java  |   93 +-
 .../map/BluetoothMapConvoListing.java         |   46 +-
 .../map/BluetoothMapConvoListingElement.java  |   48 +-
 .../map/BluetoothMapFolderElement.java        |   74 +-
 .../map/BluetoothMapMasInstance.java          |  120 +-
 .../map/BluetoothMapMessageListing.java       |   61 +-
 .../BluetoothMapMessageListingElement.java    |   53 +-
 .../bluetooth/map/BluetoothMapObexServer.java |  582 ++++---
 .../bluetooth/map/BluetoothMapService.java    |  286 ++--
 .../bluetooth/map/BluetoothMapSettings.java   |   33 +-
 .../map/BluetoothMapSettingsAdapter.java      |  273 +--
 .../map/BluetoothMapSettingsDataHolder.java   |   27 +-
 .../bluetooth/map/BluetoothMapSmsPdu.java     |  241 +--
 .../bluetooth/map/BluetoothMapUtils.java      |  161 +-
 .../bluetooth/map/BluetoothMapbMessage.java   |  158 +-
 .../map/BluetoothMapbMessageEmail.java        |   34 +-
 .../map/BluetoothMapbMessageMime.java         |   76 +-
 .../map/BluetoothMapbMessageSms.java          |   57 +-
 .../bluetooth/map/BluetoothMnsObexClient.java |   72 +-
 .../com/android/bluetooth/map/MapContact.java |   30 +-
 .../bluetooth/map/MmsFileProvider.java        |   52 +-
 .../android/bluetooth/map/SmsMmsContacts.java |   70 +-
 .../bluetooth/mapclient/MapClientContent.java |  206 +--
 .../bluetooth/mapclient/MapClientService.java |  102 +-
 .../bluetooth/mapclient/MasClient.java        |   61 +-
 .../bluetooth/mapclient/MceStateMachine.java  |  416 +++--
 .../bluetooth/mapclient/MnsObexServer.java    |   46 +-
 .../bluetooth/mapclient/MnsService.java       |   30 +-
 .../bluetooth/mapclient/obex/Bmessage.java    |   17 +-
 .../mapclient/obex/BmessageBuilder.java       |    7 +-
 .../mapclient/obex/BmessageParser.java        |   17 +-
 .../mapclient/obex/BmsgTokenizer.java         |    3 +-
 .../bluetooth/mapclient/obex/EventReport.java |   28 +-
 .../bluetooth/mapclient/obex/Message.java     |   73 +-
 .../mapclient/obex/MessagesFilter.java        |    5 +-
 .../bluetooth/mapclient/obex/ObexTime.java    |   38 +-
 .../bluetooth/mapclient/obex/Request.java     |    4 +-
 .../mapclient/obex/RequestGetMessage.java     |    6 +-
 .../obex/RequestGetMessagesListing.java       |    9 +-
 ...RequestGetMessagesListingForOwnNumber.java |  121 +-
 .../mapclient/obex/RequestPushMessage.java    |    4 +-
 .../obex/RequestSetMessageStatus.java         |   17 +-
 .../RequestSetNotificationRegistration.java   |    1 -
 .../mapclient/obex/RequestSetPath.java        |    4 +-
 .../com/android/bluetooth/mcp/McpService.java |   50 +-
 .../mcp/MediaControlGattService.java          | 1299 ++++++++------
 .../mcp/MediaControlGattServiceInterface.java |   32 +-
 .../bluetooth/mcp/MediaControlProfile.java    |  133 +-
 .../mcp/MediaControlServiceCallbacks.java     |   17 +-
 .../com/android/bluetooth/mcp/MediaState.java |    4 +-
 .../com/android/bluetooth/mcp/ObjectIds.java  |    5 +-
 .../bluetooth/mcp/PlayerStateField.java       |    4 +-
 .../android/bluetooth/mcp/PlayingOrder.java   |    4 +-
 .../com/android/bluetooth/mcp/Request.java    |   70 +-
 .../android/bluetooth/mcp/SearchRequest.java  |   18 +-
 .../android/bluetooth/mcp/ServiceFeature.java |   23 +-
 .../android/bluetooth/mcp/ServiceStatus.java  |    4 +-
 .../bluetooth/mcp/SupportedPlayingOrder.java  |    4 +-
 .../bluetooth/opp/BluetoothOppBatch.java      |   36 +-
 .../opp/BluetoothOppBtEnableActivity.java     |   19 +-
 .../opp/BluetoothOppBtEnablingActivity.java   |   74 +-
 .../opp/BluetoothOppBtErrorActivity.java      |    5 +-
 .../opp/BluetoothOppHandoverReceiver.java     |   34 +-
 ...uetoothOppIncomingFileConfirmActivity.java |   96 +-
 .../opp/BluetoothOppLauncherActivity.java     |  127 +-
 .../bluetooth/opp/BluetoothOppManager.java    |  164 +-
 .../opp/BluetoothOppNotification.java         |  389 +++--
 .../opp/BluetoothOppObexClientSession.java    |   88 +-
 .../opp/BluetoothOppObexServerSession.java    |  130 +-
 .../opp/BluetoothOppObexSession.java          |   20 +-
 .../bluetooth/opp/BluetoothOppPreference.java |   13 +-
 .../bluetooth/opp/BluetoothOppProvider.java   |  180 +-
 .../opp/BluetoothOppReceiveFileInfo.java      |   37 +-
 .../bluetooth/opp/BluetoothOppReceiver.java   |   76 +-
 .../opp/BluetoothOppSendFileInfo.java         |   67 +-
 .../bluetooth/opp/BluetoothOppService.java    |  296 ++--
 .../bluetooth/opp/BluetoothOppShareInfo.java  |   29 +-
 .../bluetooth/opp/BluetoothOppTransfer.java   |  220 +--
 .../opp/BluetoothOppTransferActivity.java     |  113 +-
 .../opp/BluetoothOppTransferAdapter.java      |   22 +-
 .../opp/BluetoothOppTransferHistory.java      |  121 +-
 .../opp/BluetoothOppTransferInfo.java         |    4 +-
 .../bluetooth/opp/BluetoothOppUtility.java    |  161 +-
 .../android/bluetooth/opp/BluetoothShare.java |  341 ++--
 .../com/android/bluetooth/opp/Constants.java  |   69 +-
 .../pan/BluetoothTetheringNetworkFactory.java |  149 +-
 .../com/android/bluetooth/pan/PanService.java |  181 +-
 .../bluetooth/pbap/BluetoothPbapActivity.java |   83 +-
 .../pbap/BluetoothPbapAuthenticator.java      |    7 +-
 .../pbap/BluetoothPbapCallLogComposer.java    |  121 +-
 .../bluetooth/pbap/BluetoothPbapConfig.java   |    5 +-
 .../pbap/BluetoothPbapObexServer.java         |  504 +++---
 .../bluetooth/pbap/BluetoothPbapService.java  |  218 +--
 .../pbap/BluetoothPbapSimVcardManager.java    |  205 ++-
 .../bluetooth/pbap/BluetoothPbapUtils.java    |  113 +-
 .../pbap/BluetoothPbapVcardManager.java       |  440 +++--
 .../bluetooth/pbap/PbapStateMachine.java      |  117 +-
 .../bluetooth/pbapclient/Authenticator.java   |   15 +-
 .../BluetoothPbapObexAuthenticator.java       |   12 +-
 .../BluetoothPbapRequestPullPhoneBook.java    |    9 +-
 .../pbapclient/BluetoothPbapVcardList.java    |   10 +-
 .../pbapclient/CallLogPullRequest.java        |   41 +-
 .../PbapClientConnectionHandler.java          |   85 +-
 .../pbapclient/PbapClientService.java         |  108 +-
 .../pbapclient/PbapClientStateMachine.java    |   50 +-
 .../pbapclient/PhonebookPullRequest.java      |    4 +-
 .../bluetooth/pbapclient/PullRequest.java     |    1 -
 .../bluetooth/sap/ISapRilReceiver.java        |   24 +-
 .../com/android/bluetooth/sap/SapMessage.java |  767 +++++----
 .../android/bluetooth/sap/SapRilReceiver.java |   76 +-
 .../bluetooth/sap/SapRilReceiverHidl.java     |   74 +-
 .../com/android/bluetooth/sap/SapServer.java  |  320 ++--
 .../com/android/bluetooth/sap/SapService.java |  287 ++--
 .../com/android/bluetooth/sdp/SdpManager.java |   28 +-
 .../tbs/BluetoothGattServerProxy.java         |   42 +-
 .../tbs/BluetoothLeCallControlProxy.java      |   22 +-
 .../com/android/bluetooth/tbs/TbsCall.java    |   13 +-
 .../com/android/bluetooth/tbs/TbsGatt.java    |  864 ++++++----
 .../com/android/bluetooth/tbs/TbsGeneric.java |  442 +++--
 .../com/android/bluetooth/tbs/TbsService.java |  109 +-
 .../bluetooth/telephony/BluetoothCall.java    |   29 +-
 .../telephony/BluetoothInCallService.java     |  491 +++---
 .../bluetooth/util/DevicePolicyUtils.java     |    7 +-
 .../android/bluetooth/util/GsmAlphabet.java   |  781 +++++----
 .../android/bluetooth/util/NumberUtils.java   |   12 +-
 .../bluetooth/util/WorkSourceUtil.java        |    4 +-
 .../vc/VolumeControlNativeInterface.java      |   89 +-
 .../bluetooth/vc/VolumeControlService.java    |  230 +--
 .../bluetooth/vc/VolumeControlStackEvent.java |   18 +-
 .../vc/VolumeControlStateMachine.java         |  189 ++-
 321 files changed, 23374 insertions(+), 18062 deletions(-)

diff --git a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java
index 918aecddc5d..dd7493a1aee 100644
--- a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java
+++ b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java
@@ -56,69 +56,64 @@ import android.net.Uri;
  * permission is needed for the provider.
  */
 public final class BluetoothMapContract {
-    /**
-     * Constructor - should not be used
-     */
+    /** Constructor - should not be used */
     private BluetoothMapContract() {
-      /* class should not be instantiated */
+        /* class should not be instantiated */
     }
 
     /**
-     * Provider interface that should be used as intent-filter action in the provider section
-     * of the manifest file.
+     * Provider interface that should be used as intent-filter action in the provider section of the
+     * manifest file.
      */
     public static final String PROVIDER_INTERFACE_EMAIL =
             "android.bluetooth.action.BLUETOOTH_MAP_PROVIDER";
+
     public static final String PROVIDER_INTERFACE_IM =
             "android.bluetooth.action.BLUETOOTH_MAP_IM_PROVIDER";
+
     /**
-     * The Bluetooth Message Access profile allows a remote BT-MAP client to trigger
-     * an update of a folder for a specific e-mail account, register for reception
-     * of new messages from the server.
+     * The Bluetooth Message Access profile allows a remote BT-MAP client to trigger an update of a
+     * folder for a specific e-mail account, register for reception of new messages from the server.
      *
-     * Additionally the Bluetooth Message Access profile allows a remote BT-MAP client
-     * to push a message to a folder - e.g. outbox or draft. The Bluetooth profile
-     * implementation will place a new message in one of these existing folders through
-     * the content provider.
+     * 

Additionally the Bluetooth Message Access profile allows a remote BT-MAP client to push a + * message to a folder - e.g. outbox or draft. The Bluetooth profile implementation will place a + * new message in one of these existing folders through the content provider. * - * ContentProvider.call() is used for these purposes, and the METHOD_UPDATE_FOLDER - * method name shall trigger an update of the specified folder for a specified - * account. + *

ContentProvider.call() is used for these purposes, and the METHOD_UPDATE_FOLDER method + * name shall trigger an update of the specified folder for a specified account. * - * This shall be a non blocking call simply starting the update, and the update should - * both send and receive messages, depending on what makes sense for the specified - * folder. - * Bundle extra parameter will carry two INTEGER (long) values: - * EXTRA_UPDATE_ACCOUNT_ID containing the account_id - * EXTRA_UPDATE_FOLDER_ID containing the folder_id of the folder to update + *

This shall be a non blocking call simply starting the update, and the update should both + * send and receive messages, depending on what makes sense for the specified folder. Bundle + * extra parameter will carry two INTEGER (long) values: EXTRA_UPDATE_ACCOUNT_ID containing the + * account_id EXTRA_UPDATE_FOLDER_ID containing the folder_id of the folder to update * - * The status for send complete of messages shall be reported by updating the sent-flag - * and e.g. for outbox messages, move them to the sent folder in the message table of the - * content provider and trigger a change notification to any attached content observer. + *

The status for send complete of messages shall be reported by updating the sent-flag and + * e.g. for outbox messages, move them to the sent folder in the message table of the content + * provider and trigger a change notification to any attached content observer. */ public static final String METHOD_UPDATE_FOLDER = "UpdateFolder"; + public static final String EXTRA_UPDATE_ACCOUNT_ID = "UpdateAccountId"; public static final String EXTRA_UPDATE_FOLDER_ID = "UpdateFolderId"; /** - * The Bluetooth Message Access profile allows a remote BT-MAP Client to update - * the owners presence and chat state + * The Bluetooth Message Access profile allows a remote BT-MAP Client to update the owners + * presence and chat state * - * ContentProvider.call() is used for these purposes, and the METHOD_SET_OWNER_STATUS - * method name shall trigger a change in owner/users presence or chat properties for an - * account or conversation. + *

ContentProvider.call() is used for these purposes, and the METHOD_SET_OWNER_STATUS method + * name shall trigger a change in owner/users presence or chat properties for an account or + * conversation. * - * This shall be a non blocking call simply setting the properties, and the change should - * be sent to the remote server/users, depending on what property is changed. - * Bundle extra parameter will carry following values: - * EXTRA_ACCOUNT_ID containing the account_id - * EXTRA_PRESENCE_STATE containing the presence state of the owner account - * EXTRA_PRESENCE_STATUS containing the presence status text from the owner - * EXTRA_LAST_ACTIVE containing the last activity time stamp of the owner account - * EXTRA_CHAT_STATE containing the chat state of a specific conversation - * EXTRA_CONVERSATION_ID containing the conversation that is changed + *

This shall be a non blocking call simply setting the properties, and the change should be + * sent to the remote server/users, depending on what property is changed. Bundle extra + * parameter will carry following values: EXTRA_ACCOUNT_ID containing the account_id + * EXTRA_PRESENCE_STATE containing the presence state of the owner account EXTRA_PRESENCE_STATUS + * containing the presence status text from the owner EXTRA_LAST_ACTIVE containing the last + * activity time stamp of the owner account EXTRA_CHAT_STATE containing the chat state of a + * specific conversation EXTRA_CONVERSATION_ID containing the conversation that is changed */ public static final String METHOD_SET_OWNER_STATUS = "SetOwnerStatus"; + public static final String EXTRA_ACCOUNT_ID = "AccountId"; // Is this needed public static final String EXTRA_PRESENCE_STATE = "PresenceState"; public static final String EXTRA_PRESENCE_STATUS = "PresenceStatus"; @@ -130,73 +125,71 @@ public final class BluetoothMapContract { * The Bluetooth Message Access profile can inform the messaging application of the Bluetooth * state, whether is is turned 'on' or 'off' * - * ContentProvider.call() is used for these purposes, and the METHOD_SET_BLUETOOTH_STATE - * method name shall trigger a change in owner/users presence or chat properties for an - * account or conversation. + *

ContentProvider.call() is used for these purposes, and the METHOD_SET_BLUETOOTH_STATE + * method name shall trigger a change in owner/users presence or chat properties for an account + * or conversation. * - * This shall be a non blocking call simply setting the properties. + *

This shall be a non blocking call simply setting the properties. * - * Bundle extra parameter will carry following values: - * EXTRA_BLUETOOTH_STATE containing the state of the Bluetooth connectivity + *

Bundle extra parameter will carry following values: EXTRA_BLUETOOTH_STATE containing the + * state of the Bluetooth connectivity */ public static final String METHOD_SET_BLUETOOTH_STATE = "SetBtState"; + public static final String EXTRA_BLUETOOTH_STATE = "BluetoothState"; /** - * These column names are used as last path segment of the URI (getLastPathSegment()). - * Access to a specific row in the tables is done by using the where-clause, hence - * support for .../#id if not needed for the Email clients. - * The URI format for accessing the tables are as follows: - * content://ProviderAuthority/TABLE_ACCOUNT - * content://ProviderAuthority/account_id/TABLE_MESSAGE - * content://ProviderAuthority/account_id/TABLE_FOLDER - * content://ProviderAuthority/account_id/TABLE_CONVERSATION - * content://ProviderAuthority/account_id/TABLE_CONVOCONTACT - **/ + * These column names are used as last path segment of the URI (getLastPathSegment()). Access to + * a specific row in the tables is done by using the where-clause, hence support for .../#id if + * not needed for the Email clients. The URI format for accessing the tables are as follows: + * content://ProviderAuthority/TABLE_ACCOUNT + * content://ProviderAuthority/account_id/TABLE_MESSAGE + * content://ProviderAuthority/account_id/TABLE_FOLDER + * content://ProviderAuthority/account_id/TABLE_CONVERSATION + * content://ProviderAuthority/account_id/TABLE_CONVOCONTACT + */ /** - * Build URI representing the given Accounts data-set in a - * Bluetooth provider. When queried, the direct URI for the account - * with the given accountID is returned. + * Build URI representing the given Accounts data-set in a Bluetooth provider. When queried, the + * direct URI for the account with the given accountID is returned. */ public static Uri buildAccountUri(String authority) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(TABLE_ACCOUNT) .build(); } /** - * Build URI representing the given Account data-set with specific Id in a - * Bluetooth provider. When queried, the direct URI for the account - * with the given accountID is returned. + * Build URI representing the given Account data-set with specific Id in a Bluetooth provider. + * When queried, the direct URI for the account with the given accountID is returned. */ public static Uri buildAccountUriwithId(String authority, String accountId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(TABLE_ACCOUNT) .appendPath(accountId) .build(); } - /** - * Build URI representing the entire Message table in a - * Bluetooth provider. - */ + /** Build URI representing the entire Message table in a Bluetooth provider. */ public static Uri buildMessageUri(String authority) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(TABLE_MESSAGE) .build(); } /** - * Build URI representing the given Message data-set in a - * Bluetooth provider. When queried, the URI for the Messages - * with the given accountID is returned. + * Build URI representing the given Message data-set in a Bluetooth provider. When queried, the + * URI for the Messages with the given accountID is returned. */ public static Uri buildMessageUri(String authority, String accountId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(accountId) .appendPath(TABLE_MESSAGE) @@ -204,12 +197,12 @@ public final class BluetoothMapContract { } /** - * Build URI representing the given Message data-set with specific messageId in a - * Bluetooth provider. When queried, the direct URI for the account - * with the given accountID is returned. + * Build URI representing the given Message data-set with specific messageId in a Bluetooth + * provider. When queried, the direct URI for the account with the given accountID is returned. */ public static Uri buildMessageUriWithId(String authority, String accountId, String messageId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(accountId) .appendPath(TABLE_MESSAGE) @@ -218,12 +211,12 @@ public final class BluetoothMapContract { } /** - * Build URI representing the given Message data-set in a - * Bluetooth provider. When queried, the direct URI for the folder - * with the given accountID is returned. + * Build URI representing the given Message data-set in a Bluetooth provider. When queried, the + * direct URI for the folder with the given accountID is returned. */ public static Uri buildFolderUri(String authority, String accountId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(accountId) .appendPath(TABLE_FOLDER) @@ -231,12 +224,12 @@ public final class BluetoothMapContract { } /** - * Build URI representing the given Message data-set in a - * Bluetooth provider. When queried, the direct URI for the conversation - * with the given accountID is returned. + * Build URI representing the given Message data-set in a Bluetooth provider. When queried, the + * direct URI for the conversation with the given accountID is returned. */ public static Uri buildConversationUri(String authority, String accountId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(accountId) .appendPath(TABLE_CONVERSATION) @@ -244,24 +237,24 @@ public final class BluetoothMapContract { } /** - * Build URI representing the given Contact data-set in a - * Bluetooth provider. When queried, the direct URI for the contacts - * with the given accountID is returned. + * Build URI representing the given Contact data-set in a Bluetooth provider. When queried, the + * direct URI for the contacts with the given accountID is returned. */ public static Uri buildConvoContactsUri(String authority) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(TABLE_CONVOCONTACT) .build(); } /** - * Build URI representing the given Contact data-set in a - * Bluetooth provider. When queried, the direct URI for the contacts - * with the given accountID is returned. + * Build URI representing the given Contact data-set in a Bluetooth provider. When queried, the + * direct URI for the contacts with the given accountID is returned. */ public static Uri buildConvoContactsUri(String authority, String accountId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(accountId) .appendPath(TABLE_CONVOCONTACT) @@ -269,13 +262,13 @@ public final class BluetoothMapContract { } /** - * Build URI representing the given Contact data-set in a - * Bluetooth provider. When queried, the direct URI for the contact - * with the given contactID and accountID is returned. + * Build URI representing the given Contact data-set in a Bluetooth provider. When queried, the + * direct URI for the contact with the given contactID and accountID is returned. */ - public static Uri buildConvoContactsUriWithId(String authority, String accountId, - String contactId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + public static Uri buildConvoContactsUriWithId( + String authority, String accountId, String contactId) { + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(accountId) .appendPath(TABLE_CONVOCONTACT) @@ -283,572 +276,529 @@ public final class BluetoothMapContract { .build(); } - /** - * @hide - */ + /** @hide */ public static final String TABLE_ACCOUNT = "Account"; + public static final String TABLE_MESSAGE = "Message"; public static final String TABLE_MESSAGE_PART = "Part"; public static final String TABLE_FOLDER = "Folder"; public static final String TABLE_CONVERSATION = "Conversation"; public static final String TABLE_CONVOCONTACT = "ConvoContact"; - /** - * Mandatory folders for the Bluetooth message access profile. - * The email client shall at least implement the following root folders. - * E.g. as a mapping for them such that the naming will match the underlying - * matching folder ID's. + * Mandatory folders for the Bluetooth message access profile. The email client shall at least + * implement the following root folders. E.g. as a mapping for them such that the naming will + * match the underlying matching folder ID's. */ public static final String FOLDER_NAME_INBOX = "inbox"; + public static final String FOLDER_NAME_SENT = "sent"; public static final String FOLDER_NAME_OUTBOX = "outbox"; public static final String FOLDER_NAME_DRAFT = "draft"; public static final String FOLDER_NAME_DELETED = "deleted"; public static final String FOLDER_NAME_OTHER = "other"; - /** - * Folder IDs to be used with Instant Messaging virtual folders - */ + /** Folder IDs to be used with Instant Messaging virtual folders */ public static final long FOLDER_ID_OTHER = 0; + public static final long FOLDER_ID_INBOX = 1; public static final long FOLDER_ID_SENT = 2; public static final long FOLDER_ID_DRAFT = 3; public static final long FOLDER_ID_OUTBOX = 4; public static final long FOLDER_ID_DELETED = 5; - /** - * To push RFC2822 encoded messages into a folder and read RFC2822 encoded messages from - * a folder, the openFile() interface will be used as follows: - * Open a file descriptor to a message. - * Two modes supported for read: With and without attachments. - * One mode exist for write and the actual content will be with or without - * attachments. + * To push RFC2822 encoded messages into a folder and read RFC2822 encoded messages from a + * folder, the openFile() interface will be used as follows: Open a file descriptor to a + * message. Two modes supported for read: With and without attachments. One mode exist for write + * and the actual content will be with or without attachments. * - * mode will be "r" for read and "w" for write, never "rw". + *

mode will be "r" for read and "w" for write, never "rw". * - * URI format: - * The URI scheme is as follows. - * For reading messages with attachments: - * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId - * Note: This shall be an offline operation, including only message parts and attachments - * already downloaded to the device. + *

URI format: The URI scheme is as follows. For reading messages with attachments: + * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId Note: This shall be an offline + * operation, including only message parts and attachments already downloaded to the device. * - * For reading messages without attachments: - * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_NO_ATTACHMENTS - * Note: This shall be an offline operation, including only message parts already - * downloaded to the device. + *

For reading messages without attachments: + * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_NO_ATTACHMENTS Note: This + * shall be an offline operation, including only message parts already downloaded to the device. * - * For downloading and reading messages with attachments: - * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD - * Note: This shall download the message content and all attachments if possible, - * else throw an IOException. + *

For downloading and reading messages with attachments: + * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD Note: This shall + * download the message content and all attachments if possible, else throw an IOException. * - * For downloading and reading messages without attachments: - * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD_NO_ATTACHMENTS - * Note: This shall download the message content if possible, else throw an IOException. + *

For downloading and reading messages without attachments: + * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD_NO_ATTACHMENTS + * Note: This shall download the message content if possible, else throw an IOException. * - * When reading from the file descriptor, the content provider shall return a stream - * of bytes containing a RFC2822 encoded message, as if the message was send to an email - * server. + *

When reading from the file descriptor, the content provider shall return a stream of bytes + * containing a RFC2822 encoded message, as if the message was send to an email server. * - * When a byte stream is written to the file descriptor, the content provider shall - * decode the RFC2822 encoded data and insert the message into the TABLE_MESSAGE at the ID - * supplied in URI - additionally the message content shall be stored in the underlying - * data base structure as if the message was received from an email server. The Message ID - * will be created using a insert on the TABLE_MESSAGE prior to calling openFile(). - * Hence the procedure for inserting a message is: - * - uri/msgId = insert(uri, value: folderId=xxx) - * - fd = openFile(uri/msgId) - * - fd.write (RFC2822 encoded data) + *

When a byte stream is written to the file descriptor, the content provider shall decode + * the RFC2822 encoded data and insert the message into the TABLE_MESSAGE at the ID supplied in + * URI - additionally the message content shall be stored in the underlying data base structure + * as if the message was received from an email server. The Message ID will be created using a + * insert on the TABLE_MESSAGE prior to calling openFile(). Hence the procedure for inserting a + * message is: - uri/msgId = insert(uri, value: folderId=xxx) - fd = openFile(uri/msgId) - + * fd.write (RFC2822 encoded data) * - * The Bluetooth Message Access Client might not know what to put into the From: - * header nor have a valid time stamp, hence the content provider shall check - * if the From: and Date: headers have been set by the message written, else - * it must fill in appropriate values. + *

The Bluetooth Message Access Client might not know what to put into the From: header nor + * have a valid time stamp, hence the content provider shall check if the From: and Date: + * headers have been set by the message written, else it must fill in appropriate values. */ public static final String FILE_MSG_NO_ATTACHMENTS = "NO_ATTACHMENTS"; + public static final String FILE_MSG_DOWNLOAD = "DOWNLOAD"; public static final String FILE_MSG_DOWNLOAD_NO_ATTACHMENTS = "DOWNLOAD_NO_ATTACHMENTS"; /** - * Account Table - * The columns needed to supply account information. - * The e-mail client app may choose to expose all e-mails as being from the same account, - * but it is not recommended, as this would be a violation of the Bluetooth specification. - * The Bluetooth Message Access settings activity will provide the user the ability to - * change the FLAG_EXPOSE values for each account in this table. - * The Bluetooth Message Access service will read the values when Bluetooth is turned on, - * and again on every notified change through the content observer interface. + * Account Table The columns needed to supply account information. The e-mail client app may + * choose to expose all e-mails as being from the same account, but it is not recommended, as + * this would be a violation of the Bluetooth specification. The Bluetooth Message Access + * settings activity will provide the user the ability to change the FLAG_EXPOSE values for each + * account in this table. The Bluetooth Message Access service will read the values when + * Bluetooth is turned on, and again on every notified change through the content observer + * interface. */ public interface AccountColumns { /** * The unique ID for a row. - *

Type: INTEGER (long)

+ * + *

Type: INTEGER (long) */ String _ID = "_id"; /** - * The account name to display to the user on the device when selecting whether - * or not to share the account over Bluetooth. - * - * The account display name should not reveal any sensitive information e.g. email- - * address, as it will be added to the Bluetooth SDP record, which can be read by - * any Bluetooth enabled device. (Access to any account content is only provided to - * authenticated devices). It is recommended that if the email client uses the email - * address as account name, then the address should be obfuscated (i.e. replace "@" - * with ".") - *

Type: TEXT

- * read-only + * The account name to display to the user on the device when selecting whether or not to + * share the account over Bluetooth. + * + *

The account display name should not reveal any sensitive information e.g. email- + * address, as it will be added to the Bluetooth SDP record, which can be read by any + * Bluetooth enabled device. (Access to any account content is only provided to + * authenticated devices). It is recommended that if the email client uses the email address + * as account name, then the address should be obfuscated (i.e. replace "@" with ".") + * + *

Type: TEXT read-only */ String ACCOUNT_DISPLAY_NAME = "account_display_name"; /** - * Expose this account to other authenticated Bluetooth devices. If the expose flag - * is set, this account will be listed as an available account to access from another - * Bluetooth device. + * Expose this account to other authenticated Bluetooth devices. If the expose flag is set, + * this account will be listed as an available account to access from another Bluetooth + * device. * - * This is a read/write flag, that can be set either from within the E-mail client - * UI or the Bluetooth settings menu. + *

This is a read/write flag, that can be set either from within the E-mail client UI or + * the Bluetooth settings menu. * - * It is recommended to either ask the user whether to expose the account, or set this - * to "show" as default. + *

It is recommended to either ask the user whether to expose the account, or set this to + * "show" as default. * - * This setting shall not be used to enforce whether or not an account should be shared - * or not if the account is bound by an administrative security policy. In this case - * the email app should not list the account at all if it is not to be sharable over BT. + *

This setting shall not be used to enforce whether or not an account should be shared + * or not if the account is bound by an administrative security policy. In this case the + * email app should not list the account at all if it is not to be sharable over BT. * - *

Type: INTEGER (boolean) hide = 0, show = 1

+ *

Type: INTEGER (boolean) hide = 0, show = 1 */ String FLAG_EXPOSE = "flag_expose"; - /** * The account unique identifier representing this account. For most IM clients this will be * the fully qualified user name to which an invite message can be sent, from another use. * - * e.g.: "map_test_user_12345@gmail.com" - for a Hangouts account + *

e.g.: "map_test_user_12345@gmail.com" - for a Hangouts account * - * This value will only be visible to authenticated Bluetooth devices, and will be + *

This value will only be visible to authenticated Bluetooth devices, and will be * transmitted using an encrypted link. - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String ACCOUNT_UCI = "account_uci"; - /** - * The Bluetooth SIG maintains a list of assigned numbers(text strings) for IM clients. - * If your client/account has such a string, this is the place to return it. - * If supported by both devices, the presence of this prefix will make it possible to - * respond to a message by making a voice-call, using the same account information. - * (The call will be made using the HandsFree profile) + * The Bluetooth SIG maintains a list of assigned numbers(text strings) for IM clients. If + * your client/account has such a string, this is the place to return it. If supported by + * both devices, the presence of this prefix will make it possible to respond to a message + * by making a voice-call, using the same account information. (The call will be made using + * the HandsFree profile) * https://www.bluetooth.org/en-us/specification/assigned-numbers/uniform-caller-identifiers * - * e.g.: "hgus" - for Hangouts + *

e.g.: "hgus" - for Hangouts * - *

Type: TEXT

- * read-only + *

Type: TEXT read-only */ String ACCOUNT_UCI_PREFIX = "account_uci_PREFIX"; - } /** - * Message Data Parts Table - * The columns needed to contain the actual data of the messageparts in IM messages. - * Each "part" has its own row and represent a single mime-part in a multipart-mime + * Message Data Parts Table The columns needed to contain the actual data of the messageparts in + * IM messages. Each "part" has its own row and represent a single mime-part in a multipart-mime * formatted message. - * */ public interface MessagePartColumns { /** * The unique ID for a row. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String _ID = "_id"; + // FIXME add message parts for IM attachments /** - * is this a text part yes/no? - *

Type: TEXT

- * read-only + * is this a text part yes/no? + * + *

Type: TEXT read-only */ String TEXT = "text"; /** - * The charset used in the content if it is text or 8BIT if it is - * binary data + * The charset used in the content if it is text or 8BIT if it is binary data * - *

Type: TEXT

- * read-only + *

Type: TEXT read-only */ String CHARSET = "charset"; /** - * The filename representing the data file of the raw data in the database - * If this is empty, then it must be text and part of the message body. - * This is the name that the data will have when it is included as attachment + * The filename representing the data file of the raw data in the database If this is empty, + * then it must be text and part of the message body. This is the name that the data will + * have when it is included as attachment * - *

Type: TEXT

- * read-only + *

Type: TEXT read-only */ - String FILENAME = "filename"; /** - * Identifier for the content in the data. This can be used to - * refer directly to the data in the body part. + * Identifier for the content in the data. This can be used to refer directly to the data in + * the body part. * - *

Type: TEXT

- * read-only + *

Type: TEXT read-only */ - String CONTENT_ID = "cid"; /** * The raw data in either text format or binary format * - *

Type: BLOB

- * read-only + *

Type: BLOB read-only */ String RAW_DATA = "raw_data"; - } /** - * The actual message table containing all messages. - * Content that must support filtering using WHERE clauses: - * - To, From, Cc, Bcc, Date, ReadFlag, PriorityFlag, folder_id, account_id - * Additional content that must be supplied: - * - Subject, AttachmentFlag, LoadedState, MessageSize, AttachmentSize - * Content that must support update: - * - FLAG_READ and FOLDER_ID (FOLDER_ID is used to move a message to deleted) - * Additional insert of a new message with the following values shall be supported: - * - FOLDER_ID + * The actual message table containing all messages. Content that must support filtering using + * WHERE clauses: - To, From, Cc, Bcc, Date, ReadFlag, PriorityFlag, folder_id, account_id + * Additional content that must be supplied: - Subject, AttachmentFlag, LoadedState, + * MessageSize, AttachmentSize Content that must support update: - FLAG_READ and FOLDER_ID + * (FOLDER_ID is used to move a message to deleted) Additional insert of a new message with the + * following values shall be supported: - FOLDER_ID * - * When doing an insert on this table, the actual content of the message (subject, - * date etc) written through file-i/o takes precedence over the inserted values and should - * overwrite them. + *

When doing an insert on this table, the actual content of the message (subject, date etc) + * written through file-i/o takes precedence over the inserted values and should overwrite them. */ public interface MessageColumns extends EmailMessageColumns { /** * The unique ID for a row. - *

Type: INTEGER (long)

+ * + *

Type: INTEGER (long) */ String _ID = "_id"; /** - * The date the message was received as a unix timestamp - * (miliseconds since 00:00:00 UTC 1/1-1970). + * The date the message was received as a unix timestamp (miliseconds since 00:00:00 UTC + * 1/1-1970). * - *

Type: INTEGER (long)

- * read-only + *

Type: INTEGER (long) read-only */ String DATE = "date"; - //TODO REMOVE WHEN Parts Table is in place + // TODO REMOVE WHEN Parts Table is in place /** * Message body. Used by Instant Messaging - *

Type: TEXT

- * read-only. + * + *

Type: TEXT read-only. */ String BODY = "body"; /** * Message subject. - *

Type: TEXT

- * read-only. + * + *

Type: TEXT read-only. */ String SUBJECT = "subject"; /** * Message Read flag - *

Type: INTEGER (boolean) unread = 0, read = 1

- * read/write + * + *

Type: INTEGER (boolean) unread = 0, read = 1 read/write */ String FLAG_READ = "flag_read"; /** * Message Priority flag - *

Type: INTEGER (boolean) normal priority = 0, high priority = 1

- * read-only + * + *

Type: INTEGER (boolean) normal priority = 0, high priority = 1 read-only */ String FLAG_HIGH_PRIORITY = "high_priority"; /** * Reception state - the amount of the message that have been loaded from the server. - *

Type: TEXT see RECEPTION_STATE_* constants below

- * read-only + * + *

Type: TEXT see RECEPTION_STATE_* constants below read-only */ String RECEPTION_STATE = "reception_state"; /** * Delivery state - the amount of the message that have been loaded from the server. - *

Type: TEXT see DELIVERY_STATE_* constants below

- * read-only + * + *

Type: TEXT see DELIVERY_STATE_* constants below read-only */ String DEVILERY_STATE = "delivery_state"; - /** To be able to filter messages with attachments, we need this flag. - *

Type: INTEGER (boolean) no attachment = 0, attachment = 1

- * read-only + /** + * To be able to filter messages with attachments, we need this flag. + * + *

Type: INTEGER (boolean) no attachment = 0, attachment = 1 read-only */ String FLAG_ATTACHMENT = "flag_attachment"; - /** The overall size in bytes of the attachments of the message. - *

Type: INTEGER

+ /** + * The overall size in bytes of the attachments of the message. + * + *

Type: INTEGER */ String ATTACHMENT_SIZE = "attachment_size"; - /** The mine type of the attachments for the message. - *

Type: TEXT

- * read-only + /** + * The mine type of the attachments for the message. + * + *

Type: TEXT read-only */ String ATTACHMENT_MINE_TYPES = "attachment_mime_types"; - /** The overall size in bytes of the message including any attachments. - * This value is informative only and should be the size an email client - * would display as size for the message. - *

Type: INTEGER

- * read-only + /** + * The overall size in bytes of the message including any attachments. This value is + * informative only and should be the size an email client would display as size for the + * message. + * + *

Type: INTEGER read-only */ String MESSAGE_SIZE = "message_size"; - /** Indicates that the message or a part of it is protected by a DRM scheme. - *

Type: INTEGER (boolean) no DRM = 0, DRM protected = 1

- * read-only + /** + * Indicates that the message or a part of it is protected by a DRM scheme. + * + *

Type: INTEGER (boolean) no DRM = 0, DRM protected = 1 read-only */ String FLAG_PROTECTED = "flag_protected"; /** - * A comma-delimited list of FROM addresses in RFC2822 format. - * The list must be compatible with Rfc822Tokenizer.tokenize(); - *

Type: TEXT

- * read-only + * A comma-delimited list of FROM addresses in RFC2822 format. The list must be compatible + * with Rfc822Tokenizer.tokenize(); + * + *

Type: TEXT read-only */ String FROM_LIST = "from_list"; /** - * A comma-delimited list of TO addresses in RFC2822 format. - * The list must be compatible with Rfc822Tokenizer.tokenize(); - *

Type: TEXT

- * read-only + * A comma-delimited list of TO addresses in RFC2822 format. The list must be compatible + * with Rfc822Tokenizer.tokenize(); + * + *

Type: TEXT read-only */ String TO_LIST = "to_list"; /** * The unique ID for a row in the folder table in which this message belongs. - *

Type: INTEGER (long)

- * read/write + * + *

Type: INTEGER (long) read/write */ String FOLDER_ID = "folder_id"; /** * The unique ID for a row in the account table which owns this message. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String ACCOUNT_ID = "account_id"; /** - * The ID identify the thread/conversation a message belongs to. - * If no thread id is available, set value to "-1" - *

Type: INTEGER (long)

- * read-only + * The ID identify the thread/conversation a message belongs to. If no thread id is + * available, set value to "-1" + * + *

Type: INTEGER (long) read-only */ String THREAD_ID = "thread_id"; /** * The Name of the thread/conversation a message belongs to. - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String THREAD_NAME = "thread_name"; } public interface EmailMessageColumns { - /** - * A comma-delimited list of CC addresses in RFC2822 format. - * The list must be compatible with Rfc822Tokenizer.tokenize(); - *

Type: TEXT

- * read-only + * A comma-delimited list of CC addresses in RFC2822 format. The list must be compatible + * with Rfc822Tokenizer.tokenize(); + * + *

Type: TEXT read-only */ String CC_LIST = "cc_list"; /** - * A comma-delimited list of BCC addresses in RFC2822 format. - * The list must be compatible with Rfc822Tokenizer.tokenize(); - *

Type: TEXT

- * read-only + * A comma-delimited list of BCC addresses in RFC2822 format. The list must be compatible + * with Rfc822Tokenizer.tokenize(); + * + *

Type: TEXT read-only */ String BCC_LIST = "bcc_list"; /** - * A comma-delimited list of REPLY-TO addresses in RFC2822 format. - * The list must be compatible with Rfc822Tokenizer.tokenize(); - *

Type: TEXT

- * read-only + * A comma-delimited list of REPLY-TO addresses in RFC2822 format. The list must be + * compatible with Rfc822Tokenizer.tokenize(); + * + *

Type: TEXT read-only */ String REPLY_TO_LIST = "reply_to_List"; - - } - /** - * Indicates the complete message has been delivered to the recipient. - */ + /** Indicates the complete message has been delivered to the recipient. */ public static final String DELIVERY_STATE_DELIVERED = "delivered"; - /** - * Indicates that the complete message has been sent from the MSE to the remote network. - */ + + /** Indicates that the complete message has been sent from the MSE to the remote network. */ public static final String DELIVERY_STATE_SENT = "sent"; /** - * Indicates that the message, including any attachments, has been received from the - * server to the device. + * Indicates that the message, including any attachments, has been received from the server to + * the device. */ public static final String RECEPTION_STATE_COMPLETE = "complete"; - /** - * Indicates the message is partially received from the email server. - */ + + /** Indicates the message is partially received from the email server. */ public static final String RECEPTION_STATE_FRACTIONED = "fractioned"; - /** - * Indicates that only a notification about the message have been received. - */ + + /** Indicates that only a notification about the message have been received. */ public static final String RECEPTION_STATE_NOTIFICATION = "notification"; /** - * Message folder structure - * MAP enforces use of a folder structure with mandatory folders: - * - inbox, outbox, sent, deleted, draft - * User defined folders are supported. - * The folder table must provide filtering (use of WHERE clauses) of the following entries: - * - account_id (linking the folder to an e-mail account) - * - parent_id (linking the folders individually) - * The folder table must have a folder name for each entry, and the mandatory folders - * MUST exist for each account_id. The folders may be empty. - * Use the FOLDER_NAME_xxx constants for the mandatory folders. Their names must - * not be translated into other languages, as the folder browsing is string based, and - * many Bluetooth Message Clients will use these strings to navigate to the folders. + * Message folder structure MAP enforces use of a folder structure with mandatory folders: - + * inbox, outbox, sent, deleted, draft User defined folders are supported. The folder table must + * provide filtering (use of WHERE clauses) of the following entries: - account_id (linking the + * folder to an e-mail account) - parent_id (linking the folders individually) The folder table + * must have a folder name for each entry, and the mandatory folders MUST exist for each + * account_id. The folders may be empty. Use the FOLDER_NAME_xxx constants for the mandatory + * folders. Their names must not be translated into other languages, as the folder browsing is + * string based, and many Bluetooth Message Clients will use these strings to navigate to the + * folders. */ public interface FolderColumns { /** * The unique ID for a row. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String _ID = "_id"; /** * The folder display name to present to the user. - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String NAME = "name"; /** * The _id-key to the account this folder refers to. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String ACCOUNT_ID = "account_id"; /** * The _id-key to the parent folder. -1 for root folders. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String PARENT_FOLDER_ID = "parent_id"; } /** * Message conversation structure. Enables use of a conversation structure for messages across - * folders, further binding contacts to conversations. - * Content that must be supplied: - * - Name, LastActivity, ReadStatus, VersionCounter - * Content that must support update: - * - READ_STATUS, LAST_ACTIVITY and VERSION_COUNTER (VERSION_COUNTER used to validity of _ID) - * Additional insert of a new conversation with the following values shall be supported: - * - FOLDER_ID - * When querying this table, the cursor returned must contain one row for each contact member - * in a thread. - * For filter/search parameters attributes to the URI will be used. The following columns must - * support filtering: - * - ConvoContactColumns.NAME - * - ConversationColumns.THREAD_ID - * - ConversationColumns.LAST_ACTIVITY - * - ConversationColumns.READ_STATUS + * folders, further binding contacts to conversations. Content that must be supplied: - Name, + * LastActivity, ReadStatus, VersionCounter Content that must support update: - READ_STATUS, + * LAST_ACTIVITY and VERSION_COUNTER (VERSION_COUNTER used to validity of _ID) Additional insert + * of a new conversation with the following values shall be supported: - FOLDER_ID When querying + * this table, the cursor returned must contain one row for each contact member in a thread. For + * filter/search parameters attributes to the URI will be used. The following columns must + * support filtering: - ConvoContactColumns.NAME - ConversationColumns.THREAD_ID - + * ConversationColumns.LAST_ACTIVITY - ConversationColumns.READ_STATUS */ public interface ConversationColumns extends ConvoContactColumns { /** * The unique ID for a row. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ -// Should not be needed anymore public static final String _ID = "_id"; + // Should not be needed anymore public static final String _ID = "_id"; /** * The unique ID for a Thread. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String THREAD_ID = "thread_id"; /** * The unique ID for a row. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ -// TODO: IS THIS NECESSARY - or do we need the thread ID to hold thread Id from message -// or can we be sure we are in control and can use the _ID and put that in the message DB - //public static final String THREAD_ID = "thread_id"; + // TODO: IS THIS NECESSARY - or do we need the thread ID to hold thread Id from message + // or can we be sure we are in control and can use the _ID and put that in the message + // DB + // public static final String THREAD_ID = "thread_id"; /** * The type of conversation, see {@link ConversationType} - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ -// TODO: IS THIS NECESSARY - no conversation type is available in the latest, -// guess it can be found from number of contacts in the conversation - //public static final String TYPE = "type"; + // TODO: IS THIS NECESSARY - no conversation type is available in the latest, + // guess it can be found from number of contacts in the conversation + // public static final String TYPE = "type"; /** * The name of the conversation, e.g. group name in case of group chat - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String THREAD_NAME = "thread_name"; /** - * The time stamp of the last activity in the conversation as a unix timestamp - * (miliseconds since 00:00:00 UTC 1/1-1970) - *

Type: INTEGER (long)

- * read-only + * The time stamp of the last activity in the conversation as a unix timestamp (miliseconds + * since 00:00:00 UTC 1/1-1970) + * + *

Type: INTEGER (long) read-only */ String LAST_THREAD_ACTIVITY = "last_thread_activity"; /** * The status on the conversation, either 'read' or 'unread' - *

Type: INTEGER (boolean) unread = 0, read = 1

- * read/write + * + *

Type: INTEGER (boolean) unread = 0, read = 1 read/write */ String READ_STATUS = "read_status"; /** * A counter that keep tack of version of the table content, count up on ID reuse - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ -// TODO: IS THIS NECESSARY - skal den ligge i databasen? + // TODO: IS THIS NECESSARY - skal den ligge i databasen? // CB: If we need it, it must be in the database, or initialized with a random value at // BT-ON // UPDATE: TODO: Change to the last_activity time stamp (as a long value). This will @@ -856,110 +806,96 @@ public final class BluetoothMapContract { String VERSION_COUNTER = "version_counter"; /** - * A short description of the latest activity on conversation - typically - * part of the last message. - *

Type: TEXT

- * read-only + * A short description of the latest activity on conversation - typically part of the last + * message. + * + *

Type: TEXT read-only */ String SUMMARY = "convo_summary"; - - } /** - * MAP enables access to contacts for the conversation - * The conversation table must provide filtering (using WHERE clauses) of following entries: - * - convo_id linking contacts to conversations - * - x_bt_uid linking contacts to PBAP contacts - * The conversation contact table must have a convo_id and a name for each entry. + * MAP enables access to contacts for the conversation The conversation table must provide + * filtering (using WHERE clauses) of following entries: - convo_id linking contacts to + * conversations - x_bt_uid linking contacts to PBAP contacts The conversation contact table + * must have a convo_id and a name for each entry. */ public interface ConvoContactColumns extends ChatStatusColumns, PresenceColumns { /** * The unique ID for a contact in Conversation - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ -// Should not be needed anymore public static final String _ID = "_id"; + // Should not be needed anymore public static final String _ID = "_id"; /** * The ID of the conversation the contact is part of. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String CONVO_ID = "convo_id"; /** * The name of contact in instant message application - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String NAME = "name"; /** * The nickname of contact in instant message group chat conversation. - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String NICKNAME = "nickname"; - /** * The unique ID for all Bluetooth contacts available through PBAP. - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String X_BT_UID = "x_bt_uid"; /** - * The unique ID for the contact within the domain of the interfacing service. - * (UCI: Unique Call Identity) - * It is expected that a message send to this ID will reach the recipient regardless - * through which interface the message is send. - * For E-mail this will be the e-mail address, for Google+ this will be the e-mail address - * associated with the contact account. - * This ID - *

Type: TEXT

- * read-only + * The unique ID for the contact within the domain of the interfacing service. (UCI: Unique + * Call Identity) It is expected that a message send to this ID will reach the recipient + * regardless through which interface the message is send. For E-mail this will be the + * e-mail address, for Google+ this will be the e-mail address associated with the contact + * account. This ID + * + *

Type: TEXT read-only */ String UCI = "x_bt_uci"; } - /** - * The name of query parameter used to filter on recipient - */ + /** The name of query parameter used to filter on recipient */ public static final String FILTER_RECIPIENT_SUBSTRING = "rec_sub_str"; - /** - * The name of query parameter used to filter on originator - */ + /** The name of query parameter used to filter on originator */ public static final String FILTER_ORIGINATOR_SUBSTRING = "org_sub_str"; /** - * The name of query parameter used to filter on read status. - * - true - return only threads with all messages marked as read - * - false - return only threads with one or more unread messages - * - omitted as query parameter - do not filter on read status + * The name of query parameter used to filter on read status. - true - return only threads with + * all messages marked as read - false - return only threads with one or more unread messages - + * omitted as query parameter - do not filter on read status */ public static final String FILTER_READ_STATUS = "read"; /** - * Time in ms since epoch. For conversations this will be for last activity - * as a unix timestamp (miliseconds since 00:00:00 UTC 1/1-1970) + * Time in ms since epoch. For conversations this will be for last activity as a unix timestamp + * (miliseconds since 00:00:00 UTC 1/1-1970) */ public static final String FILTER_PERIOD_BEGIN = "t_begin"; /** - * Time in ms since epoch. For conversations this will be for last activity - * as a unix timestamp (miliseconds since 00:00:00 UTC 1/1-1970) + * Time in ms since epoch. For conversations this will be for last activity as a unix timestamp + * (miliseconds since 00:00:00 UTC 1/1-1970) */ public static final String FILTER_PERIOD_END = "t_end"; - /** - * Filter for a specific ThreadId - */ + /** Filter for a specific ThreadId */ public static final String FILTER_THREAD_ID = "thread_id"; - public interface ChatState { int UNKNOWN = 0; int INACITVE = 1; @@ -970,51 +906,49 @@ public final class BluetoothMapContract { } /** - * Instant Messaging contact chat state information - * MAP enables access to contacts chat state for the instant messaging application - * The chat state table must provide filtering (use of WHERE clauses) of the following entries: - * - contact_id (linking chat state to contacts) - * - thread_id (linking chat state to conversations and messages) - * The presence table must have a contact_id for each entry. + * Instant Messaging contact chat state information MAP enables access to contacts chat state + * for the instant messaging application The chat state table must provide filtering (use of + * WHERE clauses) of the following entries: - contact_id (linking chat state to contacts) - + * thread_id (linking chat state to conversations and messages) The presence table must have a + * contact_id for each entry. */ public interface ChatStatusColumns { -// /** -// * The contact ID of a instant messaging contact. -// *

Type: TEXT

-// * read-only -// */ -// public static final String CONTACT_ID = "contact_id"; -// -// /** -// * The thread id for a conversation. -// *

Type: INTEGER (long)

-// * read-only -// */ -// public static final String CONVO_ID = "convo_id"; + // /** + // * The contact ID of a instant messaging contact. + // *

Type: TEXT

+ // * read-only + // */ + // public static final String CONTACT_ID = "contact_id"; + // + // /** + // * The thread id for a conversation. + // *

Type: INTEGER (long)

+ // * read-only + // */ + // public static final String CONVO_ID = "convo_id"; /** * The chat state of contact in conversation, see {@link ChatState} - *

Type: INTERGER

- * read-only + * + *

Type: INTERGER read-only */ String CHAT_STATE = "chat_state"; -// /** -// * The geo location of the contact -// *

Type: TEXT

-// * read-only -// */ -//// TODO: IS THIS NEEDED - not in latest specification -// public static final String GEOLOC = "geoloc"; + // /** + // * The geo location of the contact + // *

Type: TEXT

+ // * read-only + // */ + //// TODO: IS THIS NEEDED - not in latest specification + // public static final String GEOLOC = "geoloc"; /** * The time stamp of the last time this contact was active in the conversation - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String LAST_ACTIVE = "last_active"; - } public interface PresenceState { @@ -1028,196 +962,183 @@ public final class BluetoothMapContract { } /** - * Instant Messaging contact presence information - * MAP enables access to contacts presences information for the instant messaging application - * The presence table must provide filtering (use of WHERE clauses) of the following entries: - * - contact_id (linking contacts to presence) + * Instant Messaging contact presence information MAP enables access to contacts presences + * information for the instant messaging application The presence table must provide filtering + * (use of WHERE clauses) of the following entries: - contact_id (linking contacts to presence) * The presence table must have a contact_id for each entry. */ public interface PresenceColumns { -// /** -// * The contact ID of a instant messaging contact. -// *

Type: TEXT

-// * read-only -// */ -// public static final String CONTACT_ID = "contact_id"; + // /** + // * The contact ID of a instant messaging contact. + // *

Type: TEXT

+ // * read-only + // */ + // public static final String CONTACT_ID = "contact_id"; /** * The presence state of contact, see {@link PresenceState} - *

Type: INTERGER

- * read-only + * + *

Type: INTERGER read-only */ String PRESENCE_STATE = "presence_state"; /** * The priority of contact presence - *

Type: INTERGER

- * read-only + * + *

Type: INTERGER read-only */ -// TODO: IS THIS NEEDED - not in latest specification + // TODO: IS THIS NEEDED - not in latest specification String PRIORITY = "priority"; /** * The last status text from contact - *

Type: TEXT

- * read-only + * + *

Type: TEXT read-only */ String STATUS_TEXT = "status_text"; /** * The time stamp of the last time the contact was online - *

Type: INTEGER (long)

- * read-only + * + *

Type: INTEGER (long) read-only */ String LAST_ONLINE = "last_online"; - } + /** A projection of all the columns in the Message table */ + public static final String[] BT_MESSAGE_PROJECTION = + new String[] { + MessageColumns._ID, + MessageColumns.DATE, + MessageColumns.SUBJECT, + // TODO REMOVE WHEN Parts Table is in place + MessageColumns.BODY, + MessageColumns.MESSAGE_SIZE, + MessageColumns.FOLDER_ID, + MessageColumns.FLAG_READ, + MessageColumns.FLAG_PROTECTED, + MessageColumns.FLAG_HIGH_PRIORITY, + MessageColumns.FLAG_ATTACHMENT, + MessageColumns.ATTACHMENT_SIZE, + MessageColumns.FROM_LIST, + MessageColumns.TO_LIST, + MessageColumns.CC_LIST, + MessageColumns.BCC_LIST, + MessageColumns.REPLY_TO_LIST, + MessageColumns.RECEPTION_STATE, + MessageColumns.DEVILERY_STATE, + MessageColumns.THREAD_ID + }; + + public static final String[] BT_INSTANT_MESSAGE_PROJECTION = + new String[] { + MessageColumns._ID, + MessageColumns.DATE, + MessageColumns.SUBJECT, + MessageColumns.MESSAGE_SIZE, + MessageColumns.FOLDER_ID, + MessageColumns.FLAG_READ, + MessageColumns.FLAG_PROTECTED, + MessageColumns.FLAG_HIGH_PRIORITY, + MessageColumns.FLAG_ATTACHMENT, + MessageColumns.ATTACHMENT_SIZE, + MessageColumns.ATTACHMENT_MINE_TYPES, + MessageColumns.FROM_LIST, + MessageColumns.TO_LIST, + MessageColumns.RECEPTION_STATE, + MessageColumns.DEVILERY_STATE, + MessageColumns.THREAD_ID, + MessageColumns.THREAD_NAME + }; + + /** A projection of all the columns in the Account table */ + public static final String[] BT_ACCOUNT_PROJECTION = + new String[] { + AccountColumns._ID, AccountColumns.ACCOUNT_DISPLAY_NAME, AccountColumns.FLAG_EXPOSE, + }; /** - * A projection of all the columns in the Message table - */ - public static final String[] BT_MESSAGE_PROJECTION = new String[]{ - MessageColumns._ID, - MessageColumns.DATE, - MessageColumns.SUBJECT, - //TODO REMOVE WHEN Parts Table is in place - MessageColumns.BODY, - MessageColumns.MESSAGE_SIZE, - MessageColumns.FOLDER_ID, - MessageColumns.FLAG_READ, - MessageColumns.FLAG_PROTECTED, - MessageColumns.FLAG_HIGH_PRIORITY, - MessageColumns.FLAG_ATTACHMENT, - MessageColumns.ATTACHMENT_SIZE, - MessageColumns.FROM_LIST, - MessageColumns.TO_LIST, - MessageColumns.CC_LIST, - MessageColumns.BCC_LIST, - MessageColumns.REPLY_TO_LIST, - MessageColumns.RECEPTION_STATE, - MessageColumns.DEVILERY_STATE, - MessageColumns.THREAD_ID - }; - - public static final String[] BT_INSTANT_MESSAGE_PROJECTION = new String[]{ - MessageColumns._ID, - MessageColumns.DATE, - MessageColumns.SUBJECT, - MessageColumns.MESSAGE_SIZE, - MessageColumns.FOLDER_ID, - MessageColumns.FLAG_READ, - MessageColumns.FLAG_PROTECTED, - MessageColumns.FLAG_HIGH_PRIORITY, - MessageColumns.FLAG_ATTACHMENT, - MessageColumns.ATTACHMENT_SIZE, - MessageColumns.ATTACHMENT_MINE_TYPES, - MessageColumns.FROM_LIST, - MessageColumns.TO_LIST, - MessageColumns.RECEPTION_STATE, - MessageColumns.DEVILERY_STATE, - MessageColumns.THREAD_ID, - MessageColumns.THREAD_NAME - }; - - /** - * A projection of all the columns in the Account table - */ - public static final String[] BT_ACCOUNT_PROJECTION = new String[]{ - AccountColumns._ID, AccountColumns.ACCOUNT_DISPLAY_NAME, AccountColumns.FLAG_EXPOSE, - }; - - /** - * A projection of all the columns in the Account table - * TODO: Is this the way to differentiate - */ - public static final String[] BT_IM_ACCOUNT_PROJECTION = new String[]{ - AccountColumns._ID, - AccountColumns.ACCOUNT_DISPLAY_NAME, - AccountColumns.FLAG_EXPOSE, - AccountColumns.ACCOUNT_UCI, - AccountColumns.ACCOUNT_UCI_PREFIX - }; - - /** - * A projection of all the columns in the Folder table - */ - public static final String[] BT_FOLDER_PROJECTION = new String[]{ - FolderColumns._ID, - FolderColumns.NAME, - FolderColumns.ACCOUNT_ID, - FolderColumns.PARENT_FOLDER_ID - }; - - - /** - * A projection of all the columns in the Conversation table - */ - public static final String[] BT_CONVERSATION_PROJECTION = new String[]{ - /* Thread information */ - ConversationColumns.THREAD_ID, - ConversationColumns.THREAD_NAME, - ConversationColumns.READ_STATUS, - ConversationColumns.LAST_THREAD_ACTIVITY, - ConversationColumns.VERSION_COUNTER, - ConversationColumns.SUMMARY, - /* Contact information */ - ConversationColumns.UCI, - ConversationColumns.NAME, - ConversationColumns.NICKNAME, - ConversationColumns.CHAT_STATE, - ConversationColumns.LAST_ACTIVE, - ConversationColumns.X_BT_UID, - ConversationColumns.PRESENCE_STATE, - ConversationColumns.STATUS_TEXT, - ConversationColumns.PRIORITY - }; - - /** - * A projection of the Contact Info and Presence columns in the Contact Info in table - */ - public static final String[] BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION = new String[]{ - ConvoContactColumns.UCI, - ConvoContactColumns.CONVO_ID, - ConvoContactColumns.NAME, - ConvoContactColumns.NICKNAME, - ConvoContactColumns.X_BT_UID, - ConvoContactColumns.CHAT_STATE, - ConvoContactColumns.LAST_ACTIVE, - ConvoContactColumns.PRESENCE_STATE, - ConvoContactColumns.PRIORITY, - ConvoContactColumns.STATUS_TEXT, - ConvoContactColumns.LAST_ONLINE - }; - - /** - * A projection of the Contact Info the columns in Contacts Info table + * A projection of all the columns in the Account table TODO: Is this the way to differentiate */ - public static final String[] BT_CONTACT_PROJECTION = new String[]{ - ConvoContactColumns.UCI, - ConvoContactColumns.CONVO_ID, - ConvoContactColumns.X_BT_UID, - ConvoContactColumns.NAME, - ConvoContactColumns.NICKNAME - }; - - - /** - * A projection of all the columns in the Chat Status table - */ - public static final String[] BT_CHATSTATUS_PROJECTION = new String[]{ - ChatStatusColumns.CHAT_STATE, ChatStatusColumns.LAST_ACTIVE, - }; - - /** - * A projection of all the columns in the Presence table - */ - public static final String[] BT_PRESENCE_PROJECTION = new String[]{ - PresenceColumns.PRESENCE_STATE, - PresenceColumns.PRIORITY, - PresenceColumns.STATUS_TEXT, - PresenceColumns.LAST_ONLINE - }; - + public static final String[] BT_IM_ACCOUNT_PROJECTION = + new String[] { + AccountColumns._ID, + AccountColumns.ACCOUNT_DISPLAY_NAME, + AccountColumns.FLAG_EXPOSE, + AccountColumns.ACCOUNT_UCI, + AccountColumns.ACCOUNT_UCI_PREFIX + }; + + /** A projection of all the columns in the Folder table */ + public static final String[] BT_FOLDER_PROJECTION = + new String[] { + FolderColumns._ID, + FolderColumns.NAME, + FolderColumns.ACCOUNT_ID, + FolderColumns.PARENT_FOLDER_ID + }; + + /** A projection of all the columns in the Conversation table */ + public static final String[] BT_CONVERSATION_PROJECTION = + new String[] { + /* Thread information */ + ConversationColumns.THREAD_ID, + ConversationColumns.THREAD_NAME, + ConversationColumns.READ_STATUS, + ConversationColumns.LAST_THREAD_ACTIVITY, + ConversationColumns.VERSION_COUNTER, + ConversationColumns.SUMMARY, + /* Contact information */ + ConversationColumns.UCI, + ConversationColumns.NAME, + ConversationColumns.NICKNAME, + ConversationColumns.CHAT_STATE, + ConversationColumns.LAST_ACTIVE, + ConversationColumns.X_BT_UID, + ConversationColumns.PRESENCE_STATE, + ConversationColumns.STATUS_TEXT, + ConversationColumns.PRIORITY + }; + + /** A projection of the Contact Info and Presence columns in the Contact Info in table */ + public static final String[] BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION = + new String[] { + ConvoContactColumns.UCI, + ConvoContactColumns.CONVO_ID, + ConvoContactColumns.NAME, + ConvoContactColumns.NICKNAME, + ConvoContactColumns.X_BT_UID, + ConvoContactColumns.CHAT_STATE, + ConvoContactColumns.LAST_ACTIVE, + ConvoContactColumns.PRESENCE_STATE, + ConvoContactColumns.PRIORITY, + ConvoContactColumns.STATUS_TEXT, + ConvoContactColumns.LAST_ONLINE + }; + + /** A projection of the Contact Info the columns in Contacts Info table */ + public static final String[] BT_CONTACT_PROJECTION = + new String[] { + ConvoContactColumns.UCI, + ConvoContactColumns.CONVO_ID, + ConvoContactColumns.X_BT_UID, + ConvoContactColumns.NAME, + ConvoContactColumns.NICKNAME + }; + + /** A projection of all the columns in the Chat Status table */ + public static final String[] BT_CHATSTATUS_PROJECTION = + new String[] { + ChatStatusColumns.CHAT_STATE, ChatStatusColumns.LAST_ACTIVE, + }; + + /** A projection of all the columns in the Presence table */ + public static final String[] BT_PRESENCE_PROJECTION = + new String[] { + PresenceColumns.PRESENCE_STATE, + PresenceColumns.PRIORITY, + PresenceColumns.STATUS_TEXT, + PresenceColumns.LAST_ONLINE + }; } diff --git a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java index 29e2f0de639..a5ee32357f8 100644 --- a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java +++ b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java @@ -38,9 +38,8 @@ import java.util.List; import java.util.Map; /** - * A base implementation of the BluetoothMapEmailContract. - * A base class for a ContentProvider that allows access to Email messages from a Bluetooth - * device through the Message Access Profile. + * A base implementation of the BluetoothMapEmailContract. A base class for a ContentProvider that + * allows access to Email messages from a Bluetooth device through the Message Access Profile. */ public abstract class BluetoothMapEmailProvider extends ContentProvider { @@ -57,32 +56,35 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { private String mAuthority; private UriMatcher mMatcher; - private PipeReader mPipeReader = new PipeReader(); private PipeWriter mPipeWriter = new PipeWriter(); /** * Write the content of a message to a stream as MIME encoded RFC-2822 data. + * * @param accountId the ID of the account to which the message belong * @param messageId the ID of the message to write to the stream * @param includeAttachment true if attachments should be included - * @param download true if any missing part of the message shall be downloaded - * before written to the stream. The download flag will determine - * whether or not attachments shall be downloaded or only the message content. + * @param download true if any missing part of the message shall be downloaded before written to + * the stream. The download flag will determine whether or not attachments shall be + * downloaded or only the message content. * @param out the FileOurputStream to write to. * @throws IOException */ - protected abstract void WriteMessageToStream(long accountId, long messageId, - boolean includeAttachment, boolean download, FileOutputStream out) throws IOException; + protected abstract void WriteMessageToStream( + long accountId, + long messageId, + boolean includeAttachment, + boolean download, + FileOutputStream out) + throws IOException; /** * @return the CONTENT_URI exposed. This will be used to send out notifications. */ protected abstract Uri getContentUri(); - /** - * Implementation is provided by the parent class. - */ + /** Implementation is provided by the parent class. */ @Override public void attachInfo(Context context, ProviderInfo info) { mAuthority = info.authority; @@ -105,37 +107,35 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { super.attachInfo(context, info); } - /** - * Interface to write a stream of data to a pipe. Use with - * {@link ContentProvider#openPipeHelper}. + * Interface to write a stream of data to a pipe. Use with {@link + * ContentProvider#openPipeHelper}. */ public interface PipeDataReader { /** - * Called from a background thread to stream data from a pipe. - * Note that the pipe is blocking, so this thread can block on - * reads for an arbitrary amount of time if the client is slow - * at writing. + * Called from a background thread to stream data from a pipe. Note that the pipe is + * blocking, so this thread can block on reads for an arbitrary amount of time if the client + * is slow at writing. * - * @param input The pipe where data should be read. This will be - * closed for you upon returning from this function. + * @param input The pipe where data should be read. This will be closed for you upon + * returning from this function. * @param uri The URI whose data is to be written. * @param mimeType The desired type of data to be written. * @param opts Options supplied by caller. * @param args Your own custom arguments. */ - void readDataFromPipe(ParcelFileDescriptor input, Uri uri, String mimeType, Bundle opts, - T args); + void readDataFromPipe( + ParcelFileDescriptor input, Uri uri, String mimeType, Bundle opts, T args); } public class PipeReader implements PipeDataReader { /** - * Read the data from the pipe and generate a message. - * Use the message to do an update of the message specified by the URI. + * Read the data from the pipe and generate a message. Use the message to do an update of + * the message specified by the URI. */ @Override - public void readDataFromPipe(ParcelFileDescriptor input, Uri uri, String mimeType, - Bundle opts, Cursor args) { + public void readDataFromPipe( + ParcelFileDescriptor input, Uri uri, String mimeType, Bundle opts, Cursor args) { Log.v(TAG, "readDataFromPipe(): uri=" + uri.toString()); FileInputStream fIn = null; try { @@ -162,29 +162,30 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * Read a MIME encoded RFC-2822 fileStream and update the message content. - * The Date and/or From headers may not be present in the MIME encoded - * message, and this function shall add appropriate values if the headers - * are missing. From should be set to the owner of the account. + * Read a MIME encoded RFC-2822 fileStream and update the message content. The Date and/or From + * headers may not be present in the MIME encoded message, and this function shall add + * appropriate values if the headers are missing. From should be set to the owner of the + * account. * * @param input the file stream to read data from * @param accountId the accountId * @param messageId ID of the message to update */ - protected abstract void UpdateMimeMessageFromStream(FileInputStream input, long accountId, - long messageId) throws IOException; + protected abstract void UpdateMimeMessageFromStream( + FileInputStream input, long accountId, long messageId) throws IOException; public class PipeWriter implements PipeDataWriter { - /** - * Generate a message based on the cursor, and write the encoded data to the stream. - */ - + /** Generate a message based on the cursor, and write the encoded data to the stream. */ @Override - public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType, - Bundle opts, Cursor c) { + public void writeDataToPipe( + ParcelFileDescriptor output, Uri uri, String mimeType, Bundle opts, Cursor c) { if (D) { - Log.d(TAG, "writeDataToPipe(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + Log.d( + TAG, + "writeDataToPipe(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); } FileOutputStream fout = null; @@ -232,10 +233,11 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * This function shall be called when any Account database content have changed - * to Notify any attached observers. - * @param accountId the ID of the account that changed. Null is a valid value, - * if accountId is unknown or multiple accounts changed. + * This function shall be called when any Account database content have changed to Notify any + * attached observers. + * + * @param accountId the ID of the account that changed. Null is a valid value, if accountId is + * unknown or multiple accounts changed. */ protected void onAccountChanged(String accountId) { Uri newUri = null; @@ -255,12 +257,13 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * This function shall be called when any Message database content have changed - * to notify any attached observers. - * @param accountId Null is a valid value, if accountId is unknown, but - * recommended for increased performance. - * @param messageId Null is a valid value, if multiple messages changed or the - * messageId is unknown, but recommended for increased performance. + * This function shall be called when any Message database content have changed to notify any + * attached observers. + * + * @param accountId Null is a valid value, if accountId is unknown, but recommended for + * increased performance. + * @param messageId Null is a valid value, if multiple messages changed or the messageId is + * unknown, but recommended for increased performance. */ protected void onMessageChanged(String accountId, String messageId) { Uri newUri = null; @@ -275,61 +278,65 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { if (messageId == null) { newUri = BluetoothMapContract.buildMessageUri(mAuthority, accountId); } else { - newUri = BluetoothMapContract.buildMessageUriWithId(mAuthority, accountId, - messageId); + newUri = + BluetoothMapContract.buildMessageUriWithId( + mAuthority, accountId, messageId); } } if (D) { - Log.d(TAG, "onMessageChanged() accountId = " + accountId + " messageId = " + messageId - + " URI: " + newUri); + Log.d( + TAG, + "onMessageChanged() accountId = " + + accountId + + " messageId = " + + messageId + + " URI: " + + newUri); } mResolver.notifyChange(newUri, null); } - /** - * Not used, this is just a dummy implementation. - */ + /** Not used, this is just a dummy implementation. */ @Override public String getType(Uri uri) { return "Email"; } /** - * Open a file descriptor to a message. - * Two modes supported for read: With and without attachments. - * One mode exist for write and the actual content will be with or without + * Open a file descriptor to a message. Two modes supported for read: With and without + * attachments. One mode exist for write and the actual content will be with or without * attachments. * - * Mode will be "r" or "w". + *

Mode will be "r" or "w". * - * URI format: - * The URI scheme is as follows. - * For messages with attachments: - * content://com.android.mail.bluetoothprovider/Messages/msgId# + *

URI format: The URI scheme is as follows. For messages with attachments: + * content://com.android.mail.bluetoothprovider/Messages/msgId# * - * For messages without attachments: - * content://com.android.mail.bluetoothprovider/Messages/msgId#/NO_ATTACHMENTS + *

For messages without attachments: + * content://com.android.mail.bluetoothprovider/Messages/msgId#/NO_ATTACHMENTS * - * UPDATE: For write. - * First create a message in the DB using insert into the message DB - * Then open a file handle to the #id - * write the data to a stream created from the fileHandle. + *

UPDATE: For write. First create a message in the DB using insert into the message DB Then + * open a file handle to the #id write the data to a stream created from the fileHandle. * * @param uri the URI to open. ../Messages/#id - * @param mode the mode to use. The following modes exist: - UPDATE do not work - use URI - * - "read_with_attachments" - to read an e-mail including any attachments - * - "read_no_attachments" - to read an e-mail excluding any attachments - * - "write" - to add a mime encoded message to the database. This write - * should not trigger the message to be send. + * @param mode the mode to use. The following modes exist: - UPDATE do not work - use URI - + * "read_with_attachments" - to read an e-mail including any attachments - + * "read_no_attachments" - to read an e-mail excluding any attachments - "write" - to add a + * mime encoded message to the database. This write should not trigger the message to be + * send. * @return the ParcelFileDescriptor - * @throws FileNotFoundException + * @throws FileNotFoundException */ @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { final long callingId = Binder.clearCallingIdentity(); if (D) { - Log.d(TAG, "openFile(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + Log.d( + TAG, + "openFile(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); } try { /* To be able to do abstraction of the file IO, we simply ignore the URI at this @@ -348,40 +355,42 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * A helper function for implementing {@link #openFile}, for - * creating a data pipe and background thread allowing you to stream - * data back from the client. This function returns a new - * ParcelFileDescriptor that should be returned to the caller (the caller - * is responsible for closing it). + * A helper function for implementing {@link #openFile}, for creating a data pipe and background + * thread allowing you to stream data back from the client. This function returns a new + * ParcelFileDescriptor that should be returned to the caller (the caller is responsible for + * closing it). * * @param uri The URI whose data is to be written. * @param mimeType The desired type of data to be written. * @param opts Options supplied by caller. * @param args Your own custom arguments. - * @param func Interface implementing the function that will actually - * stream the data. - * @return Returns a new ParcelFileDescriptor holding the read side of - * the pipe. This should be returned to the caller for reading; the caller - * is responsible for closing it when done. + * @param func Interface implementing the function that will actually stream the data. + * @return Returns a new ParcelFileDescriptor holding the read side of the pipe. This should be + * returned to the caller for reading; the caller is responsible for closing it when done. */ - private ParcelFileDescriptor openInversePipeHelper(final Uri uri, final String mimeType, - final Bundle opts, final T args, final PipeDataReader func) + private ParcelFileDescriptor openInversePipeHelper( + final Uri uri, + final String mimeType, + final Bundle opts, + final T args, + final PipeDataReader func) throws FileNotFoundException { try { final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe(); - AsyncTask task = new AsyncTask() { - @Override - protected Object doInBackground(Object... params) { - func.readDataFromPipe(fds[0], uri, mimeType, opts, args); - try { - fds[0].close(); - } catch (IOException e) { - Log.w(TAG, "Failure closing pipe", e); - } - return null; - } - }; + AsyncTask task = + new AsyncTask() { + @Override + protected Object doInBackground(Object... params) { + func.readDataFromPipe(fds[0], uri, mimeType, opts, args); + try { + fds[0].close(); + } catch (IOException e) { + Log.w(TAG, "Failure closing pipe", e); + } + return null; + } + }; task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[]) null); return fds[1]; @@ -392,9 +401,8 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { /** * The MAP specification states that a delete request from MAP client is a folder shift to the - * 'deleted' folder. - * Only use case of delete() is when transparency is requested for push messages, then - * message should not remain in sent folder and therefore must be deleted + * 'deleted' folder. Only use case of delete() is when transparency is requested for push + * messages, then message should not remain in sent folder and therefore must be deleted */ @Override public int delete(Uri uri, String where, String[] selectionArgs) { @@ -413,7 +421,6 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { throw new IllegalArgumentException("Message ID missing in update values!"); } - String accountId = getAccountId(uri); if (accountId == null) { throw new IllegalArgumentException("Account ID missing in update values!"); @@ -436,6 +443,7 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { /** * This function deletes a message. + * * @param accountId the ID of the Account * @param messageId the ID of the message to delete. * @return the number of messages deleted - 0 if the message was not found. @@ -443,12 +451,9 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { protected abstract int deleteMessage(String accountId, String messageId); /** - * Insert is used to add new messages to the data base. - * Insert message approach: - * - Insert an empty message to get an _id with only a folder_id - * - Open the _id for write - * - Write the message content - * (When the writer completes, this provider should do an update of the message) + * Insert is used to add new messages to the data base. Insert message approach: - Insert an + * empty message to get an _id with only a folder_id - Open the _id for write - Write the + * message content (When the writer completes, this provider should do an update of the message) */ @Override public Uri insert(Uri uri, ContentValues values) { @@ -464,8 +469,12 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { String id; // the id of the entry inserted into the database final long callingId = Binder.clearCallingIdentity(); - Log.d(TAG, "insert(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + Log.d( + TAG, + "insert(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); try { if (table.equals(BluetoothMapContract.TABLE_MESSAGE)) { id = insertMessage(accountId, folderId.toString()); @@ -482,10 +491,10 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } } - /** - * Inserts an empty message into the Message data base in the specified folder. - * This is done before the actual message content is written by fileIO. + * Inserts an empty message into the Message data base in the specified folder. This is done + * before the actual message content is written by fileIO. + * * @param accountId the ID of the account * @param folderId the ID of the folder to create a new message in. * @return the message id as a string @@ -495,9 +504,10 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { /** * Utility function to build a projection based on a projectionMap. * - * "btColumnName" -> "emailColumnName as btColumnName" for each entry. + *

"btColumnName" -> "emailColumnName as btColumnName" for each entry. + * + *

This supports SQL statements in the emailColumnName entry. * - * This supports SQL statements in the emailColumnName entry. * @param projection * @param projectionMap * @return the converted projection @@ -511,11 +521,15 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * This query needs to map from the data used in the e-mail client to BluetoothMapContract - * type of data. + * This query needs to map from the data used in the e-mail client to BluetoothMapContract type + * of data. */ @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { final long callingId = Binder.clearCallingIdentity(); try { @@ -538,21 +552,22 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * Query account information. - * This function shall return only exposable e-mail accounts. Hence shall not - * return accounts that has policies suggesting not to be shared them. + * Query account information. This function shall return only exposable e-mail accounts. Hence + * shall not return accounts that has policies suggesting not to be shared them. + * * @param projection * @param selection * @param selectionArgs * @param sortOrder * @return a cursor to the accounts that are subject to exposure over BT. */ - protected abstract Cursor queryAccount(String[] projection, String selection, - String[] selectionArgs, String sortOrder); + protected abstract Cursor queryAccount( + String[] projection, String selection, String[] selectionArgs, String sortOrder); /** - * Filter out the non usable folders and ensure to name the mandatory folders - * inbox, outbox, sent, deleted and draft. + * Filter out the non usable folders and ensure to name the mandatory folders inbox, outbox, + * sent, deleted and draft. + * * @param accountId * @param projection * @param selection @@ -560,20 +575,20 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { * @param sortOrder * @return */ - protected abstract Cursor queryFolder(String accountId, String[] projection, String selection, - String[] selectionArgs, String sortOrder); + protected abstract Cursor queryFolder( + String accountId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder); /** * For the message table the selection (where clause) can only include the following columns: - * date: less than, greater than and equals - * flagRead: = 1 or = 0 - * flagPriority: = 1 or = 0 - * folder_id: the ID of the folder only equals - * toList: partial name/address search - * ccList: partial name/address search - * bccList: partial name/address search - * fromList: partial name/address search - * Additionally the COUNT and OFFSET shall be supported. + * date: less than, greater than and equals flagRead: = 1 or = 0 flagPriority: = 1 or = 0 + * folder_id: the ID of the folder only equals toList: partial name/address search ccList: + * partial name/address search bccList: partial name/address search fromList: partial + * name/address search Additionally the COUNT and OFFSET shall be supported. + * * @param accountId the ID of the account * @param projection * @param selection @@ -581,18 +596,19 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { * @param sortOrder * @return a cursor to query result */ - protected abstract Cursor queryMessage(String accountId, String[] projection, String selection, - String[] selectionArgs, String sortOrder); + protected abstract Cursor queryMessage( + String accountId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder); /** - * update() - * Messages can be modified in the following cases: - * - the folder_key of a message - hence the message can be moved to a new folder, - * but the content cannot be modified. - * - the FLAG_READ state can be changed. - * The selection statement will always be selection of a message ID, when updating a message, - * hence this function will be called multiple times if multiple messages must be updated - * due to the nature of the Bluetooth Message Access profile. + * update() Messages can be modified in the following cases: - the folder_key of a message - + * hence the message can be moved to a new folder, but the content cannot be modified. - the + * FLAG_READ state can be changed. The selection statement will always be selection of a message + * ID, when updating a message, hence this function will be called multiple times if multiple + * messages must be updated due to the nature of the Bluetooth Message Access profile. */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { @@ -608,8 +624,12 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { final long callingId = Binder.clearCallingIdentity(); if (D) { - Log.w(TAG, "update(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + Log.w( + TAG, + "update(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); } try { if (table.equals(BluetoothMapContract.TABLE_ACCOUNT)) { @@ -647,8 +667,9 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { } /** - * Update an entry in the account table. Only the expose flag will be - * changed through this interface. + * Update an entry in the account table. Only the expose flag will be changed through this + * interface. + * * @param accountId the ID of the account to change. * @param flagExpose the updated value. * @return the number of entries changed - 0 if account not found or value cannot be changed. @@ -657,22 +678,28 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { /** * Update an entry in the message table. + * * @param accountId ID of the account to which the messageId relates * @param messageId the ID of the message to update * @param folderId the new folder ID value to set - ignore if null. * @param flagRead the new flagRead value to set - ignore if null. * @return */ - protected abstract int updateMessage(String accountId, Long messageId, Long folderId, - Boolean flagRead); - + protected abstract int updateMessage( + String accountId, Long messageId, Long folderId, Boolean flagRead); @Override public Bundle call(String method, String arg, Bundle extras) { final long callingId = Binder.clearCallingIdentity(); if (D) { - Log.d(TAG, "call(): method=" + method + " arg=" + arg + "ThreadId: " - + Thread.currentThread().getId()); + Log.d( + TAG, + "call(): method=" + + method + + " arg=" + + arg + + "ThreadId: " + + Thread.currentThread().getId()); } try { @@ -701,23 +728,20 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider { /** * Trigger a sync of the specified folder. + * * @param accountId the ID of the account that owns the folder * @param folderId the ID of the folder. * @return 0 at success */ protected abstract int syncFolder(long accountId, long folderId); - /** - * Need this to suppress warning in unit tests. - */ + /** Need this to suppress warning in unit tests. */ @Override public void shutdown() { // Don't call super.shutdown(), which emits a warning... } - /** - * Extract the BluetoothMapContract.AccountColumns._ID from the given URI. - */ + /** Extract the BluetoothMapContract.AccountColumns._ID from the given URI. */ public static String getAccountId(Uri uri) { final List segments = uri.getPathSegments(); if (segments.size() < 1) { diff --git a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java index e0e3a5e74cd..7e4e8d7640c 100644 --- a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java +++ b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.mapapi; @@ -33,9 +33,8 @@ import java.util.Map.Entry; import java.util.Set; /** - * A base implementation of the BluetoothMapContract. - * A base class for a ContentProvider that allows access to Instant messages from a Bluetooth - * device through the Message Access Profile. + * A base implementation of the BluetoothMapContract. A base class for a ContentProvider that allows + * access to Instant messages from a Bluetooth device through the Message Access Profile. */ public abstract class BluetoothMapIMProvider extends ContentProvider { @@ -58,9 +57,7 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { */ protected abstract Uri getContentUri(); - /** - * Implementation is provided by the parent class. - */ + /** Implementation is provided by the parent class. */ @Override public void attachInfo(Context context, ProviderInfo info) { mAuthority = info.authority; @@ -68,10 +65,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { mMatcher = new UriMatcher(UriMatcher.NO_MATCH); mMatcher.addURI(mAuthority, BluetoothMapContract.TABLE_ACCOUNT, MATCH_ACCOUNT); mMatcher.addURI(mAuthority, "#/" + BluetoothMapContract.TABLE_MESSAGE, MATCH_MESSAGE); - mMatcher.addURI(mAuthority, "#/" + BluetoothMapContract.TABLE_CONVERSATION, - MATCH_CONVERSATION); - mMatcher.addURI(mAuthority, "#/" + BluetoothMapContract.TABLE_CONVOCONTACT, - MATCH_CONVOCONTACT); + mMatcher.addURI( + mAuthority, "#/" + BluetoothMapContract.TABLE_CONVERSATION, MATCH_CONVERSATION); + mMatcher.addURI( + mAuthority, "#/" + BluetoothMapContract.TABLE_CONVOCONTACT, MATCH_CONVOCONTACT); // Sanity check our setup if (!info.exported) { @@ -91,10 +88,11 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { } /** - * This function shall be called when any Account database content have changed - * to Notify any attached observers. - * @param accountId the ID of the account that changed. Null is a valid value, - * if accountId is unknown or multiple accounts changed. + * This function shall be called when any Account database content have changed to Notify any + * attached observers. + * + * @param accountId the ID of the account that changed. Null is a valid value, if accountId is + * unknown or multiple accounts changed. */ protected void onAccountChanged(String accountId) { Uri newUri = null; @@ -115,12 +113,13 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { } /** - * This function shall be called when any Message database content have changed - * to notify any attached observers. - * @param accountId Null is a valid value, if accountId is unknown, but - * recommended for increased performance. - * @param messageId Null is a valid value, if multiple messages changed or the - * messageId is unknown, but recommended for increased performance. + * This function shall be called when any Message database content have changed to notify any + * attached observers. + * + * @param accountId Null is a valid value, if accountId is unknown, but recommended for + * increased performance. + * @param messageId Null is a valid value, if multiple messages changed or the messageId is + * unknown, but recommended for increased performance. */ protected void onMessageChanged(String accountId, String messageId) { Uri newUri = null; @@ -134,25 +133,32 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { if (messageId == null) { newUri = BluetoothMapContract.buildMessageUri(mAuthority, accountId); } else { - newUri = BluetoothMapContract.buildMessageUriWithId(mAuthority, accountId, - messageId); + newUri = + BluetoothMapContract.buildMessageUriWithId( + mAuthority, accountId, messageId); } } if (D) { - Log.d(TAG, "onMessageChanged() accountId = " + accountId + " messageId = " + messageId - + " URI: " + newUri); + Log.d( + TAG, + "onMessageChanged() accountId = " + + accountId + + " messageId = " + + messageId + + " URI: " + + newUri); } mResolver.notifyChange(newUri, null); } - /** - * This function shall be called when any Message database content have changed - * to notify any attached observers. - * @param accountId Null is a valid value, if accountId is unknown, but - * recommended for increased performance. - * @param contactId Null is a valid value, if multiple contacts changed or the - * contactId is unknown, but recommended for increased performance. + * This function shall be called when any Message database content have changed to notify any + * attached observers. + * + * @param accountId Null is a valid value, if accountId is unknown, but recommended for + * increased performance. + * @param contactId Null is a valid value, if multiple contacts changed or the contactId is + * unknown, but recommended for increased performance. */ protected void onContactChanged(String accountId, String contactId) { Uri newUri = null; @@ -166,20 +172,27 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { if (contactId == null) { newUri = BluetoothMapContract.buildConvoContactsUri(mAuthority, accountId); } else { - newUri = BluetoothMapContract.buildConvoContactsUriWithId(mAuthority, accountId, - contactId); + newUri = + BluetoothMapContract.buildConvoContactsUriWithId( + mAuthority, accountId, contactId); } } if (D) { - Log.d(TAG, "onContactChanged() accountId = " + accountId + " contactId = " + contactId - + " URI: " + newUri); + Log.d( + TAG, + "onContactChanged() accountId = " + + accountId + + " contactId = " + + contactId + + " URI: " + + newUri); } mResolver.notifyChange(newUri, null); } /** - * Not used, this is just a dummy implementation. - * TODO: We might need to something intelligent here after introducing IM + * Not used, this is just a dummy implementation. TODO: We might need to something intelligent + * here after introducing IM */ @Override public String getType(Uri uri) { @@ -188,9 +201,8 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { /** * The MAP specification states that a delete request from MAP client is a folder shift to the - * 'deleted' folder. - * Only use case of delete() is when transparency is requested for push messages, then - * message should not remain in sent folder and therefore must be deleted + * 'deleted' folder. Only use case of delete() is when transparency is requested for push + * messages, then message should not remain in sent folder and therefore must be deleted */ @Override public int delete(Uri uri, String where, String[] selectionArgs) { @@ -231,6 +243,7 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { /** * This function deletes a message. + * * @param accountId the ID of the Account * @param messageId the ID of the message to delete. * @return the number of messages deleted - 0 if the message was not found. @@ -238,12 +251,9 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { protected abstract int deleteMessage(String accountId, String messageId); /** - * Insert is used to add new messages to the data base. - * Insert message approach: - * - Insert an empty message to get an _id with only a folder_id - * - Open the _id for write - * - Write the message content - * (When the writer completes, this provider should do an update of the message) + * Insert is used to add new messages to the data base. Insert message approach: - Insert an + * empty message to get an _id with only a folder_id - Open the _id for write - Write the + * message content (When the writer completes, this provider should do an update of the message) */ @Override public Uri insert(Uri uri, ContentValues values) { @@ -261,8 +271,12 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { String id; // the id of the entry inserted into the database final long callingId = Binder.clearCallingIdentity(); - Log.d(TAG, "insert(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + Log.d( + TAG, + "insert(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); try { if (table.equals(BluetoothMapContract.TABLE_MESSAGE)) { id = insertMessage(accountId, values); @@ -279,10 +293,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { } } - /** - * Inserts an empty message into the Message data base in the specified folder. - * This is done before the actual message content is written by fileIO. + * Inserts an empty message into the Message data base in the specified folder. This is done + * before the actual message content is written by fileIO. + * * @param accountId the ID of the account * @param folderId the ID of the folder to create a new message in. * @return the message id as a string @@ -292,9 +306,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { /** * Utility function to build a projection based on a projectionMap. * - * "btColumnName" -> "imColumnName as btColumnName" for each entry. + *

"btColumnName" -> "imColumnName as btColumnName" for each entry. + * + *

This supports SQL statements in the column name entry. * - * This supports SQL statements in the column name entry. * @param projection * @param projectionMap * @return the converted projection @@ -308,11 +323,15 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { } /** - * This query needs to map from the data used in the e-mail client to - * BluetoothMapContract type of data. + * This query needs to map from the data used in the e-mail client to BluetoothMapContract type + * of data. */ @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { final long callingId = Binder.clearCallingIdentity(); try { @@ -353,13 +372,20 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { if (value != null) { threadId = Long.parseLong(value); } - return queryConversation(accountId, threadId, read, periodEnd, periodBegin, - searchString, projection, sortOrder); + return queryConversation( + accountId, + threadId, + read, + periodEnd, + periodBegin, + searchString, + projection, + sortOrder); case MATCH_CONVOCONTACT: accountId = getAccountId(uri); long contactId = 0; - return queryConvoContact(accountId, contactId, projection, selection, - selectionArgs, sortOrder); + return queryConvoContact( + accountId, contactId, projection, selection, selectionArgs, sortOrder); default: throw new UnsupportedOperationException("Unsupported Uri " + uri); } @@ -369,27 +395,24 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { } /** - * Query account information. - * This function shall return only exposable e-mail accounts. Hence shall not - * return accounts that has policies suggesting not to be shared them. + * Query account information. This function shall return only exposable e-mail accounts. Hence + * shall not return accounts that has policies suggesting not to be shared them. + * * @param projection * @param selection * @param selectionArgs * @param sortOrder * @return a cursor to the accounts that are subject to exposure over BT. */ - protected abstract Cursor queryAccount(String[] projection, String selection, - String[] selectionArgs, String sortOrder); + protected abstract Cursor queryAccount( + String[] projection, String selection, String[] selectionArgs, String sortOrder); /** * For the message table the selection (where clause) can only include the following columns: - * date: less than, greater than and equals - * flagRead: = 1 or = 0 - * flagPriority: = 1 or = 0 - * folder_id: the ID of the folder only equals - * toList: partial name/address search - * fromList: partial name/address search - * Additionally the COUNT and OFFSET shall be supported. + * date: less than, greater than and equals flagRead: = 1 or = 0 flagPriority: = 1 or = 0 + * folder_id: the ID of the folder only equals toList: partial name/address search fromList: + * partial name/address search Additionally the COUNT and OFFSET shall be supported. + * * @param accountId the ID of the account * @param projection * @param selection @@ -397,17 +420,19 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { * @param sortOrder * @return a cursor to query result */ - protected abstract Cursor queryMessage(String accountId, String[] projection, String selection, - String[] selectionArgs, String sortOrder); + protected abstract Cursor queryMessage( + String accountId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder); /** - * For the Conversation table the selection (where clause) can only include - * the following columns: - * _id: the ID of the conversation only equals - * name: partial name search - * last_activity: less than, greater than and equals - * version_counter: updated IDs are regenerated - * Additionally the COUNT and OFFSET shall be supported. + * For the Conversation table the selection (where clause) can only include the following + * columns: _id: the ID of the conversation only equals name: partial name search last_activity: + * less than, greater than and equals version_counter: updated IDs are regenerated Additionally + * the COUNT and OFFSET shall be supported. + * * @param accountId the ID of the account * @param threadId the ID of the conversation * @param projection @@ -416,51 +441,46 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { * @param sortOrder * @return a cursor to query result */ -// abstract protected Cursor queryConversation(Long threadId, String[] projection, -// String selection, String[] selectionArgs, String sortOrder); + // abstract protected Cursor queryConversation(Long threadId, String[] projection, + // String selection, String[] selectionArgs, String sortOrder); /** - * Query for conversations with contact information. The expected result is a cursor pointing - * to one row for each contact in a conversation. - * E.g.: - * ThreadId | ThreadName | ... | ContactName | ContactPrecence | ... | - * 1 | "Bowling" | ... | Hans | 1 | ... | - * 1 | "Bowling" | ... | Peter | 2 | ... | - * 2 | "" | ... | Peter | 2 | ... | - * 3 | "" | ... | Hans | 1 | ... | + * Query for conversations with contact information. The expected result is a cursor pointing to + * one row for each contact in a conversation. E.g.: ThreadId | ThreadName | ... | ContactName | + * ContactPrecence | ... | 1 | "Bowling" | ... | Hans | 1 | ... | 1 | "Bowling" | ... | Peter | + * 2 | ... | 2 | "" | ... | Peter | 2 | ... | 3 | "" | ... | Hans | 1 | ... | * * @param accountId the ID of the account * @param threadId filter on a single threadId - null if no filtering is needed. - * @param read filter on a read status: - * null: no filtering on read is needed. - * true: return only threads that has NO unread messages. - * false: return only threads that has unread messages. - * @param periodEnd last_activity time stamp of the the newest thread to include in the - * result. + * @param read filter on a read status: null: no filtering on read is needed. true: return only + * threads that has NO unread messages. false: return only threads that has unread messages. + * @param periodEnd last_activity time stamp of the the newest thread to include in the result. * @param periodBegin last_activity time stamp of the the oldest thread to include in the - * result. + * result. * @param searchString if not null, include only threads that has contacts that matches the - * searchString as part of the contact name or nickName. + * searchString as part of the contact name or nickName. * @param projection A list of the columns that is needed in the result - * @param sortOrder the sort order + * @param sortOrder the sort order * @return a Cursor representing the query result. */ - protected abstract Cursor queryConversation(String accountId, Long threadId, Boolean read, - Long periodEnd, Long periodBegin, String searchString, String[] projection, + protected abstract Cursor queryConversation( + String accountId, + Long threadId, + Boolean read, + Long periodEnd, + Long periodBegin, + String searchString, + String[] projection, String sortOrder); /** - * For the ConvoContact table the selection (where clause) can only include the - * following columns: - * _id: the ID of the contact only equals - * convo_id: id of conversation contact is part of - * name: partial name search - * x_bt_uid: the ID of the bt uid only equals - * chat_state: active, inactive, gone, composing, paused - * last_active: less than, greater than and equals - * presence_state: online, do_not_disturb, away, offline - * priority: level of priority 0 - 100 - * last_online: less than, greater than and equals + * For the ConvoContact table the selection (where clause) can only include the following + * columns: _id: the ID of the contact only equals convo_id: id of conversation contact is part + * of name: partial name search x_bt_uid: the ID of the bt uid only equals chat_state: active, + * inactive, gone, composing, paused last_active: less than, greater than and equals + * presence_state: online, do_not_disturb, away, offline priority: level of priority 0 - 100 + * last_online: less than, greater than and equals + * * @param accountId the ID of the account * @param contactId the ID of the contact * @param projection @@ -469,27 +489,27 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { * @param sortOrder * @return a cursor to query result */ - protected abstract Cursor queryConvoContact(String accountId, Long contactId, - String[] projection, String selection, String[] selectionArgs, String sortOrder); + protected abstract Cursor queryConvoContact( + String accountId, + Long contactId, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder); /** - * update() - * Messages can be modified in the following cases: - * - the folder_key of a message - hence the message can be moved to a new folder, - * but the content cannot be modified. - * - the FLAG_READ state can be changed. - * Conversations can be modified in the following cases: - * - the read status - changing between read, unread - * - the last activity - the time stamp of last message sent of received in the conversation - * ConvoContacts can be modified in the following cases: - * - the chat_state - chat status of the contact in conversation - * - the last_active - the time stamp of last action in the conversation - * - the presence_state - the time stamp of last time contact online - * - the status - the status text of the contact available in a conversation - * - the last_online - the time stamp of last time contact online - * The selection statement will always be selection of a message ID, when updating a message, - * hence this function will be called multiple times if multiple messages must be updated - * due to the nature of the Bluetooth Message Access profile. + * update() Messages can be modified in the following cases: - the folder_key of a message - + * hence the message can be moved to a new folder, but the content cannot be modified. - the + * FLAG_READ state can be changed. Conversations can be modified in the following cases: - the + * read status - changing between read, unread - the last activity - the time stamp of last + * message sent of received in the conversation ConvoContacts can be modified in the following + * cases: - the chat_state - chat status of the contact in conversation - the last_active - the + * time stamp of last action in the conversation - the presence_state - the time stamp of last + * time contact online - the status - the status text of the contact available in a conversation + * - the last_online - the time stamp of last time contact online The selection statement will + * always be selection of a message ID, when updating a message, hence this function will be + * called multiple times if multiple messages must be updated due to the nature of the Bluetooth + * Message Access profile. */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { @@ -505,8 +525,12 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { final long callingId = Binder.clearCallingIdentity(); if (D) { - Log.w(TAG, "update(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + Log.w( + TAG, + "update(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); } try { if (table.equals(BluetoothMapContract.TABLE_ACCOUNT)) { @@ -551,8 +575,9 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { } /** - * Update an entry in the account table. Only the expose flag will be - * changed through this interface. + * Update an entry in the account table. Only the expose flag will be changed through this + * interface. + * * @param accountId the ID of the account to change. * @param flagExpose the updated value. * @return the number of entries changed - 0 if account not found or value cannot be changed. @@ -561,26 +586,27 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { /** * Update an entry in the message table. + * * @param accountId ID of the account to which the messageId relates * @param messageId the ID of the message to update * @param folderId the new folder ID value to set - ignore if null. * @param flagRead the new flagRead value to set - ignore if null. * @return */ - protected abstract int updateMessage(String accountId, Long messageId, Long folderId, - Boolean flagRead); + protected abstract int updateMessage( + String accountId, Long messageId, Long folderId, Boolean flagRead); /** - * Utility function to Creates a ContentValues object based on a modified valuesSet. - * To be used after changing the keys and optionally values of a valueSet obtained - * from a ContentValues object received in update(). + * Utility function to Creates a ContentValues object based on a modified valuesSet. To be used + * after changing the keys and optionally values of a valueSet obtained from a ContentValues + * object received in update(). + * * @param valueSet the values as received in the contentProvider * @param keyMap the key map - * @return a new ContentValues object with the keys replaced as specified in the - * keyMap + * @return a new ContentValues object with the keys replaced as specified in the keyMap */ - protected ContentValues createContentValues(Set> valueSet, - Map keyMap) { + protected ContentValues createContentValues( + Set> valueSet, Map keyMap) { ContentValues values = new ContentValues(valueSet.size()); for (Entry ent : valueSet) { String key = keyMap.get(ent.getKey()); // Convert the key name @@ -616,8 +642,14 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { public Bundle call(String method, String arg, Bundle extras) { final long callingId = Binder.clearCallingIdentity(); if (D) { - Log.w(TAG, "call(): method=" + method + " arg=" + arg + "ThreadId: " - + Thread.currentThread().getId()); + Log.w( + TAG, + "call(): method=" + + method + + " arg=" + + arg + + "ThreadId: " + + Thread.currentThread().getId()); } int ret = -1; try { @@ -658,6 +690,7 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { /** * Trigger a sync of the specified folder. + * * @param accountId the ID of the account that owns the folder * @param folderId the ID of the folder. * @return 0 at success @@ -665,9 +698,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { protected abstract int syncFolder(long accountId, long folderId); /** - * Set the properties that should change presence or chat state of owner - * e.g. when the owner is active on a BT client device but not on the BT server device - * where the IM application is installed, it should still be possible to show an active status. + * Set the properties that should change presence or chat state of owner e.g. when the owner is + * active on a BT client device but not on the BT server device where the IM application is + * installed, it should still be possible to show an active status. + * * @param presenceState should follow the contract specified values * @param presenceStatus string the owners current status * @param lastActive time stamp of the owners last activity @@ -675,28 +709,28 @@ public abstract class BluetoothMapIMProvider extends ContentProvider { * @param convoId ID to the conversation to change * @return 0 at success */ - protected abstract int setOwnerStatus(int presenceState, String presenceStatus, long lastActive, - int chatState, String convoId); + protected abstract int setOwnerStatus( + int presenceState, + String presenceStatus, + long lastActive, + int chatState, + String convoId); /** * Notify the application of the Bluetooth state + * * @param bluetoothState 'on' of 'off' * @return 0 at success */ protected abstract int setBluetoothStatus(boolean bluetoothState); - - /** - * Need this to suppress warning in unit tests. - */ + /** Need this to suppress warning in unit tests. */ @Override public void shutdown() { // Don't call super.shutdown(), which emits a warning... } - /** - * Extract the BluetoothMapContract.AccountColumns._ID from the given URI. - */ + /** Extract the BluetoothMapContract.AccountColumns._ID from the given URI. */ public static String getAccountId(Uri uri) { final List segments = uri.getPathSegments(); if (segments.size() < 1) { diff --git a/android/app/src/com/android/bluetooth/AlertActivity.java b/android/app/src/com/android/bluetooth/AlertActivity.java index cb5e15eff30..0bcc9bfea59 100644 --- a/android/app/src/com/android/bluetooth/AlertActivity.java +++ b/android/app/src/com/android/bluetooth/AlertActivity.java @@ -38,14 +38,12 @@ import com.android.internal.annotations.VisibleForTesting; * @see #setupAlert() */ @SuppressLint("AndroidFrameworkBluetoothPermission") -public abstract class AlertActivity extends Activity implements DialogInterface.OnDismissListener, - DialogInterface.OnCancelListener { +public abstract class AlertActivity extends Activity + implements DialogInterface.OnDismissListener, DialogInterface.OnCancelListener { - /** - * The model for the alert. - * - */ + /** The model for the alert. */ protected AlertDialog.Builder mAlertBuilder; + private AlertDialog mAlert; public AlertActivity() {} @@ -80,14 +78,15 @@ public abstract class AlertActivity extends Activity implements DialogInterface. return dispatchPopulateAccessibilityEvent(this, event); } - private static boolean dispatchPopulateAccessibilityEvent(Activity act, - AccessibilityEvent event) { + private static boolean dispatchPopulateAccessibilityEvent( + Activity act, AccessibilityEvent event) { event.setClassName(Dialog.class.getName()); event.setPackageName(act.getPackageName()); ViewGroup.LayoutParams params = act.getWindow().getAttributes(); - boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT) - && (params.height == ViewGroup.LayoutParams.MATCH_PARENT); + boolean isFullScreen = + (params.width == ViewGroup.LayoutParams.MATCH_PARENT) + && (params.height == ViewGroup.LayoutParams.MATCH_PARENT); event.setFullScreen(isFullScreen); return false; @@ -102,6 +101,7 @@ public abstract class AlertActivity extends Activity implements DialogInterface. if (mAlert == null) return; mAlert.setIconAttribute(attrId); } + protected void changeTitle(CharSequence title) { if (mAlert == null) return; mAlert.setTitle(title); @@ -134,5 +134,4 @@ public abstract class AlertActivity extends Activity implements DialogInterface. } super.onDestroy(); } - } diff --git a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java index 22604dde37a..c4591ef0007 100644 --- a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java +++ b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java @@ -36,8 +36,7 @@ public class BluetoothEventLogger { } public String toString() { - return (new StringBuilder(mTimeStamp) - .append(" ").append(mMsg).toString()); + return (new StringBuilder(mTimeStamp).append(" ").append(mMsg).toString()); } } diff --git a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java index 4965baf89ca..39a324ca2f0 100644 --- a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +++ b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java @@ -57,16 +57,13 @@ import java.io.OutputStream; import java.util.List; import java.util.Set; -/** - * Proxy class for method calls to help with unit testing - */ +/** Proxy class for method calls to help with unit testing */ public class BluetoothMethodProxy { private static final String TAG = BluetoothMethodProxy.class.getSimpleName(); private static final Object INSTANCE_LOCK = new Object(); private static BluetoothMethodProxy sInstance; - private BluetoothMethodProxy() { - } + private BluetoothMethodProxy() {} /** * Get the singleton instance of proxy @@ -96,52 +93,55 @@ public class BluetoothMethodProxy { } } - /** - * Proxies {@link ContentResolver#query(Uri, String[], String, String[], String)}. - */ - public Cursor contentResolverQuery(ContentResolver contentResolver, final Uri contentUri, - final String[] projection, final String selection, final String[] selectionArgs, + /** Proxies {@link ContentResolver#query(Uri, String[], String, String[], String)}. */ + public Cursor contentResolverQuery( + ContentResolver contentResolver, + final Uri contentUri, + final String[] projection, + final String selection, + final String[] selectionArgs, final String sortOrder) { return contentResolver.query(contentUri, projection, selection, selectionArgs, sortOrder); } - /** - * Proxies {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. - */ - public Cursor contentResolverQuery(ContentResolver contentResolver, final Uri contentUri, - final String[] projection, final Bundle queryArgs, + /** Proxies {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. */ + public Cursor contentResolverQuery( + ContentResolver contentResolver, + final Uri contentUri, + final String[] projection, + final Bundle queryArgs, final CancellationSignal cancellationSignal) { return contentResolver.query(contentUri, projection, queryArgs, cancellationSignal); } - /** - * Proxies {@link ContentResolver#insert(Uri, ContentValues)}. - */ - public Uri contentResolverInsert(ContentResolver contentResolver, final Uri contentUri, + /** Proxies {@link ContentResolver#insert(Uri, ContentValues)}. */ + public Uri contentResolverInsert( + ContentResolver contentResolver, + final Uri contentUri, final ContentValues contentValues) { return contentResolver.insert(contentUri, contentValues); } - /** - * Proxies {@link ContentResolver#update(Uri, ContentValues, String, String[])}. - */ - public int contentResolverUpdate(ContentResolver contentResolver, final Uri contentUri, - final ContentValues contentValues, String where, String[] selectionArgs) { + /** Proxies {@link ContentResolver#update(Uri, ContentValues, String, String[])}. */ + public int contentResolverUpdate( + ContentResolver contentResolver, + final Uri contentUri, + final ContentValues contentValues, + String where, + String[] selectionArgs) { return contentResolver.update(contentUri, contentValues, where, selectionArgs); } - /** - * Proxies {@link ContentResolver#delete(Uri, String, String[])}. - */ - public int contentResolverDelete(ContentResolver contentResolver, final Uri url, + /** Proxies {@link ContentResolver#delete(Uri, String, String[])}. */ + public int contentResolverDelete( + ContentResolver contentResolver, + final Uri url, final String where, final String[] selectionArgs) { return contentResolver.delete(url, where, selectionArgs); } - /** - * Proxies {@link BluetoothAdapter#isEnabled()}. - */ + /** Proxies {@link BluetoothAdapter#isEnabled()}. */ public boolean bluetoothAdapterIsEnabled(BluetoothAdapter adapter) { return adapter.isEnabled(); } @@ -153,86 +153,65 @@ public class BluetoothMethodProxy { return BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(address, addressType); } - /** - * Proxies {@link ContentResolver#openFileDescriptor(Uri, String)}. - */ - public ParcelFileDescriptor contentResolverOpenFileDescriptor(ContentResolver contentResolver, - final Uri uri, final String mode) throws FileNotFoundException { + /** Proxies {@link ContentResolver#openFileDescriptor(Uri, String)}. */ + public ParcelFileDescriptor contentResolverOpenFileDescriptor( + ContentResolver contentResolver, final Uri uri, final String mode) + throws FileNotFoundException { return contentResolver.openFileDescriptor(uri, mode); } - /** - * Proxies {@link ContentResolver#openAssetFileDescriptor(Uri, String)}. - */ + /** Proxies {@link ContentResolver#openAssetFileDescriptor(Uri, String)}. */ public AssetFileDescriptor contentResolverOpenAssetFileDescriptor( ContentResolver contentResolver, final Uri uri, final String mode) throws FileNotFoundException { return contentResolver.openAssetFileDescriptor(uri, mode); } - /** - * Proxies {@link ContentResolver#openInputStream(Uri)}. - */ - public InputStream contentResolverOpenInputStream(ContentResolver contentResolver, - final Uri uri) throws FileNotFoundException { + /** Proxies {@link ContentResolver#openInputStream(Uri)}. */ + public InputStream contentResolverOpenInputStream( + ContentResolver contentResolver, final Uri uri) throws FileNotFoundException { return contentResolver.openInputStream(uri); } - /** - * Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}. - */ + /** Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}. */ public ContentProviderClient contentResolverAcquireUnstableContentProviderClient( ContentResolver contentResolver, @NonNull String name) { return contentResolver.acquireUnstableContentProviderClient(name); } - /** - * Proxies {@link ContentResolver#openOutputStream(Uri)}. - */ + /** Proxies {@link ContentResolver#openOutputStream(Uri)}. */ public OutputStream contentResolverOpenOutputStream(ContentResolver contentResolver, Uri uri) throws FileNotFoundException { return contentResolver.openOutputStream(uri); } - /** - * Proxies {@link Context#sendBroadcast(Intent)}. - */ + /** Proxies {@link Context#sendBroadcast(Intent)}. */ public void contextSendBroadcast(Context context, @RequiresPermission Intent intent) { context.sendBroadcast(intent); } - /** - * Proxies {@link Handler#sendEmptyMessage(int)}}. - */ + /** Proxies {@link Handler#sendEmptyMessage(int)}}. */ public boolean handlerSendEmptyMessage(Handler handler, final int what) { return handler.sendEmptyMessage(what); } - /** - * Proxies {@link Handler#sendMessageDelayed(Message, long)}. - */ - public boolean handlerSendMessageDelayed(Handler handler, final int what, - final long delayMillis) { + /** Proxies {@link Handler#sendMessageDelayed(Message, long)}. */ + public boolean handlerSendMessageDelayed( + Handler handler, final int what, final long delayMillis) { return handler.sendMessageDelayed(handler.obtainMessage(what), delayMillis); } - /** - * Proxies {@link HeaderSet#getHeader}. - */ + /** Proxies {@link HeaderSet#getHeader}. */ public Object getHeader(HeaderSet headerSet, int headerId) throws IOException { return headerSet.getHeader(headerId); } - /** - * Proxies {@link Context#getSystemService(Class)}. - */ + /** Proxies {@link Context#getSystemService(Class)}. */ public T getSystemService(Context context, Class serviceClass) { return context.getSystemService(serviceClass); } - /** - * Proxies {@link Telephony.Threads#getOrCreateThreadId(Context, Set )}. - */ + /** Proxies {@link Telephony.Threads#getOrCreateThreadId(Context, Set )}. */ public long telephonyGetOrCreateThreadId(Context context, Set recipients) { return Telephony.Threads.getOrCreateThreadId(context, recipients); } @@ -250,9 +229,13 @@ public class BluetoothMethodProxy { * Proxies {@link PeriodicAdvertisingManager#registerSync(ScanResult, int, int, * PeriodicAdvertisingCallback, Handler)}. */ - public void periodicAdvertisingManagerRegisterSync(PeriodicAdvertisingManager manager, - ScanResult scanResult, int skip, int timeout, - PeriodicAdvertisingCallback callback, Handler handler) { + public void periodicAdvertisingManagerRegisterSync( + PeriodicAdvertisingManager manager, + ScanResult scanResult, + int skip, + int timeout, + PeriodicAdvertisingCallback callback, + Handler handler) { manager.registerSync(scanResult, skip, timeout, callback, handler); } @@ -261,20 +244,23 @@ public class BluetoothMethodProxy { PeriodicAdvertisingManager manager, PeriodicAdvertisingCallback callback) { manager.unregisterSync(callback); } - /** - * Proxies {@link PeriodicAdvertisingManager#transferSync}. - */ - public void periodicAdvertisingManagerTransferSync(PeriodicAdvertisingManager manager, - BluetoothDevice bda, int serviceData, int syncHandle) { + + /** Proxies {@link PeriodicAdvertisingManager#transferSync}. */ + public void periodicAdvertisingManagerTransferSync( + PeriodicAdvertisingManager manager, + BluetoothDevice bda, + int serviceData, + int syncHandle) { manager.transferSync(bda, serviceData, syncHandle); } - /** - * Proxies {@link PeriodicAdvertisingManager#transferSetInfo}. - */ + /** Proxies {@link PeriodicAdvertisingManager#transferSetInfo}. */ public void periodicAdvertisingManagerTransferSetInfo( - PeriodicAdvertisingManager manager, BluetoothDevice bda, int serviceData, - int advHandle, PeriodicAdvertisingCallback callback) { + PeriodicAdvertisingManager manager, + BluetoothDevice bda, + int serviceData, + int advHandle, + PeriodicAdvertisingCallback callback) { manager.transferSetInfo(bda, serviceData, advHandle, callback); } diff --git a/android/app/src/com/android/bluetooth/BluetoothObexTransport.java b/android/app/src/com/android/bluetooth/BluetoothObexTransport.java index 3516cc98d6b..a635612fe2b 100644 --- a/android/app/src/com/android/bluetooth/BluetoothObexTransport.java +++ b/android/app/src/com/android/bluetooth/BluetoothObexTransport.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth; @@ -26,16 +26,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -/** - * Generic Obex Transport class, to be used in OBEX based Bluetooth - * Profiles. - */ +/** Generic Obex Transport class, to be used in OBEX based Bluetooth Profiles. */ public class BluetoothObexTransport implements ObexTransport { private BluetoothSocket mSocket = null; - /** - * Will default at the maximum packet length. - */ + /** Will default at the maximum packet length. */ public static final int PACKET_SIZE_UNSPECIFIED = -1; private int mMaxTransmitPacketSize = PACKET_SIZE_UNSPECIFIED; @@ -79,20 +74,16 @@ public class BluetoothObexTransport implements ObexTransport { } @Override - public void connect() throws IOException { - } + public void connect() throws IOException {} @Override - public void create() throws IOException { - } + public void create() throws IOException {} @Override - public void disconnect() throws IOException { - } + public void disconnect() throws IOException {} @Override - public void listen() throws IOException { - } + public void listen() throws IOException {} public boolean isConnected() throws IOException { return true; @@ -101,8 +92,7 @@ public class BluetoothObexTransport implements ObexTransport { @Override public int getMaxTransmitPacketSize() { if (mSocket.getConnectionType() != BluetoothSocket.TYPE_L2CAP - || (mIsCoverArt - && mMaxTransmitPacketSize != PACKET_SIZE_UNSPECIFIED)) { + || (mIsCoverArt && mMaxTransmitPacketSize != PACKET_SIZE_UNSPECIFIED)) { return mMaxTransmitPacketSize; } return mSocket.getMaxTransmitPacketSize(); diff --git a/android/app/src/com/android/bluetooth/BluetoothPrefs.java b/android/app/src/com/android/bluetooth/BluetoothPrefs.java index 2c7c87aaa77..715144b8de5 100644 --- a/android/app/src/com/android/bluetooth/BluetoothPrefs.java +++ b/android/app/src/com/android/bluetooth/BluetoothPrefs.java @@ -20,9 +20,7 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; -/** - * Activity that routes to Bluetooth settings when launched - */ +/** Activity that routes to Bluetooth settings when launched */ public class BluetoothPrefs extends Activity { public static final String BLUETOOTH_SETTING_ACTION = "android.settings.BLUETOOTH_SETTINGS"; diff --git a/android/app/src/com/android/bluetooth/ChangeIds.java b/android/app/src/com/android/bluetooth/ChangeIds.java index 0416784d793..4c06486deea 100644 --- a/android/app/src/com/android/bluetooth/ChangeIds.java +++ b/android/app/src/com/android/bluetooth/ChangeIds.java @@ -19,9 +19,7 @@ package com.android.bluetooth; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; -/** - * All the {@link ChangeId} used for Bluetooth App. - */ +/** All the {@link ChangeId} used for Bluetooth App. */ public class ChangeIds { /** * Starting with {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, BLUETOOTH_CONNECT diff --git a/android/app/src/com/android/bluetooth/IObexConnectionHandler.java b/android/app/src/com/android/bluetooth/IObexConnectionHandler.java index 66f078d4b8e..f5ba88aa577 100644 --- a/android/app/src/com/android/bluetooth/IObexConnectionHandler.java +++ b/android/app/src/com/android/bluetooth/IObexConnectionHandler.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth; import android.bluetooth.BluetoothDevice; @@ -23,17 +23,15 @@ public interface IObexConnectionHandler { * Called to validate if a connection to the Bluetooth device should be accepted. * * @param device the connecting BluetoothDevice. Use .getType() to determine the type of - * connection. - * @return Shall return TRUE if the connection should be accepted. - * FALSE otherwise + * connection. + * @return Shall return TRUE if the connection should be accepted. FALSE otherwise */ boolean onConnect(BluetoothDevice device, BluetoothSocket socket); /** - * Will be called in case the accept call fails. - * When called, at lease one of the accept threads are about to terminate. - * The behavior needed is to shutdown the ObexServerSockets object, and create a - * new one. + * Will be called in case the accept call fails. When called, at lease one of the accept threads + * are about to terminate. The behavior needed is to shutdown the ObexServerSockets object, and + * create a new one. */ void onAcceptFailed(); } diff --git a/android/app/src/com/android/bluetooth/ObexRejectServer.java b/android/app/src/com/android/bluetooth/ObexRejectServer.java index ed50b76889a..cc38c2d1dbc 100644 --- a/android/app/src/com/android/bluetooth/ObexRejectServer.java +++ b/android/app/src/com/android/bluetooth/ObexRejectServer.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth; @@ -28,11 +28,11 @@ import com.android.obex.ServerRequestHandler; import java.io.IOException; /** - * A simple ObexServer used to handle connection rejection in two cases: - * - A profile cannot handle a new connection, as it is already connected to another device. - * - The user rejected access to the resources needed by the profile. + * A simple ObexServer used to handle connection rejection in two cases: - A profile cannot handle a + * new connection, as it is already connected to another device. - The user rejected access to the + * resources needed by the profile. * - * Will reject the OBEX connection, start a timer, and at timeout close the socket. + *

Will reject the OBEX connection, start a timer, and at timeout close the socket. */ public class ObexRejectServer extends ServerRequestHandler implements Handler.Callback { @@ -51,8 +51,9 @@ public class ObexRejectServer extends ServerRequestHandler implements Handler.Ca super(); mResult = result; mSocket = socket; - mHandlerThread = new HandlerThread("TestTimeoutHandler", - android.os.Process.THREAD_PRIORITY_BACKGROUND); + mHandlerThread = + new HandlerThread( + "TestTimeoutHandler", android.os.Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.start(); Looper timeoutLooper = mHandlerThread.getLooper(); mMessageHandler = new Handler(timeoutLooper, this); diff --git a/android/app/src/com/android/bluetooth/ObexServerSockets.java b/android/app/src/com/android/bluetooth/ObexServerSockets.java index bb4633f3a39..b58b35d8637 100644 --- a/android/app/src/com/android/bluetooth/ObexServerSockets.java +++ b/android/app/src/com/android/bluetooth/ObexServerSockets.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth; import android.annotation.RequiresPermission; @@ -27,22 +27,22 @@ import com.android.obex.ServerSession; import java.io.IOException; /** - * Wraps multiple BluetoothServerSocket objects to make it possible to accept connections on - * both a RFCOMM and L2CAP channel in parallel.
+ * Wraps multiple BluetoothServerSocket objects to make it possible to accept connections on both a + * RFCOMM and L2CAP channel in parallel.
* Create an instance using {@link #create()}, which will block until the sockets have been created * and channel numbers have been assigned.
- * Use {@link #getRfcommChannel()} and {@link #getL2capPsm()} to get the channel numbers to - * put into the SDP record.
- * Call {@link #shutdown(boolean)} to terminate the accept threads created by the call to - * {@link #create(IObexConnectionHandler)}.
+ * Use {@link #getRfcommChannel()} and {@link #getL2capPsm()} to get the channel numbers to put into + * the SDP record.
+ * Call {@link #shutdown(boolean)} to terminate the accept threads created by the call to {@link + * #create(IObexConnectionHandler)}.
* A reference to an object of this type cannot be reused, and the {@link BluetoothServerSocket} * object references passed to this object will be closed by this object, hence cannot be reused * either (This is needed, as the only way to interrupt an accept call is to close the socket...) *
- * When a connection is accepted, - * {@link IObexConnectionHandler#onConnect(BluetoothDevice, BluetoothSocket)} will be called.
- * If the an error occur while waiting for an incoming connection - * {@link IObexConnectionHandler#onConnect(BluetoothDevice, BluetoothSocket)} will be called.
+ * When a connection is accepted, {@link IObexConnectionHandler#onConnect(BluetoothDevice, + * BluetoothSocket)} will be called.
+ * If the an error occur while waiting for an incoming connection {@link + * IObexConnectionHandler#onConnect(BluetoothDevice, BluetoothSocket)} will be called.
* In both cases the {@link ObexServerSockets} object have terminated, and a new must be created. */ public class ObexServerSockets { @@ -56,8 +56,9 @@ public class ObexServerSockets { private SocketAcceptThread mRfcommThread; private SocketAcceptThread mL2capThread; - - private ObexServerSockets(IObexConnectionHandler conHandler, BluetoothServerSocket rfcommSocket, + private ObexServerSockets( + IObexConnectionHandler conHandler, + BluetoothServerSocket rfcommSocket, BluetoothServerSocket l2capSocket) { mConHandler = conHandler; mRfcommSocket = rfcommSocket; @@ -66,27 +67,35 @@ public class ObexServerSockets { /** * Creates an RFCOMM {@link BluetoothServerSocket} and a L2CAP {@link BluetoothServerSocket} - * @param validator a reference to the {@link IObexConnectionHandler} object to call - * to validate an incoming connection. + * + * @param validator a reference to the {@link IObexConnectionHandler} object to call to validate + * an incoming connection. * @return a reference to a {@link ObexServerSockets} object instance. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static ObexServerSockets create(IObexConnectionHandler validator) { - return create(validator, BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, - BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, true); + return create( + validator, + BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, + BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, + true); } /** - * Creates an Insecure RFCOMM {@link BluetoothServerSocket} and a L2CAP - * {@link BluetoothServerSocket} - * @param validator a reference to the {@link IObexConnectionHandler} object to call - * to validate an incoming connection. + * Creates an Insecure RFCOMM {@link BluetoothServerSocket} and a L2CAP {@link + * BluetoothServerSocket} + * + * @param validator a reference to the {@link IObexConnectionHandler} object to call to validate + * an incoming connection. * @return a reference to a {@link ObexServerSockets} object instance. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static ObexServerSockets createInsecure(IObexConnectionHandler validator) { - return create(validator, BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, - BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false); + return create( + validator, + BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, + BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, + false); } private static final int CREATE_RETRY_TIME = 10; @@ -96,17 +105,17 @@ public class ObexServerSockets { * with specific l2cap and RFCOMM channel numbers. It is the responsibility of the caller to * ensure the numbers are free and can be used, e.g. by calling {@link #getL2capPsm()} and * {@link #getRfcommChannel()} in {@link ObexServerSockets}. - * @param validator a reference to the {@link IObexConnectionHandler} object to call - * to validate an incoming connection. + * + * @param validator a reference to the {@link IObexConnectionHandler} object to call to validate + * an incoming connection. * @param isSecure boolean flag to determine whther socket would be secured or inseucure. * @return a reference to a {@link ObexServerSockets} object instance. - * - * TODO: Make public when it becomes possible to determine that the listen-call - * failed due to channel-in-use. + *

TODO: Make public when it becomes possible to determine that the listen-call failed + * due to channel-in-use. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - private static ObexServerSockets create(IObexConnectionHandler validator, int rfcommChannel, - int l2capPsm, boolean isSecure) { + private static ObexServerSockets create( + IObexConnectionHandler validator, int rfcommChannel, int l2capPsm, boolean isSecure) { Log.d(TAG, "create(rfcomm = " + rfcommChannel + ", l2capPsm = " + l2capPsm + ")"); BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); if (bt == null) { @@ -145,8 +154,8 @@ public class ObexServerSockets { if (!initSocketOK) { // Need to break out of this loop if BT is being turned off. int state = bt.getState(); - if ((state != BluetoothAdapter.STATE_TURNING_ON) && (state - != BluetoothAdapter.STATE_ON)) { + if ((state != BluetoothAdapter.STATE_TURNING_ON) + && (state != BluetoothAdapter.STATE_ON)) { Log.w(TAG, "initServerSockets failed as BT is (being) turned off"); break; } @@ -175,6 +184,7 @@ public class ObexServerSockets { /** * Returns the channel number assigned to the RFCOMM socket. This will be a static value, that * should be reused for multiple connections. + * * @return the RFCOMM channel number */ public int getRfcommChannel() { @@ -184,6 +194,7 @@ public class ObexServerSockets { /** * Returns the channel number assigned to the L2CAP socket. This will be a static value, that * should be reused for multiple connections. + * * @return the L2CAP channel number */ public int getL2capPsm() { @@ -191,9 +202,9 @@ public class ObexServerSockets { } /** - * Initiate the accept threads. - * Will create a thread for each socket type. an incoming connection will be signaled to - * the {@link IObexConnectionValidator#onConnect()}, at which point both threads will exit. + * Initiate the accept threads. Will create a thread for each socket type. an incoming + * connection will be signaled to the {@link IObexConnectionValidator#onConnect()}, at which + * point both threads will exit. */ private void startAccept() { Log.d(TAG, "startAccept()"); @@ -207,6 +218,7 @@ public class ObexServerSockets { /** * Called from the AcceptThreads to signal an incoming connection. + * * @param device the connecting device. * @param conSocket the socket associated with the connection. * @return true if the connection is accepted, false otherwise. @@ -216,9 +228,7 @@ public class ObexServerSockets { return mConHandler.onConnect(device, conSocket); } - /** - * Signal to the {@link IObexConnectionHandler} that an error have occurred. - */ + /** Signal to the {@link IObexConnectionHandler} that an error have occurred. */ private synchronized void onAcceptFailed() { shutdown(false); BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -230,8 +240,8 @@ public class ObexServerSockets { /** * Terminate any running accept threads - * @param block Set true to block the calling thread until the AcceptThreads - * has ended execution + * + * @param block Set true to block the calling thread until the AcceptThreads has ended execution */ public synchronized void shutdown(boolean block) { Log.d(TAG, "shutdown(block = " + block + ")"); @@ -263,10 +273,9 @@ public class ObexServerSockets { } /** - * A thread that runs in the background waiting for remote an incoming - * connect. Once a remote socket connects, this thread will be - * shutdown. When the remote disconnect, this thread shall be restarted to - * accept a new connection. + * A thread that runs in the background waiting for remote an incoming connect. Once a remote + * socket connects, this thread will be shutdown. When the remote disconnect, this thread shall + * be restarted to accept a new connection. */ private class SocketAcceptThread extends Thread { @@ -275,6 +284,7 @@ public class ObexServerSockets { /** * Create a SocketAcceptThread + * * @param serverSocket shall never be null. * @throws IllegalArgumentException if {@code serverSocket} is null */ @@ -286,8 +296,8 @@ public class ObexServerSockets { } /** - * Run until shutdown of BT. - * Accept incoming connections and reject if needed. Keep accepting incoming connections. + * Run until shutdown of BT. Accept incoming connections and reject if needed. Keep + * accepting incoming connections. */ @Override public void run() { @@ -332,9 +342,11 @@ public class ObexServerSockets { new BluetoothObexTransport(connSocket); // Create and detach a selfdestructing ServerSession to respond to any // incoming OBEX signals. - new ServerSession(obexTrans, - new ObexRejectServer(ResponseCodes.OBEX_HTTP_UNAVAILABLE, - connSocket), null); + new ServerSession( + obexTrans, + new ObexRejectServer( + ResponseCodes.OBEX_HTTP_UNAVAILABLE, connSocket), + null); // now wait for a new connect } else { // now wait for a new connect @@ -356,8 +368,8 @@ public class ObexServerSockets { /** * Shuts down the accept threads, and closes the ServerSockets, causing all related - * BluetoothSockets to disconnect, hence do not call until all all accepted connections - * are ready to be disconnected. + * BluetoothSockets to disconnect, hence do not call until all all accepted connections are + * ready to be disconnected. */ public void shutdown() { if (!mStopped) { diff --git a/android/app/src/com/android/bluetooth/SignedLongLong.java b/android/app/src/com/android/bluetooth/SignedLongLong.java index 40bf20e7ff6..c84757f1f8d 100644 --- a/android/app/src/com/android/bluetooth/SignedLongLong.java +++ b/android/app/src/com/android/bluetooth/SignedLongLong.java @@ -1,18 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth; @@ -22,10 +21,9 @@ import java.io.UnsupportedEncodingException; import java.util.Objects; /** - * Class to represent a 128bit value using two long member variables. - * Has functionality to convert to/from hex-strings. - * Mind that since signed variables are used to store the value internally - * is used, the MSB/LSB long values can be negative. + * Class to represent a 128bit value using two long member variables. Has functionality to convert + * to/from hex-strings. Mind that since signed variables are used to store the value internally is + * used, the MSB/LSB long values can be negative. */ public class SignedLongLong implements Comparable { @@ -39,6 +37,7 @@ public class SignedLongLong implements Comparable { /** * Create a SignedLongLong from a Hex-String without "0x" prefix + * * @param value the hex-string * @return the created object * @throws UnsupportedEncodingException if "US-ASCII" charset is not supported, @@ -92,7 +91,6 @@ public class SignedLongLong implements Comparable { } /** - * * @return a hex-string representation of the object values */ public String toHexString() { @@ -132,5 +130,4 @@ public class SignedLongLong implements Comparable { public long getLeastSignificantBits() { return mLeastSigBits; } - } diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java b/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java index 13d1bddf351..bfab4d6e9f3 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java @@ -64,11 +64,11 @@ class A2dpCodecConfig { AudioManager audioManager = mContext.getSystemService(AudioManager.class); if (audioManager == null) { - Log.w(TAG, "Can't obtain the codec offloading prefernece from null AudioManager"); - return; + Log.w(TAG, "Can't obtain the codec offloading prefernece from null AudioManager"); + return; } - mCodecConfigOffloading = audioManager.getHwOffloadFormatsSupportedForA2dp() - .toArray(mCodecConfigOffloading); + mCodecConfigOffloading = + audioManager.getHwOffloadFormatsSupportedForA2dp().toArray(mCodecConfigOffloading); } BluetoothCodecConfig[] codecConfigPriorities() { @@ -79,23 +79,24 @@ class A2dpCodecConfig { return mCodecConfigOffloading; } - void setCodecConfigPreference(BluetoothDevice device, - BluetoothCodecStatus codecStatus, - BluetoothCodecConfig newCodecConfig) { + void setCodecConfigPreference( + BluetoothDevice device, + BluetoothCodecStatus codecStatus, + BluetoothCodecConfig newCodecConfig) { Objects.requireNonNull(codecStatus); // Check whether the codecConfig is selectable for this Bluetooth device. List selectableCodecs = codecStatus.getCodecsSelectableCapabilities(); - if (!selectableCodecs.stream().anyMatch(codec -> - codec.isMandatoryCodec())) { + if (!selectableCodecs.stream().anyMatch(codec -> codec.isMandatoryCodec())) { // Do not set codec preference to native if the selectableCodecs not contain mandatory // codec. The reason could be remote codec negotiation is not completed yet. Log.w(TAG, "setCodecConfigPreference: must have mandatory codec before changing."); return; } if (!codecStatus.isCodecConfigSelectable(newCodecConfig)) { - Log.w(TAG, "setCodecConfigPreference: invalid codec " - + Objects.toString(newCodecConfig)); + Log.w( + TAG, + "setCodecConfigPreference: invalid codec " + Objects.toString(newCodecConfig)); return; } @@ -104,8 +105,9 @@ class A2dpCodecConfig { BluetoothCodecConfig currentCodecConfig = codecStatus.getCodecConfig(); if (prioritizedCodecType == currentCodecConfig.getCodecType() && (prioritizedCodecType != newCodecConfig.getCodecType() - || (currentCodecConfig.similarCodecFeedingParameters(newCodecConfig) - && currentCodecConfig.sameCodecSpecificParameters(newCodecConfig)))) { + || (currentCodecConfig.similarCodecFeedingParameters(newCodecConfig) + && currentCodecConfig.sameCodecSpecificParameters( + newCodecConfig)))) { // Same codec with same parameters, no need to send this request to native. Log.w(TAG, "setCodecConfigPreference: codec not changed."); return; @@ -118,8 +120,10 @@ class A2dpCodecConfig { void enableOptionalCodecs(BluetoothDevice device, BluetoothCodecConfig currentCodecConfig) { if (currentCodecConfig != null && !currentCodecConfig.isMandatoryCodec()) { - Log.i(TAG, "enableOptionalCodecs: already using optional codec " - + BluetoothCodecConfig.getCodecName(currentCodecConfig.getCodecType())); + Log.i( + TAG, + "enableOptionalCodecs: already using optional codec " + + BluetoothCodecConfig.getCodecName(currentCodecConfig.getCodecType())); return; } @@ -162,8 +166,8 @@ class A2dpCodecConfig { } // Get the codec type of the highest priority of selectableCodecs and codecConfig. - private int getPrioitizedCodecType(BluetoothCodecConfig codecConfig, - List selectableCodecs) { + private int getPrioitizedCodecType( + BluetoothCodecConfig codecConfig, List selectableCodecs) { BluetoothCodecConfig prioritizedCodecConfig = codecConfig; for (BluetoothCodecConfig config : selectableCodecs) { if (prioritizedCodecConfig == null) { @@ -185,62 +189,67 @@ class A2dpCodecConfig { int value; try { - value = SystemProperties.getInt( - "bluetooth.a2dp.source.sbc_priority.config", - resources.getInteger(R.integer.a2dp_source_codec_priority_sbc)); + value = + SystemProperties.getInt( + "bluetooth.a2dp.source.sbc_priority.config", + resources.getInteger(R.integer.a2dp_source_codec_priority_sbc)); } catch (NotFoundException e) { value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; } - if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value - < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { + if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) + && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { mA2dpSourceCodecPrioritySbc = value; } try { - value = SystemProperties.getInt( - "bluetooth.a2dp.source.aac_priority.config", - resources.getInteger(R.integer.a2dp_source_codec_priority_aac)); + value = + SystemProperties.getInt( + "bluetooth.a2dp.source.aac_priority.config", + resources.getInteger(R.integer.a2dp_source_codec_priority_aac)); } catch (NotFoundException e) { value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; } - if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value - < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { + if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) + && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { mA2dpSourceCodecPriorityAac = value; } try { - value = SystemProperties.getInt( - "bluetooth.a2dp.source.aptx_priority.config", - resources.getInteger(R.integer.a2dp_source_codec_priority_aptx)); + value = + SystemProperties.getInt( + "bluetooth.a2dp.source.aptx_priority.config", + resources.getInteger(R.integer.a2dp_source_codec_priority_aptx)); } catch (NotFoundException e) { value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; } - if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value - < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { + if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) + && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { mA2dpSourceCodecPriorityAptx = value; } try { - value = SystemProperties.getInt( - "bluetooth.a2dp.source.aptx_hd_priority.config", - resources.getInteger(R.integer.a2dp_source_codec_priority_aptx_hd)); + value = + SystemProperties.getInt( + "bluetooth.a2dp.source.aptx_hd_priority.config", + resources.getInteger(R.integer.a2dp_source_codec_priority_aptx_hd)); } catch (NotFoundException e) { value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; } - if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value - < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { + if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) + && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { mA2dpSourceCodecPriorityAptxHd = value; } try { - value = SystemProperties.getInt( - "bluetooth.a2dp.source.ldac_priority.config", - resources.getInteger(R.integer.a2dp_source_codec_priority_ldac)); + value = + SystemProperties.getInt( + "bluetooth.a2dp.source.ldac_priority.config", + resources.getInteger(R.integer.a2dp_source_codec_priority_ldac)); } catch (NotFoundException e) { value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; } - if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value - < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { + if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) + && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { mA2dpSourceCodecPriorityLdac = value; } @@ -249,43 +258,48 @@ class A2dpCodecConfig { } catch (NotFoundException e) { value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; } - if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value - < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { + if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) + && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) { mA2dpSourceCodecPriorityOpus = value; } BluetoothCodecConfig codecConfig; - BluetoothCodecConfig[] codecConfigArray = - new BluetoothCodecConfig[6]; - codecConfig = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) - .setCodecPriority(mA2dpSourceCodecPrioritySbc) - .build(); + BluetoothCodecConfig[] codecConfigArray = new BluetoothCodecConfig[6]; + codecConfig = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) + .setCodecPriority(mA2dpSourceCodecPrioritySbc) + .build(); codecConfigArray[0] = codecConfig; - codecConfig = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) - .setCodecPriority(mA2dpSourceCodecPriorityAac) - .build(); + codecConfig = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) + .setCodecPriority(mA2dpSourceCodecPriorityAac) + .build(); codecConfigArray[1] = codecConfig; - codecConfig = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) - .setCodecPriority(mA2dpSourceCodecPriorityAptx) - .build(); + codecConfig = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) + .setCodecPriority(mA2dpSourceCodecPriorityAptx) + .build(); codecConfigArray[2] = codecConfig; - codecConfig = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) - .setCodecPriority(mA2dpSourceCodecPriorityAptxHd) - .build(); + codecConfig = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) + .setCodecPriority(mA2dpSourceCodecPriorityAptxHd) + .build(); codecConfigArray[3] = codecConfig; - codecConfig = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) - .setCodecPriority(mA2dpSourceCodecPriorityLdac) - .build(); + codecConfig = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) + .setCodecPriority(mA2dpSourceCodecPriorityLdac) + .build(); codecConfigArray[4] = codecConfig; - codecConfig = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) - .setCodecPriority(mA2dpSourceCodecPriorityOpus) - .build(); + codecConfig = + new BluetoothCodecConfig.Builder() + .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) + .setCodecPriority(mA2dpSourceCodecPriorityOpus) + .build(); codecConfigArray[5] = codecConfig; return codecConfigArray; @@ -293,14 +307,13 @@ class A2dpCodecConfig { public void switchCodecByBufferSize( BluetoothDevice device, boolean isLowLatency, int currentCodecType) { - if ((isLowLatency - && currentCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) + if ((isLowLatency && currentCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) || (!isLowLatency - && currentCodecType != BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)) { + && currentCodecType != BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)) { return; } BluetoothCodecConfig[] codecConfigArray = assignCodecConfigPriorities(); - for (int i = 0; i < codecConfigArray.length; i++){ + for (int i = 0; i < codecConfigArray.length; i++) { BluetoothCodecConfig codecConfig = codecConfigArray[i]; if (codecConfig.getCodecType() == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) { if (isLowLatency) { @@ -315,4 +328,3 @@ class A2dpCodecConfig { mA2dpNativeInterface.setCodecConfigPreference(device, codecConfigArray); } } - diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java index e1c7669b617..aa0c8dad3c3 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java @@ -39,9 +39,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -/** - * A2DP Native Interface to/from JNI. - */ +/** A2DP Native Interface to/from JNI. */ public class A2dpNativeInterface { private static final String TAG = A2dpNativeInterface.class.getSimpleName(); private BluetoothAdapter mAdapter; @@ -60,13 +58,13 @@ public class A2dpNativeInterface { if (mAdapter == null) { Log.wtf(TAG, "No Bluetooth Adapter Available"); } - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when A2dpNativeInterface init"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when A2dpNativeInterface init"); } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static A2dpNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -155,14 +153,12 @@ public class A2dpNativeInterface { * Sets the codec configuration preferences. * * @param device the remote Bluetooth device - * @param codecConfigArray an array with the codec configurations to - * configure. + * @param codecConfigArray an array with the codec configurations to configure. * @return true on success, otherwise false. */ - public boolean setCodecConfigPreference(BluetoothDevice device, - BluetoothCodecConfig[] codecConfigArray) { - return setCodecConfigPreferenceNative(getByteAddress(device), - codecConfigArray); + public boolean setCodecConfigPreference( + BluetoothDevice device, BluetoothCodecConfig[] codecConfigArray) { + return setCodecConfigPreferenceNative(getByteAddress(device), codecConfigArray); } private BluetoothDevice getDevice(byte[] address) { @@ -212,15 +208,18 @@ public class A2dpNativeInterface { sendMessageToService(event); } - private void onCodecConfigChanged(byte[] address, + private void onCodecConfigChanged( + byte[] address, BluetoothCodecConfig newCodecConfig, BluetoothCodecConfig[] codecsLocalCapabilities, BluetoothCodecConfig[] codecsSelectableCapabilities) { A2dpStackEvent event = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED); event.device = getDevice(address); - event.codecStatus = new BluetoothCodecStatus(newCodecConfig, - Arrays.asList(codecsLocalCapabilities), - Arrays.asList(codecsSelectableCapabilities)); + event.codecStatus = + new BluetoothCodecStatus( + newCodecConfig, + Arrays.asList(codecsLocalCapabilities), + Arrays.asList(codecsSelectableCapabilities)); Log.d(TAG, "onCodecConfigChanged: " + event); sendMessageToService(event); } @@ -239,17 +238,23 @@ public class A2dpNativeInterface { } // Native methods that call into the JNI interface - private native void initNative(int maxConnectedAudioDevices, - BluetoothCodecConfig[] codecConfigPriorities, - BluetoothCodecConfig[] codecConfigOffloading); + private native void initNative( + int maxConnectedAudioDevices, + BluetoothCodecConfig[] codecConfigPriorities, + BluetoothCodecConfig[] codecConfigOffloading); + private native void cleanupNative(); private native BluetoothCodecType[] getSupportedCodecTypesNative(); private native boolean connectA2dpNative(byte[] address); + private native boolean disconnectA2dpNative(byte[] address); + private native boolean setSilenceDeviceNative(byte[] address, boolean silence); + private native boolean setActiveDeviceNative(byte[] address); - private native boolean setCodecConfigPreferenceNative(byte[] address, - BluetoothCodecConfig[] codecConfigArray); + + private native boolean setCodecConfigPreferenceNative( + byte[] address, BluetoothCodecConfig[] codecConfigArray); } diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java index 24f8f1e4536..a4f89375c1a 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java @@ -77,9 +77,7 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -/** - * Provides Bluetooth A2DP profile, as a service in the Bluetooth application. - */ +/** Provides Bluetooth A2DP profile, as a service in the Bluetooth application. */ public class A2dpService extends ProfileService { private static final String TAG = A2dpService.class.getSimpleName(); @@ -97,8 +95,7 @@ public class A2dpService extends ProfileService { private HandlerThread mStateMachinesThread; private Handler mHandler = null; - @VisibleForTesting - ServiceFactory mFactory = new ServiceFactory(); + @VisibleForTesting ServiceFactory mFactory = new ServiceFactory(); private A2dpCodecConfig mA2dpCodecConfig; @GuardedBy("mStateMachines") @@ -273,8 +270,7 @@ public class A2dpService extends ProfileService { Log.e(TAG, "Cannot connect to " + device + " : CONNECTION_POLICY_FORBIDDEN"); return false; } - if (!Utils.arrayContains(mAdapterService.getRemoteUuids(device), - BluetoothUuid.A2DP_SINK)) { + if (!Utils.arrayContains(mAdapterService.getRemoteUuids(device), BluetoothUuid.A2DP_SINK)) { Log.e(TAG, "Cannot connect to " + device + " : Remote does not have A2DP Sink UUID"); return false; } @@ -283,10 +279,13 @@ public class A2dpService extends ProfileService { if (!connectionAllowedCheckMaxDevices(device)) { // when mMaxConnectedAudioDevices is one, disconnect current device first. if (mMaxConnectedAudioDevices == 1) { - List sinks = getDevicesMatchingConnectionStates( - new int[] {BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTING}); + List sinks = + getDevicesMatchingConnectionStates( + new int[] { + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTING + }); for (BluetoothDevice sink : sinks) { if (sink.equals(device)) { Log.w(TAG, "Connecting to device " + device + " : disconnect skipped"); @@ -342,8 +341,8 @@ public class A2dpService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers the maximum number of connected peers. + * Check whether can connect to a peer device. The check considers the maximum number of + * connected peers. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -357,7 +356,7 @@ public class A2dpService extends ProfileService { case BluetoothProfile.STATE_CONNECTING: case BluetoothProfile.STATE_CONNECTED: if (Objects.equals(device, sm.getDevice())) { - return true; // Already connected or accounted for + return true; // Already connected or accounted for } connected++; break; @@ -370,12 +369,12 @@ public class A2dpService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to - * @param isOutgoingRequest if true, the check is for outgoing connection - * request, otherwise is for incoming connection request + * @param isOutgoingRequest if true, the check is for outgoing connection request, otherwise is + * for incoming connection request * @return true if connection is allowed, otherwise false */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -388,8 +387,9 @@ public class A2dpService extends ProfileService { } // Check if too many devices if (!connectionAllowedCheckMaxDevices(device)) { - Log.e(TAG, "okToConnect: cannot connect to " + device - + " : too many connected devices"); + Log.e( + TAG, + "okToConnect: cannot connect to " + device + " : too many connected devices"); return false; } // Check connectionPolicy and accept or reject the connection. @@ -405,8 +405,10 @@ public class A2dpService extends ProfileService { if (!isOutgoingRequest) { HeadsetService headsetService = HeadsetService.getHeadsetService(); if (headsetService != null && headsetService.okToAcceptConnection(device, true)) { - Log.d(TAG, "okToConnect: return false," - + " Fallback connection to allowed HFP profile"); + Log.d( + TAG, + "okToConnect: return false," + + " Fallback connection to allowed HFP profile"); headsetService.connect(device); return false; } @@ -429,8 +431,8 @@ public class A2dpService extends ProfileService { } synchronized (mStateMachines) { for (BluetoothDevice device : bondedDevices) { - if (!Utils.arrayContains(mAdapterService.getRemoteUuids(device), - BluetoothUuid.A2DP_SINK)) { + if (!Utils.arrayContains( + mAdapterService.getRemoteUuids(device), BluetoothUuid.A2DP_SINK)) { continue; } int connectionState = BluetoothProfile.STATE_DISCONNECTED; @@ -492,14 +494,18 @@ public class A2dpService extends ProfileService { updateAndBroadcastActiveDevice(null); // Make sure the Audio Manager knows the previous active device is no longer active. - mAudioManager.handleBluetoothActiveDeviceChanged(null, previousActiveDevice, + mAudioManager.handleBluetoothActiveDeviceChanged( + null, + previousActiveDevice, BluetoothProfileConnectionInfo.createA2dpInfo(!stopAudio, -1)); synchronized (mStateMachines) { // Make sure the Active device in native layer is set to null and audio is off if (!mNativeInterface.setActiveDevice(null)) { - Log.w(TAG, "setActiveDevice(null): Cannot remove active device in native " - + "layer"); + Log.w( + TAG, + "setActiveDevice(null): Cannot remove active device in native " + + "layer"); return false; } } @@ -547,21 +553,34 @@ public class A2dpService extends ProfileService { BluetoothDevice previousActiveDevice = null; synchronized (mStateMachines) { if (Objects.equals(device, mActiveDevice)) { - Log.i(TAG, "setActiveDevice(" + device + "): current is " + mActiveDevice - + " no changed"); + Log.i( + TAG, + "setActiveDevice(" + + device + + "): current is " + + mActiveDevice + + " no changed"); // returns true since the device is activated even double attempted return true; } Log.d(TAG, "setActiveDevice(" + device + "): current is " + mActiveDevice); sm = mStateMachines.get(device); if (sm == null) { - Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active: " - + "no state machine"); + Log.e( + TAG, + "setActiveDevice(" + + device + + "): Cannot set as active: " + + "no state machine"); return false; } if (sm.getConnectionState() != BluetoothProfile.STATE_CONNECTED) { - Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active: " - + "device is not connected"); + Log.e( + TAG, + "setActiveDevice(" + + device + + "): Cannot set as active: " + + "device is not connected"); return false; } previousActiveDevice = mActiveDevice; @@ -576,8 +595,12 @@ public class A2dpService extends ProfileService { BluetoothDevice newActiveDevice = null; synchronized (mStateMachines) { if (!mNativeInterface.setActiveDevice(device)) { - Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active in native " - + "layer"); + Log.e( + TAG, + "setActiveDevice(" + + device + + "): Cannot set as active in native " + + "layer"); // Remove active device and stop playing audio. removeActiveDevice(true); return false; @@ -593,15 +616,18 @@ public class A2dpService extends ProfileService { // Tasks of Bluetooth are done, and now restore the AudioManager side. int rememberedVolume = -1; if (mFactory.getAvrcpTargetService() != null) { - rememberedVolume = mFactory.getAvrcpTargetService() - .getRememberedVolumeForDevice(newActiveDevice); + rememberedVolume = + mFactory.getAvrcpTargetService() + .getRememberedVolumeForDevice(newActiveDevice); } // Make sure the Audio Manager knows the previous Active device is disconnected, // and the new Active device is connected. // And inform the Audio Service about the codec configuration // change, so the Audio Service can reset accordingly the audio // feeding parameters in the Audio HAL to the Bluetooth stack. - mAudioManager.handleBluetoothActiveDeviceChanged(newActiveDevice, previousActiveDevice, + mAudioManager.handleBluetoothActiveDeviceChanged( + newActiveDevice, + previousActiveDevice, BluetoothProfileConnectionInfo.createA2dpInfo(true, rememberedVolume)); } return true; @@ -625,15 +651,14 @@ public class A2dpService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -641,12 +666,12 @@ public class A2dpService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.A2DP, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.A2DP, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -660,17 +685,15 @@ public class A2dpService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.A2DP); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.A2DP); } public void setAvrcpAbsoluteVolume(int volume) { @@ -700,8 +723,8 @@ public class A2dpService extends ProfileService { /** * Gets the current codec status (configuration and capability). * - * @param device the remote Bluetooth device. If null, use the current - * active A2DP Bluetooth device. + * @param device the remote Bluetooth device. If null, use the current active A2DP Bluetooth + * device. * @return the current codec status */ public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) { @@ -724,14 +747,12 @@ public class A2dpService extends ProfileService { /** * Sets the codec configuration preference. * - * @param device the remote Bluetooth device. If null, use the currect - * active A2DP Bluetooth device. + * @param device the remote Bluetooth device. If null, use the currect active A2DP Bluetooth + * device. * @param codecConfig the codec configuration preference */ - public void setCodecConfigPreference(BluetoothDevice device, - BluetoothCodecConfig codecConfig) { - Log.d(TAG, "setCodecConfigPreference(" + device + "): " - + Objects.toString(codecConfig)); + public void setCodecConfigPreference(BluetoothDevice device, BluetoothCodecConfig codecConfig) { + Log.d(TAG, "setCodecConfigPreference(" + device + "): " + Objects.toString(codecConfig)); if (device == null) { device = mActiveDevice; } @@ -754,8 +775,8 @@ public class A2dpService extends ProfileService { /** * Enables the optional codecs. * - * @param device the remote Bluetooth device. If null, use the currect - * active A2DP Bluetooth device. + * @param device the remote Bluetooth device. If null, use the currect active A2DP Bluetooth + * device. */ public void enableOptionalCodecs(BluetoothDevice device) { Log.d(TAG, "enableOptionalCodecs(" + device + ")"); @@ -782,8 +803,8 @@ public class A2dpService extends ProfileService { /** * Disables the optional codecs. * - * @param device the remote Bluetooth device. If null, use the currect - * active A2DP Bluetooth device. + * @param device the remote Bluetooth device. If null, use the currect active A2DP Bluetooth + * device. */ public void disableOptionalCodecs(BluetoothDevice device) { Log.d(TAG, "disableOptionalCodecs(" + device + ")"); @@ -811,18 +832,20 @@ public class A2dpService extends ProfileService { * Checks whether optional codecs are supported * * @param device is the remote bluetooth device. - * @return whether optional codecs are supported. Possible values are: - * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORTED}, - * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_NOT_SUPPORTED}, - * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORT_UNKNOWN}. + * @return whether optional codecs are supported. Possible values are: {@link + * OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORTED}, {@link + * OptionalCodecsSupportStatus#OPTIONAL_CODECS_NOT_SUPPORTED}, {@link + * OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORT_UNKNOWN}. */ public @OptionalCodecsSupportStatus int getSupportsOptionalCodecs(BluetoothDevice device) { return mDatabaseManager.getA2dpSupportsOptionalCodecs(device); } public void setSupportsOptionalCodecs(BluetoothDevice device, boolean doesSupport) { - int value = doesSupport ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED - : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED; + int value = + doesSupport + ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED + : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED; mDatabaseManager.setA2dpSupportsOptionalCodecs(device, value); } @@ -830,10 +853,10 @@ public class A2dpService extends ProfileService { * Checks whether optional codecs are enabled * * @param device is the remote bluetooth device - * @return whether the optional codecs are enabled. Possible values are: - * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED}, - * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED}, - * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}. + * @return whether the optional codecs are enabled. Possible values are: {@link + * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED}, {@link + * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED}, {@link + * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}. */ public @OptionalCodecsPreferenceStatus int getOptionalCodecsEnabled(BluetoothDevice device) { return mDatabaseManager.getA2dpOptionalCodecsEnabled(device); @@ -843,13 +866,13 @@ public class A2dpService extends ProfileService { * Sets the optional codecs to be set to the passed in value * * @param device is the remote bluetooth device - * @param value is the new status for the optional codecs. Possible values are: - * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED}, - * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED}, - * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}. + * @param value is the new status for the optional codecs. Possible values are: {@link + * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED}, {@link + * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED}, {@link + * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}. */ - public void setOptionalCodecsEnabled(BluetoothDevice device, - @OptionalCodecsPreferenceStatus int value) { + public void setOptionalCodecsEnabled( + BluetoothDevice device, @OptionalCodecsPreferenceStatus int value) { if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { @@ -862,15 +885,15 @@ public class A2dpService extends ProfileService { /** * Get dynamic audio buffer size supported type * - * @return support

Possible values are - * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE}, - * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD}, - * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}. + * @return support + *

Possible values are {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE}, {@link + * BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD}, {@link + * BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getDynamicBufferSupport() { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); return mAdapterService.getDynamicBufferSupport(); } @@ -881,8 +904,8 @@ public class A2dpService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public BufferConstraints getBufferConstraints() { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); return mAdapterService.getBufferConstraints(); } @@ -895,8 +918,8 @@ public class A2dpService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setBufferLengthMillis(int codec, int value) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); return mAdapterService.setBufferLengthMillis(codec, value); } @@ -913,8 +936,11 @@ public class A2dpService extends ProfileService { case A2dpStackEvent.CONNECTION_STATE_CONNECTING: // Create a new state machine only when connecting to a device if (!connectionAllowedCheckMaxDevices(device)) { - Log.e(TAG, "Cannot connect to " + device - + " : too many connected devices"); + Log.e( + TAG, + "Cannot connect to " + + device + + " : too many connected devices"); return; } sm = getOrCreateStateMachine(device); @@ -937,30 +963,45 @@ public class A2dpService extends ProfileService { * * @param device the remote device * @param codecStatus the new codec status - * @param sameAudioFeedingParameters if true the audio feeding parameters - * haven't been changed + * @param sameAudioFeedingParameters if true the audio feeding parameters haven't been changed */ @VisibleForTesting - public void codecConfigUpdated(BluetoothDevice device, BluetoothCodecStatus codecStatus, - boolean sameAudioFeedingParameters) { + public void codecConfigUpdated( + BluetoothDevice device, + BluetoothCodecStatus codecStatus, + boolean sameAudioFeedingParameters) { // Log codec config and capability metrics BluetoothCodecConfig codecConfig = codecStatus.getCodecConfig(); int metricId = mAdapterService.getMetricId(device); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED, - mAdapterService.obfuscateAddress(device), codecConfig.getCodecType(), - codecConfig.getCodecPriority(), codecConfig.getSampleRate(), - codecConfig.getBitsPerSample(), codecConfig.getChannelMode(), - codecConfig.getCodecSpecific1(), codecConfig.getCodecSpecific2(), - codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4(), metricId); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED, + mAdapterService.obfuscateAddress(device), + codecConfig.getCodecType(), + codecConfig.getCodecPriority(), + codecConfig.getSampleRate(), + codecConfig.getBitsPerSample(), + codecConfig.getChannelMode(), + codecConfig.getCodecSpecific1(), + codecConfig.getCodecSpecific2(), + codecConfig.getCodecSpecific3(), + codecConfig.getCodecSpecific4(), + metricId); List codecCapabilities = codecStatus.getCodecsSelectableCapabilities(); for (BluetoothCodecConfig codecCapability : codecCapabilities) { - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED, - mAdapterService.obfuscateAddress(device), codecCapability.getCodecType(), - codecCapability.getCodecPriority(), codecCapability.getSampleRate(), - codecCapability.getBitsPerSample(), codecCapability.getChannelMode(), - codecConfig.getCodecSpecific1(), codecConfig.getCodecSpecific2(), - codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4(), metricId); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED, + mAdapterService.obfuscateAddress(device), + codecCapability.getCodecType(), + codecCapability.getCodecPriority(), + codecCapability.getSampleRate(), + codecCapability.getBitsPerSample(), + codecCapability.getChannelMode(), + codecConfig.getCodecSpecific1(), + codecConfig.getCodecSpecific2(), + codecConfig.getCodecSpecific3(), + codecConfig.getCodecSpecific4(), + metricId); } broadcastCodecConfig(device, codecStatus); @@ -973,8 +1014,8 @@ public class A2dpService extends ProfileService { // restart the session even if feeding parameter are the same. (sameAudioFeedingParameters // is left unused until there) if (isActiveDevice(device)) { - mAudioManager.handleBluetoothActiveDeviceChanged(device, device, - BluetoothProfileConnectionInfo.createA2dpInfo(false, -1)); + mAudioManager.handleBluetoothActiveDeviceChanged( + device, device, BluetoothProfileConnectionInfo.createA2dpInfo(false, -1)); } } @@ -990,8 +1031,10 @@ public class A2dpService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_A2DP_STATE_MACHINES) { - Log.e(TAG, "Maximum number of A2DP state machines reached: " - + MAX_A2DP_STATE_MACHINES); + Log.e( + TAG, + "Maximum number of A2DP state machines reached: " + + MAX_A2DP_STATE_MACHINES); return null; } Log.d(TAG, "Creating a new state machine for " + device); @@ -1026,8 +1069,12 @@ public class A2dpService extends ProfileService { byte[] addressBytes = Utils.getBytesFromAddress(address); BluetoothDevice device = mAdapterService.getDeviceFromByte(addressBytes); - Log.d(TAG, " onAudioDevicesAdded: " + device + ", device type: " - + deviceInfo.getType()); + Log.d( + TAG, + " onAudioDevicesAdded: " + + device + + ", device type: " + + deviceInfo.getType()); /* Don't expose already exposed active device */ if (device.equals(mExposedActiveDevice)) { @@ -1035,11 +1082,16 @@ public class A2dpService extends ProfileService { return; } - if (!device.equals(mActiveDevice)) { - Log.e(TAG, "Added device does not match to the one activated here. (" - + device + " != " + mActiveDevice - + " / " + mActiveDevice+ ")"); + Log.e( + TAG, + "Added device does not match to the one activated here. (" + + device + + " != " + + mActiveDevice + + " / " + + mActiveDevice + + ")"); continue; } @@ -1070,9 +1122,14 @@ public class A2dpService extends ProfileService { mExposedActiveDevice = null; - Log.d(TAG, " onAudioDevicesRemoved: " + address + ", device type: " - + deviceInfo.getType() - + ", mActiveDevice: " + mActiveDevice); + Log.d( + TAG, + " onAudioDevicesRemoved: " + + address + + ", device type: " + + deviceInfo.getType() + + ", mActiveDevice: " + + mActiveDevice); } } } @@ -1089,13 +1146,16 @@ public class A2dpService extends ProfileService { mAdapterService.handleActiveDeviceChange(BluetoothProfile.A2DP, device); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, - BluetoothProfile.A2DP, mAdapterService.obfuscateAddress(device), + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, + BluetoothProfile.A2DP, + mAdapterService.obfuscateAddress(device), mAdapterService.getMetricId(device)); Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); } @@ -1105,7 +1165,8 @@ public class A2dpService extends ProfileService { Intent intent = new Intent(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED); intent.putExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS, codecStatus); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); } @@ -1118,10 +1179,9 @@ public class A2dpService extends ProfileService { * Process a change in the bonding state for a device. * * @param device the device whose bonding state has changed - * @param bondState the new bond state for the device. Possible values are: - * {@link BluetoothDevice#BOND_NONE}, - * {@link BluetoothDevice#BOND_BONDING}, - * {@link BluetoothDevice#BOND_BONDED}. + * @param bondState the new bond state for the device. Possible values are: {@link + * BluetoothDevice#BOND_NONE}, {@link BluetoothDevice#BOND_BONDING}, {@link + * BluetoothDevice#BOND_BONDED}. */ @VisibleForTesting void bondStateChanged(BluetoothDevice device, int bondState) { @@ -1149,8 +1209,9 @@ public class A2dpService extends ProfileService { synchronized (mStateMachines) { A2dpStateMachine sm = mStateMachines.get(device); if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); + Log.w( + TAG, + "removeStateMachine: device " + device + " does not have a state machine"); return; } Log.i(TAG, "removeStateMachine: removing state machine for device: " + device); @@ -1160,7 +1221,6 @@ public class A2dpService extends ProfileService { } } - /** * Update and initiate optional codec status change to native. * @@ -1197,8 +1257,8 @@ public class A2dpService extends ProfileService { } if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN - || supportsOptional != (previousSupport - == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) { + || supportsOptional + != (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) { setSupportsOptionalCodecs(device, supportsOptional); } if (supportsOptional) { @@ -1219,9 +1279,9 @@ public class A2dpService extends ProfileService { } /** - * Check for low-latency codec support and inform AdapterService + * Check for low-latency codec support and inform AdapterService * - * @param device device whose audio low latency will be allowed or disallowed + * @param device device whose audio low latency will be allowed or disallowed */ @VisibleForTesting public void updateLowLatencyAudioSupport(BluetoothDevice device) { @@ -1232,9 +1292,10 @@ public class A2dpService extends ProfileService { } BluetoothCodecStatus codecStatus = sm.getCodecStatus(); boolean lowLatencyAudioAllow = false; - BluetoothCodecConfig lowLatencyCodec = new BluetoothCodecConfig.Builder() - .setCodecType(SOURCE_CODEC_TYPE_OPUS) // remove in U - .build(); + BluetoothCodecConfig lowLatencyCodec = + new BluetoothCodecConfig.Builder() + .setCodecType(SOURCE_CODEC_TYPE_OPUS) // remove in U + .build(); if (codecStatus != null && codecStatus.isCodecConfigSelectable(lowLatencyCodec) @@ -1296,22 +1357,17 @@ public class A2dpService extends ProfileService { device, BluetoothProfile.A2DP, toState, fromState); } - /** - * Retrieves the most recently connected device in the A2DP connected devices list. - */ + /** Retrieves the most recently connected device in the A2DP connected devices list. */ public BluetoothDevice getFallbackDevice() { DatabaseManager dbManager = mAdapterService.getDatabase(); - return dbManager != null ? dbManager - .getMostRecentlyConnectedDevicesInList(getConnectedDevices()) - : null; + return dbManager != null + ? dbManager.getMostRecentlyConnectedDevicesInList(getConnectedDevices()) + : null; } - /** - * Binder object: must be a static class or memory leak may occur. - */ + /** Binder object: must be a static class or memory leak may occur. */ @VisibleForTesting - static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub - implements IProfileServiceBinder { + static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub implements IProfileServiceBinder { private A2dpService mService; @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) @@ -1486,8 +1542,10 @@ public class A2dpService extends ProfileService { } @Override - public void setCodecConfigPreference(BluetoothDevice device, - BluetoothCodecConfig codecConfig, AttributionSource source) { + public void setCodecConfigPreference( + BluetoothDevice device, + BluetoothCodecConfig codecConfig, + AttributionSource source) { A2dpService service = getService(source); if (service == null) { return; @@ -1500,8 +1558,12 @@ public class A2dpService extends ProfileService { + " setCodecConfigPreference without a CompanionDeviceManager" + " service"); } - enforceCdmAssociation(service.mCompanionDeviceManager, service, - source.getPackageName(), Binder.getCallingUid(), device); + enforceCdmAssociation( + service.mCompanionDeviceManager, + service, + source.getPackageName(), + Binder.getCallingUid(), + device); } service.setCodecConfigPreference(device, codecConfig); } @@ -1513,8 +1575,8 @@ public class A2dpService extends ProfileService { return; } - if (checkCallerTargetSdk(mService, source.getPackageName(), - Build.VERSION_CODES.TIRAMISU)) { + if (checkCallerTargetSdk( + mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } service.enableOptionalCodecs(device); @@ -1527,8 +1589,8 @@ public class A2dpService extends ProfileService { return; } - if (checkCallerTargetSdk(mService, source.getPackageName(), - Build.VERSION_CODES.TIRAMISU)) { + if (checkCallerTargetSdk( + mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } service.disableOptionalCodecs(device); @@ -1563,15 +1625,15 @@ public class A2dpService extends ProfileService { } @Override - public void setOptionalCodecsEnabled(BluetoothDevice device, int value, - AttributionSource source) { + public void setOptionalCodecsEnabled( + BluetoothDevice device, int value, AttributionSource source) { A2dpService service = getService(source); if (service == null) { return; } - if (checkCallerTargetSdk(mService, source.getPackageName(), - Build.VERSION_CODES.TIRAMISU)) { + if (checkCallerTargetSdk( + mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } service.setOptionalCodecsEnabled(device, value); @@ -1616,9 +1678,12 @@ public class A2dpService extends ProfileService { if (mA2dpCodecConfig != null) { ProfileService.println(sb, "codecConfigPriorities:"); for (BluetoothCodecConfig codecConfig : mA2dpCodecConfig.codecConfigPriorities()) { - ProfileService.println(sb, " " + BluetoothCodecConfig.getCodecName( - codecConfig.getCodecType()) + ": " - + codecConfig.getCodecPriority()); + ProfileService.println( + sb, + " " + + BluetoothCodecConfig.getCodecName(codecConfig.getCodecType()) + + ": " + + codecConfig.getCodecPriority()); } ProfileService.println(sb, "mA2dpOffloadEnabled: " + mA2dpOffloadEnabled); if (mA2dpOffloadEnabled) { @@ -1644,11 +1709,11 @@ public class A2dpService extends ProfileService { } /** - * Sends the preferred audio profile change requested from a call to - * {@link BluetoothAdapter#setPreferredAudioProfiles(BluetoothDevice, Bundle)} to the audio - * framework to apply the change. The audio framework will call - * {@link BluetoothAdapter#notifyActiveDeviceChangeApplied(BluetoothDevice)} once the - * change is successfully applied. + * Sends the preferred audio profile change requested from a call to {@link + * BluetoothAdapter#setPreferredAudioProfiles(BluetoothDevice, Bundle)} to the audio framework + * to apply the change. The audio framework will call {@link + * BluetoothAdapter#notifyActiveDeviceChangeApplied(BluetoothDevice)} once the change is + * successfully applied. * * @return the number of requests sent to the audio framework */ @@ -1658,7 +1723,9 @@ public class A2dpService extends ProfileService { Log.e(TAG, "sendPreferredAudioProfileChangeToAudioFramework: no active device"); return 0; } - mAudioManager.handleBluetoothActiveDeviceChanged(mActiveDevice, mActiveDevice, + mAudioManager.handleBluetoothActiveDeviceChanged( + mActiveDevice, + mActiveDevice, BluetoothProfileConnectionInfo.createA2dpInfo(false, -1)); return 1; } diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java index 4ebd82a0c48..9da6a213ea8 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java @@ -20,8 +20,8 @@ import android.bluetooth.BluetoothCodecStatus; import android.bluetooth.BluetoothDevice; /** - * Stack event sent via a callback from JNI to Java, or generated - * internally by the A2DP State Machine. + * Stack event sent via a callback from JNI to Java, or generated internally by the A2DP State + * Machine. */ public class A2dpStackEvent { // Event types for STACK_EVENT message (coming from native) diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java index 36109843625..502596c1ba3 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java @@ -15,34 +15,18 @@ */ /** - * Bluetooth A2DP StateMachine. There is one instance per remote device. - * - "Disconnected" and "Connected" are steady states. - * - "Connecting" and "Disconnecting" are transient states until the - * connection / disconnection is completed. + * Bluetooth A2DP StateMachine. There is one instance per remote device. - "Disconnected" and + * "Connected" are steady states. - "Connecting" and "Disconnecting" are transient states until the + * connection / disconnection is completed. * + *

(Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting)<--->(Disconnecting) | ^ CONNECTED + * | | DISCONNECT V | (Connected) NOTES: - If state machine is in "Connecting" state and the remote + * device sends DISCONNECT request, the state machine transitions to "Disconnecting" state. - + * Similarly, if the state machine is in "Disconnecting" state and the remote device sends CONNECT + * request, the state machine transitions to "Connecting" state. * - * (Disconnected) - * | ^ - * CONNECT | | DISCONNECTED - * V | - * (Connecting)<--->(Disconnecting) - * | ^ - * CONNECTED | | DISCONNECT - * V | - * (Connected) - * NOTES: - * - If state machine is in "Connecting" state and the remote device sends - * DISCONNECT request, the state machine transitions to "Disconnecting" state. - * - Similarly, if the state machine is in "Disconnecting" state and the remote device - * sends CONNECT request, the state machine transitions to "Connecting" state. - * - * DISCONNECT - * (Connecting) ---------------> (Disconnecting) - * <--------------- - * CONNECT - * + *

DISCONNECT (Connecting) ---------------> (Disconnecting) <--------------- CONNECT */ - package com.android.bluetooth.a2dp; import static android.Manifest.permission.BLUETOOTH_CONNECT; @@ -78,13 +62,11 @@ final class A2dpStateMachine extends StateMachine { static final int CONNECT = 1; static final int DISCONNECT = 2; - @VisibleForTesting - static final int STACK_EVENT = 101; + @VisibleForTesting static final int STACK_EVENT = 101; private static final int CONNECT_TIMEOUT = 201; // NOTE: the value is not "final" - it is modified in the unit tests - @VisibleForTesting - static int sConnectTimeoutMs = 30000; // 30s + @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s private Disconnected mDisconnected; private Connecting mConnecting; @@ -95,14 +77,16 @@ final class A2dpStateMachine extends StateMachine { private A2dpService mA2dpService; private A2dpNativeInterface mA2dpNativeInterface; - @VisibleForTesting - boolean mA2dpOffloadEnabled = false; + @VisibleForTesting boolean mA2dpOffloadEnabled = false; private final BluetoothDevice mDevice; private boolean mIsPlaying = false; private BluetoothCodecStatus mCodecStatus; - A2dpStateMachine(BluetoothDevice device, A2dpService a2dpService, - A2dpNativeInterface a2dpNativeInterface, Looper looper) { + A2dpStateMachine( + BluetoothDevice device, + A2dpService a2dpService, + A2dpNativeInterface a2dpNativeInterface, + Looper looper) { super(TAG, looper); // Let the logging framework enforce the log level. TAG is set above in the parent @@ -127,11 +111,14 @@ final class A2dpStateMachine extends StateMachine { setInitialState(mDisconnected); } - static A2dpStateMachine make(BluetoothDevice device, A2dpService a2dpService, - A2dpNativeInterface a2dpNativeInterface, Looper looper) { + static A2dpStateMachine make( + BluetoothDevice device, + A2dpService a2dpService, + A2dpNativeInterface a2dpNativeInterface, + Looper looper) { Log.i(TAG, "make for device " + device); - A2dpStateMachine a2dpSm = new A2dpStateMachine(device, a2dpService, a2dpNativeInterface, - looper); + A2dpStateMachine a2dpSm = + new A2dpStateMachine(device, a2dpService, a2dpNativeInterface, looper); a2dpSm.start(); return a2dpSm; } @@ -142,8 +129,7 @@ final class A2dpStateMachine extends StateMachine { // Stop if auido is still playing log("doQuit: stopped playing " + mDevice); mIsPlaying = false; - broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, - BluetoothA2dp.STATE_PLAYING); + broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, BluetoothA2dp.STATE_PLAYING); } quitNow(); } @@ -157,8 +143,14 @@ final class A2dpStateMachine extends StateMachine { @Override public void enter() { Message currentMessage = getCurrentMessage(); - Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + Log.i( + TAG, + "Enter Disconnected(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); mConnectionState = BluetoothProfile.STATE_DISCONNECTED; removeDeferredMessages(DISCONNECT); @@ -169,8 +161,8 @@ final class A2dpStateMachine extends StateMachine { if (mIsPlaying) { Log.i(TAG, "Disconnected: stopped playing: " + mDevice); mIsPlaying = false; - broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, - BluetoothA2dp.STATE_PLAYING); + broadcastAudioState( + BluetoothA2dp.STATE_NOT_PLAYING, BluetoothA2dp.STATE_PLAYING); } } @@ -180,15 +172,23 @@ final class A2dpStateMachine extends StateMachine { @Override public void exit() { Message currentMessage = getCurrentMessage(); - log("Exit Disconnected(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + log( + "Exit Disconnected(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Disconnected process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -294,8 +294,14 @@ final class A2dpStateMachine extends StateMachine { @Override public void enter() { Message currentMessage = getCurrentMessage(); - Log.i(TAG, "Enter Connecting(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + Log.i( + TAG, + "Enter Connecting(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_CONNECTING; broadcastConnectionState(mConnectionState, mLastConnectionState); @@ -304,33 +310,43 @@ final class A2dpStateMachine extends StateMachine { @Override public void exit() { Message currentMessage = getCurrentMessage(); - log("Exit Connecting(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + log( + "Exit Connecting(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Connecting connection timeout: " + mDevice); - mA2dpNativeInterface.disconnectA2dp(mDevice); - A2dpStackEvent event = - new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - event.device = mDevice; - event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, event); - MetricsLogger.getInstance().count( - BluetoothProtoEnums.A2DP_CONNECTION_TIMEOUT, 1); - break; - } + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Connecting connection timeout: " + mDevice); + mA2dpNativeInterface.disconnectA2dp(mDevice); + A2dpStackEvent event = + new A2dpStackEvent( + A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event.device = mDevice; + event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, event); + MetricsLogger.getInstance() + .count(BluetoothProtoEnums.A2DP_CONNECTION_TIMEOUT, 1); + break; + } case DISCONNECT: // Cancel connection Log.i(TAG, "Connecting: connection canceled to " + mDevice); @@ -392,8 +408,14 @@ final class A2dpStateMachine extends StateMachine { @Override public void enter() { Message currentMessage = getCurrentMessage(); - Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + Log.i( + TAG, + "Enter Disconnecting(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_DISCONNECTING; broadcastConnectionState(mConnectionState, mLastConnectionState); @@ -402,31 +424,41 @@ final class A2dpStateMachine extends StateMachine { @Override public void exit() { Message currentMessage = getCurrentMessage(); - log("Exit Disconnecting(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + log( + "Exit Disconnecting(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Disconnecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Disconnecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Disconnecting connection timeout: " + mDevice); - mA2dpNativeInterface.disconnectA2dp(mDevice); - A2dpStackEvent event = - new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - event.device = mDevice; - event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, event); - break; - } + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Disconnecting connection timeout: " + mDevice); + mA2dpNativeInterface.disconnectA2dp(mDevice); + A2dpStackEvent event = + new A2dpStackEvent( + A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + event.device = mDevice; + event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, event); + break; + } case DISCONNECT: deferMessage(message); break; @@ -497,8 +529,14 @@ final class A2dpStateMachine extends StateMachine { @Override public void enter() { Message currentMessage = getCurrentMessage(); - Log.i(TAG, "Enter Connected(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + Log.i( + TAG, + "Enter Connected(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); mConnectionState = BluetoothProfile.STATE_CONNECTED; removeDeferredMessages(CONNECT); @@ -518,8 +556,13 @@ final class A2dpStateMachine extends StateMachine { @Override public void exit() { Message currentMessage = getCurrentMessage(); - log("Exit Connected(" + mDevice + "): " + (currentMessage == null ? "null" - : messageWhatToString(currentMessage.what))); + log( + "Exit Connected(" + + mDevice + + "): " + + (currentMessage == null + ? "null" + : messageWhatToString(currentMessage.what))); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @@ -531,17 +574,19 @@ final class A2dpStateMachine extends StateMachine { case CONNECT: Log.w(TAG, "Connected: CONNECT ignored: " + mDevice); break; - case DISCONNECT: { - Log.i(TAG, "Disconnecting from " + mDevice); - if (!mA2dpNativeInterface.disconnectA2dp(mDevice)) { - // If error in the native stack, transition directly to Disconnected state. - Log.e(TAG, "Connected: error disconnecting from " + mDevice); - transitionTo(mDisconnected); - break; + case DISCONNECT: + { + Log.i(TAG, "Disconnecting from " + mDevice); + if (!mA2dpNativeInterface.disconnectA2dp(mDevice)) { + // If error in the native stack, transition directly to Disconnected + // state. + Log.e(TAG, "Connected: error disconnecting from " + mDevice); + transitionTo(mDisconnected); + break; + } + transitionTo(mDisconnecting); } - transitionTo(mDisconnecting); - } - break; + break; case STACK_EVENT: A2dpStackEvent event = (A2dpStackEvent) message.obj; log("Connected: stack event: " + event); @@ -600,8 +645,8 @@ final class A2dpStateMachine extends StateMachine { if (!mIsPlaying) { Log.i(TAG, "Connected: started playing: " + mDevice); mIsPlaying = true; - broadcastAudioState(BluetoothA2dp.STATE_PLAYING, - BluetoothA2dp.STATE_NOT_PLAYING); + broadcastAudioState( + BluetoothA2dp.STATE_PLAYING, BluetoothA2dp.STATE_NOT_PLAYING); } } break; @@ -611,8 +656,8 @@ final class A2dpStateMachine extends StateMachine { if (mIsPlaying) { Log.i(TAG, "Connected: stopped playing: " + mDevice); mIsPlaying = false; - broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, - BluetoothA2dp.STATE_PLAYING); + broadcastAudioState( + BluetoothA2dp.STATE_NOT_PLAYING, BluetoothA2dp.STATE_PLAYING); } } break; @@ -679,10 +724,13 @@ final class A2dpStateMachine extends StateMachine { // The following is a large enough debug operation such that we want to guard it was an // isLoggable check if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "A2DP Codec Config: " + prevCodecConfig + "->" - + newCodecStatus.getCodecConfig()); - for (BluetoothCodecConfig codecConfig : - newCodecStatus.getCodecsLocalCapabilities()) { + Log.d( + TAG, + "A2DP Codec Config: " + + prevCodecConfig + + "->" + + newCodecStatus.getCodecConfig()); + for (BluetoothCodecConfig codecConfig : newCodecStatus.getCodecsLocalCapabilities()) { Log.d(TAG, "A2DP Codec Local Capability: " + codecConfig); } for (BluetoothCodecConfig codecConfig : @@ -707,17 +755,17 @@ final class A2dpStateMachine extends StateMachine { } else if (!newCodecConfig.sameAudioFeedingParameters(prevCodecConfig)) { update = true; } else if ((newCodecConfig.getCodecType() - == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) + == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) && (prevCodecConfig != null) && (prevCodecConfig.getCodecSpecific1() - != newCodecConfig.getCodecSpecific1())) { + != newCodecConfig.getCodecSpecific1())) { update = true; } else if ((newCodecConfig.getCodecType() - == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) + == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) && (prevCodecConfig != null) // check framesize field && (prevCodecConfig.getCodecSpecific1() - != newCodecConfig.getCodecSpecific1())) { + != newCodecConfig.getCodecSpecific1())) { update = true; } if (update) { @@ -733,14 +781,20 @@ final class A2dpStateMachine extends StateMachine { // This method does not check for error condition (newState == prevState) private void broadcastConnectionState(int newState, int prevState) { - log("Connection state " + mDevice + ": " + profileStateToString(prevState) - + "->" + profileStateToString(newState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(prevState) + + "->" + + profileStateToString(newState)); Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mA2dpService.handleConnectionStateChanged(mDevice, prevState, newState); mA2dpService.sendBroadcast( @@ -748,8 +802,13 @@ final class A2dpStateMachine extends StateMachine { } private void broadcastAudioState(int newState, int prevState) { - log("A2DP Playing state : device: " + mDevice + " State:" + audioStateToString(prevState) - + "->" + audioStateToString(newState)); + log( + "A2DP Playing state : device: " + + mDevice + + " State:" + + audioStateToString(prevState) + + "->" + + audioStateToString(newState)); Intent intent = new Intent(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); @@ -773,8 +832,8 @@ final class A2dpStateMachine extends StateMachine { return builder.toString(); } - private static boolean sameSelectableCodec(BluetoothCodecStatus prevCodecStatus, - BluetoothCodecStatus newCodecStatus) { + private static boolean sameSelectableCodec( + BluetoothCodecStatus prevCodecStatus, BluetoothCodecStatus newCodecStatus) { if (prevCodecStatus == null || newCodecStatus == null) { return false; } @@ -838,16 +897,23 @@ final class A2dpStateMachine extends StateMachine { public void dump(StringBuilder sb) { boolean isActive = Objects.equals(mDevice, mA2dpService.getActiveDevice()); - ProfileService.println(sb, - "=== A2dpStateMachine for " + mDevice + (isActive ? " (Active) ===" : " ===")); - ProfileService.println(sb, - " getConnectionPolicy: " + mA2dpService.getConnectionPolicy(mDevice)); - ProfileService.println(sb, " mConnectionState: " + profileStateToString(mConnectionState) - + ", mLastConnectionState: " + profileStateToString(mLastConnectionState)); + ProfileService.println( + sb, "=== A2dpStateMachine for " + mDevice + (isActive ? " (Active) ===" : " ===")); + ProfileService.println( + sb, " getConnectionPolicy: " + mA2dpService.getConnectionPolicy(mDevice)); + ProfileService.println( + sb, + " mConnectionState: " + + profileStateToString(mConnectionState) + + ", mLastConnectionState: " + + profileStateToString(mLastConnectionState)); ProfileService.println(sb, " mIsPlaying: " + mIsPlaying); - ProfileService.println(sb, - " getSupportsOptionalCodecs: " + mA2dpService.getSupportsOptionalCodecs(mDevice) - + ", getOptionalCodecsEnabled: " + mA2dpService.getOptionalCodecsEnabled(mDevice)); + ProfileService.println( + sb, + " getSupportsOptionalCodecs: " + + mA2dpService.getSupportsOptionalCodecs(mDevice) + + ", getOptionalCodecsEnabled: " + + mA2dpService.getOptionalCodecsEnabled(mDevice)); synchronized (this) { if (mCodecStatus != null) { ProfileService.println(sb, " mCodecConfig: " + mCodecStatus.getCodecConfig()); @@ -861,7 +927,7 @@ final class A2dpStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java index 944291a2829..1f599fa1c44 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java @@ -27,9 +27,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; -/** - * A2DP Sink Native Interface to/from JNI. - */ +/** A2DP Sink Native Interface to/from JNI. */ public class A2dpSinkNativeInterface { private static final String TAG = A2dpSinkNativeInterface.class.getSimpleName(); private AdapterService mAdapterService; @@ -40,13 +38,13 @@ public class A2dpSinkNativeInterface { private static final Object INSTANCE_LOCK = new Object(); private A2dpSinkNativeInterface() { - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when A2dpSinkNativeInterface init"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when A2dpSinkNativeInterface init"); } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static A2dpSinkNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -73,9 +71,7 @@ public class A2dpSinkNativeInterface { initNative(maxConnectedAudioDevices); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ public void cleanup() { cleanupNative(); } @@ -115,10 +111,10 @@ public class A2dpSinkNativeInterface { /** * Set a BluetoothDevice as the active device * - * The active device is the only one that will receive passthrough commands and the only one + *

The active device is the only one that will receive passthrough commands and the only one * that will have its audio decoded. * - * Sending null for the active device will make no device active. + *

Sending null for the active device will make no device active. * * @param device * @return True if the active device request has been scheduled @@ -152,9 +148,7 @@ public class A2dpSinkNativeInterface { informAudioTrackGainNative(gain); } - /** - * Send a stack event up to the A2DP Sink Service - */ + /** Send a stack event up to the A2DP Sink Service */ private void sendMessageToService(StackEvent event) { A2dpSinkService service = A2dpSinkService.getA2dpSinkService(); if (service != null) { @@ -164,41 +158,40 @@ public class A2dpSinkNativeInterface { } } - /** - * For the JNI to send messages about connection state changes - */ + /** For the JNI to send messages about connection state changes */ public void onConnectionStateChanged(byte[] address, int state) { - StackEvent event = - StackEvent.connectionStateChanged(getDevice(address), state); + StackEvent event = StackEvent.connectionStateChanged(getDevice(address), state); Log.d(TAG, "onConnectionStateChanged: " + event); sendMessageToService(event); } - /** - * For the JNI to send messages about audio stream state changes - */ + /** For the JNI to send messages about audio stream state changes */ public void onAudioStateChanged(byte[] address, int state) { StackEvent event = StackEvent.audioStateChanged(getDevice(address), state); Log.d(TAG, "onAudioStateChanged: " + event); sendMessageToService(event); } - /** - * For the JNI to send messages about audio configuration changes - */ + /** For the JNI to send messages about audio configuration changes */ public void onAudioConfigChanged(byte[] address, int sampleRate, int channelCount) { - StackEvent event = StackEvent.audioConfigChanged( - getDevice(address), sampleRate, channelCount); + StackEvent event = + StackEvent.audioConfigChanged(getDevice(address), sampleRate, channelCount); Log.d(TAG, "onAudioConfigChanged: " + event); sendMessageToService(event); } // Native methods that call into the JNI interface private native void initNative(int maxConnectedAudioDevices); + private native void cleanupNative(); + private native boolean connectA2dpNative(byte[] address); + private native boolean disconnectA2dpNative(byte[] address); + private native boolean setActiveDeviceNative(byte[] address); + private native void informAudioFocusStateNative(int focusGranted); + private native void informAudioTrackGainNative(float gain); } diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java index 1bb970577bb..0965e07c653 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java @@ -44,9 +44,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -/** - * Provides Bluetooth A2DP Sink profile, as a service in the Bluetooth application. - */ +/** Provides Bluetooth A2DP Sink profile, as a service in the Bluetooth application. */ public class A2dpSinkService extends ProfileService { private static final String TAG = A2dpSinkService.class.getSimpleName(); @@ -131,17 +129,13 @@ public class A2dpSinkService extends ProfileService { return sService; } - /** - * Testing API to inject a mockA2dpSinkService. - */ + /** Testing API to inject a mockA2dpSinkService. */ @VisibleForTesting public static synchronized void setA2dpSinkService(A2dpSinkService service) { sService = service; } - /** - * Set the device that should be allowed to actively stream - */ + /** Set the device that should be allowed to actively stream */ public boolean setActiveDevice(BluetoothDevice device) { Log.i(TAG, "setActiveDevice(device=" + device + ")"); synchronized (mActiveDeviceLock) { @@ -153,18 +147,14 @@ public class A2dpSinkService extends ProfileService { } } - /** - * Get the device that is allowed to be actively streaming - */ + /** Get the device that is allowed to be actively streaming */ public BluetoothDevice getActiveDevice() { synchronized (mActiveDeviceLock) { return mActiveDevice; } } - /** - * Request audio focus such that the designated device can stream audio - */ + /** Request audio focus such that the designated device can stream audio */ public void requestAudioFocus(BluetoothDevice device, boolean request) { synchronized (mStreamHandlerLock) { if (mA2dpSinkStreamHandler == null) return; @@ -199,7 +189,7 @@ public class A2dpSinkService extends ProfileService { return new A2dpSinkServiceBinder(this); } - //Binder object: Must be static class or memory leak may occur + // Binder object: Must be static class or memory leak may occur @VisibleForTesting static class A2dpSinkServiceBinder extends IBluetoothA2dpSink.Stub implements IProfileServiceBinder { @@ -322,14 +312,13 @@ public class A2dpSinkService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { Log.d(TAG, "connect device=" + device); - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); if (device == null) { throw new IllegalArgumentException("Null device"); } if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - Log.w(TAG, "Connection not allowed: <" + device - + "> is CONNECTION_POLICY_FORBIDDEN"); + Log.w(TAG, "Connection not allowed: <" + device + "> is CONNECTION_POLICY_FORBIDDEN"); return false; } @@ -339,8 +328,11 @@ public class A2dpSinkService extends ProfileService { return true; } else { // a state machine instance doesn't exist yet, and the max has been reached. - Log.e(TAG, "Maxed out on the number of allowed A2DP Sink connections. " - + "Connect request rejected on " + device); + Log.e( + TAG, + "Maxed out on the number of allowed A2DP Sink connections. " + + "Connect request rejected on " + + device); return false; } } @@ -388,7 +380,7 @@ public class A2dpSinkService extends ProfileService { } public List getConnectedDevices() { - return getDevicesMatchingConnectionStates(new int[]{BluetoothAdapter.STATE_CONNECTED}); + return getDevicesMatchingConnectionStates(new int[] {BluetoothAdapter.STATE_CONNECTED}); } protected A2dpSinkStateMachine getOrCreateStateMachine(BluetoothDevice device) { @@ -425,8 +417,12 @@ public class A2dpSinkService extends ProfileService { } } } - Log.d(TAG, "getDevicesMatchingConnectionStates(" + Arrays.toString(states) + "): Found " - + deviceList.toString()); + Log.d( + TAG, + "getDevicesMatchingConnectionStates(" + + Arrays.toString(states) + + "): Found " + + deviceList.toString()); return deviceList; } @@ -434,28 +430,28 @@ public class A2dpSinkService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { if (device == null) return BluetoothProfile.STATE_DISCONNECTED; A2dpSinkStateMachine stateMachine = mDeviceStateMap.get(device); - return (stateMachine == null) ? BluetoothProfile.STATE_DISCONNECTED + return (stateMachine == null) + ? BluetoothProfile.STATE_DISCONNECTED : stateMachine.getState(); } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -467,8 +463,8 @@ public class A2dpSinkService extends ProfileService { BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.A2DP_SINK, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.A2DP_SINK, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -489,11 +485,9 @@ public class A2dpSinkService extends ProfileService { public int getConnectionPolicy(BluetoothDevice device) { enforceCallingOrSelfPermission( BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.A2DP_SINK); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.A2DP_SINK); } - @Override public void dump(StringBuilder sb) { super.dump(sb); @@ -501,8 +495,8 @@ public class A2dpSinkService extends ProfileService { ProfileService.println(sb, "Max Connected Devices = " + mMaxConnectedAudioDevices); ProfileService.println(sb, "Devices Tracked = " + mDeviceStateMap.size()); for (A2dpSinkStateMachine stateMachine : mDeviceStateMap.values()) { - ProfileService.println(sb, - "==== StateMachine for " + stateMachine.getDevice() + " ===="); + ProfileService.println( + sb, "==== StateMachine for " + stateMachine.getDevice() + " ===="); stateMachine.dump(sb); } } @@ -517,9 +511,7 @@ public class A2dpSinkService extends ProfileService { return stateMachine.getAudioConfig(); } - /** - * Receive and route a stack event from the JNI - */ + /** Receive and route a stack event from the JNI */ protected void messageFromNative(StackEvent event) { switch (event.mType) { case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: @@ -553,12 +545,14 @@ public class A2dpSinkService extends ProfileService { Log.e(TAG, "Received audio state change before we've been started"); return; } else if (state == StackEvent.AUDIO_STATE_STARTED) { - mA2dpSinkStreamHandler.obtainMessage( - A2dpSinkStreamHandler.SRC_STR_START).sendToTarget(); + mA2dpSinkStreamHandler + .obtainMessage(A2dpSinkStreamHandler.SRC_STR_START) + .sendToTarget(); } else if (state == StackEvent.AUDIO_STATE_STOPPED || state == StackEvent.AUDIO_STATE_REMOTE_SUSPEND) { - mA2dpSinkStreamHandler.obtainMessage( - A2dpSinkStreamHandler.SRC_STR_STOP).sendToTarget(); + mA2dpSinkStreamHandler + .obtainMessage(A2dpSinkStreamHandler.SRC_STR_STOP) + .sendToTarget(); } else { Log.w(TAG, "Unhandled audio state change, state=" + state); } diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java index f08c13a9511..927dcefefb9 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java @@ -98,9 +98,7 @@ class A2dpSinkStateMachine extends StateMachine { return mMostRecentState; } - /** - * get current audio config - */ + /** get current audio config */ BluetoothAudioConfig getAudioConfig() { return mAudioConfig; } @@ -131,17 +129,24 @@ class A2dpSinkStateMachine extends StateMachine { /** * Dump the current State Machine to the string builder. + * * @param sb output string */ public void dump(StringBuilder sb) { - ProfileService.println(sb, "mDevice: " + mDevice + "(" - + Utils.getName(mDevice) + ") " + this.toString()); + ProfileService.println( + sb, "mDevice: " + mDevice + "(" + Utils.getName(mDevice) + ") " + this.toString()); } @Override protected void unhandledMessage(Message msg) { - Log.w(TAG, "[" + mDevice + "] unhandledMessage state=" + getCurrentState() + ", msg.what=" - + msg.what); + Log.w( + TAG, + "[" + + mDevice + + "] unhandledMessage state=" + + getCurrentState() + + ", msg.what=" + + msg.what); } class Disconnected extends State { @@ -179,8 +184,12 @@ class A2dpSinkStateMachine extends StateMachine { case StackEvent.CONNECTION_STATE_CONNECTING: if (mService.getConnectionPolicy(mDevice) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - Log.w(TAG, "[" + mDevice + "] Ignore incoming connection, profile" - + " is turned off"); + Log.w( + TAG, + "[" + + mDevice + + "] Ignore incoming connection, profile" + + " is turned off"); mNativeInterface.disconnectA2dpSink(mDevice); } else { mConnecting.mIncomingConnection = true; @@ -224,8 +233,12 @@ class A2dpSinkStateMachine extends StateMachine { transitionTo(mDisconnected); return true; case DISCONNECT: - Log.d(TAG, "[" + mDevice + "] Received disconnect message while connecting." - + "deferred"); + Log.d( + TAG, + "[" + + mDevice + + "] Received disconnect message while connecting." + + "deferred"); deferMessage(message); return true; } @@ -245,12 +258,12 @@ class A2dpSinkStateMachine extends StateMachine { } } } + @Override public void exit() { removeMessages(CONNECT_TIMEOUT); mIncomingConnection = false; } - } class Connected extends State { @@ -287,8 +300,11 @@ class A2dpSinkStateMachine extends StateMachine { } break; case StackEvent.EVENT_TYPE_AUDIO_CONFIG_CHANGED: - mAudioConfig = new BluetoothAudioConfig(event.mSampleRate, event.mChannelCount, - AudioFormat.ENCODING_PCM_16BIT); + mAudioConfig = + new BluetoothAudioConfig( + event.mSampleRate, + event.mChannelCount, + AudioFormat.ENCODING_PCM_16BIT); break; } } diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java index 754ec288176..6cf7d99643a 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java @@ -32,20 +32,20 @@ import com.android.bluetooth.avrcpcontroller.AvrcpControllerService; /** * Bluetooth A2DP SINK Streaming Handler. * - * This handler defines how the stack behaves once the A2DP connection is established and both + *

This handler defines how the stack behaves once the A2DP connection is established and both * devices are ready for streaming. For simplification we assume that the connection can either * stream music immediately (i.e. data packets coming in or have potential to come in) or it cannot * stream (i.e. Idle and Open states are treated alike). See Fig 4-1 of GAVDP Spec 1.0. * - * Note: There are several different audio tracks that a connected phone may like to transmit over - * the A2DP stream including Music, Navigation, Assistant, and Notifications. Music is the only + *

Note: There are several different audio tracks that a connected phone may like to transmit + * over the A2DP stream including Music, Navigation, Assistant, and Notifications. Music is the only * track that is almost always accompanied with an AVRCP play/pause command. * - * Streaming is initiated by either an explicit play command from user interaction or audio coming - * from the phone. Streaming is terminated when either the user pauses the audio, the audio stream - * from the phone ends, the phone disconnects, or audio focus is lost. During playback if there is - * a change to audio focus playback may be temporarily paused and then resumed when focus is - * restored. + *

Streaming is initiated by either an explicit play command from user interaction or audio + * coming from the phone. Streaming is terminated when either the user pauses the audio, the audio + * stream from the phone ends, the phone disconnects, or audio focus is lost. During playback if + * there is a change to audio focus playback may be temporarily paused and then resumed when focus + * is restored. */ public class A2dpSinkStreamHandler extends Handler { private static final String TAG = A2dpSinkStreamHandler.class.getSimpleName(); @@ -89,25 +89,25 @@ public class A2dpSinkStreamHandler extends Handler { private MediaPlayer mMediaPlayer = null; // Focus changes when we are currently holding focus. - private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() { - @Override - public void onAudioFocusChange(int focusChange) { - Log.d(TAG, "onAudioFocusChangeListener(focusChange= " + focusChange + ")"); - A2dpSinkStreamHandler.this.obtainMessage(AUDIO_FOCUS_CHANGE, focusChange) - .sendToTarget(); - } - }; + private OnAudioFocusChangeListener mAudioFocusListener = + new OnAudioFocusChangeListener() { + @Override + public void onAudioFocusChange(int focusChange) { + Log.d(TAG, "onAudioFocusChangeListener(focusChange= " + focusChange + ")"); + A2dpSinkStreamHandler.this + .obtainMessage(AUDIO_FOCUS_CHANGE, focusChange) + .sendToTarget(); + } + }; - public A2dpSinkStreamHandler(A2dpSinkService a2dpSinkService, - A2dpSinkNativeInterface nativeInterface) { + public A2dpSinkStreamHandler( + A2dpSinkService a2dpSinkService, A2dpSinkNativeInterface nativeInterface) { mA2dpSinkService = a2dpSinkService; mNativeInterface = nativeInterface; mAudioManager = mA2dpSinkService.getSystemService(AudioManager.class); } - /** - * Safely clean up this stream handler object - */ + /** Safely clean up this stream handler object */ public void cleanup() { abandonAudioFocus(); removeCallbacksAndMessages(null); @@ -124,7 +124,7 @@ public class A2dpSinkStreamHandler extends Handler { boolean isPlaying() { return (mStreamAvailable && (mAudioFocus == AudioManager.AUDIOFOCUS_GAIN - || mAudioFocus == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); + || mAudioFocus == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); } @Override @@ -177,8 +177,12 @@ public class A2dpSinkStreamHandler extends Handler { case AUDIO_FOCUS_CHANGE: final int focusChangeCode = (int) message.obj; - Log.d(TAG, "New audioFocus = " + focusChangeCode - + " Previous audio focus = " + mAudioFocus); + Log.d( + TAG, + "New audioFocus = " + + focusChangeCode + + " Previous audio focus = " + + mAudioFocus); mAudioFocus = focusChangeCode; // message.obj is the newly granted audio focus. switch (mAudioFocus) { @@ -189,8 +193,10 @@ public class A2dpSinkStreamHandler extends Handler { case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Make the volume duck. - int duckPercent = mA2dpSinkService.getResources() - .getInteger(R.integer.a2dp_sink_duck_percent); + int duckPercent = + mA2dpSinkService + .getResources() + .getInteger(R.integer.a2dp_sink_duck_percent); if (duckPercent < 0 || duckPercent > 100) { Log.e(TAG, "Invalid duck percent using default."); duckPercent = DEFAULT_DUCK_PERCENT; @@ -226,9 +232,7 @@ public class A2dpSinkStreamHandler extends Handler { } } - /** - * Utility functions. - */ + /** Utility functions. */ private void requestAudioFocusIfNone() { Log.d(TAG, "requestAudioFocusIfNone()"); if (mAudioFocus != AudioManager.AUDIOFOCUS_GAIN) { @@ -241,21 +245,22 @@ public class A2dpSinkStreamHandler extends Handler { // Bluetooth A2DP may carry Music, Audio Books, Navigation, or other sounds so mark content // type unknown. AudioAttributes streamAttributes = - new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA) + new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) .build(); // Bluetooth ducking is handled at the native layer at the request of AudioManager. AudioFocusRequest focusRequest = - new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).setAudioAttributes( - streamAttributes) + new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) + .setAudioAttributes(streamAttributes) .setOnAudioFocusChangeListener(mAudioFocusListener, this) .build(); int focusRequestStatus = mAudioManager.requestAudioFocus(focusRequest); // If the request is granted begin streaming immediately and schedule an upgrade. if (focusRequestStatus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { mAudioFocus = AudioManager.AUDIOFOCUS_GAIN; - final Message a2dpSinkStreamHandlerMessage = A2dpSinkStreamHandler.this - .obtainMessage(AUDIO_FOCUS_CHANGE, mAudioFocus); + final Message a2dpSinkStreamHandlerMessage = + A2dpSinkStreamHandler.this.obtainMessage(AUDIO_FOCUS_CHANGE, mAudioFocus); A2dpSinkStreamHandler.this.sendMessageAtFrontOfQueue(a2dpSinkStreamHandlerMessage); } else { Log.e(TAG, "Audio focus was not granted:" + focusRequestStatus); @@ -267,32 +272,36 @@ public class A2dpSinkStreamHandler extends Handler { * Plays a silent audio sample so that MediaSessionService will be aware of the fact that * Bluetooth is playing audio. * - * Creates a new MediaPlayer if one does not already exist. Repeat calls to this function are + *

Creates a new MediaPlayer if one does not already exist. Repeat calls to this function are * safe and will result in the silent audio sample again. * - * This allows the MediaSession in AVRCP Controller to be routed media key events, if we've + *

This allows the MediaSession in AVRCP Controller to be routed media key events, if we've * chosen to use it. */ private synchronized void requestMediaKeyFocus() { Log.d(TAG, "requestMediaKeyFocus()"); if (mMediaPlayer == null) { - AudioAttributes attrs = new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_MEDIA) - .build(); - - mMediaPlayer = MediaPlayer.create(mA2dpSinkService, R.raw.silent, attrs, - mAudioManager.generateAudioSessionId()); + AudioAttributes attrs = + new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(); + + mMediaPlayer = + MediaPlayer.create( + mA2dpSinkService, + R.raw.silent, + attrs, + mAudioManager.generateAudioSessionId()); if (mMediaPlayer == null) { Log.e(TAG, "Failed to initialize media player. You may not get media key events"); return; } mMediaPlayer.setLooping(false); - mMediaPlayer.setOnErrorListener((mp, what, extra) -> { - Log.e(TAG, "Silent media player error: " + what + ", " + extra); - releaseMediaKeyFocus(); - return false; - }); + mMediaPlayer.setOnErrorListener( + (mp, what, extra) -> { + Log.e(TAG, "Silent media player error: " + what + ", " + extra); + releaseMediaKeyFocus(); + return false; + }); } mMediaPlayer.start(); @@ -306,8 +315,8 @@ public class A2dpSinkStreamHandler extends Handler { } /** - * Destroys the silent audio sample MediaPlayer, notifying MediaSessionService of the fact - * we're no longer playing audio. + * Destroys the silent audio sample MediaPlayer, notifying MediaSessionService of the fact we're + * no longer playing audio. */ private synchronized void releaseMediaKeyFocus() { Log.d(TAG, "releaseMediaKeyFocus()"); @@ -335,17 +344,20 @@ public class A2dpSinkStreamHandler extends Handler { } private boolean isIotDevice() { - return mA2dpSinkService.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_EMBEDDED); + return mA2dpSinkService + .getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_EMBEDDED); } private boolean isTvDevice() { - return mA2dpSinkService.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_LEANBACK); + return mA2dpSinkService + .getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_LEANBACK); } private boolean shouldRequestFocus() { - return mA2dpSinkService.getResources() + return mA2dpSinkService + .getResources() .getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus); } } diff --git a/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java b/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java index 5d0947f03e1..93ade754394 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java @@ -56,8 +56,11 @@ final class StackEvent { s += "EVENT_TYPE_AUDIO_STATE_CHANGED, state=" + mState; break; case EVENT_TYPE_AUDIO_CONFIG_CHANGED: - s += "EVENT_TYPE_AUDIO_CONFIG_CHANGED, sampleRate=" + mSampleRate - + ", channelCount=" + mChannelCount; + s += + "EVENT_TYPE_AUDIO_CONFIG_CHANGED, sampleRate=" + + mSampleRate + + ", channelCount=" + + mChannelCount; break; default: s += "Unknown"; @@ -81,8 +84,7 @@ final class StackEvent { return event; } - static StackEvent audioConfigChanged(BluetoothDevice device, int sampleRate, - int channelCount) { + static StackEvent audioConfigChanged(BluetoothDevice device, int sampleRate, int channelCount) { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_AUDIO_CONFIG_CHANGED); event.mDevice = device; event.mSampleRate = sampleRate; diff --git a/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java b/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java index 4e113433b75..6386a0ce89f 100644 --- a/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java +++ b/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java @@ -32,14 +32,13 @@ import java.util.List; import java.util.Set; /** - * This class provides a way to connect to multiple browsable players at a time. - * It will attempt to simultaneously connect to a list of services that support - * the MediaBrowserService. After a timeout, the list of connected players will - * be returned via callback. + * This class provides a way to connect to multiple browsable players at a time. It will attempt to + * simultaneously connect to a list of services that support the MediaBrowserService. After a + * timeout, the list of connected players will be returned via callback. * - * The main use of this class is to check whether a player can be browsed despite - * using the MediaBrowserService. This way we do not have to do the same checks - * when constructing BrowsedPlayerWrappers by hand. + *

The main use of this class is to check whether a player can be browsed despite using the + * MediaBrowserService. This way we do not have to do the same checks when constructing + * BrowsedPlayerWrappers by hand. */ public class BrowsablePlayerConnector extends Handler { private static final String TAG = "AvrcpBrowsablePlayerConnector"; @@ -66,10 +65,7 @@ public class BrowsablePlayerConnector extends Handler { } static BrowsablePlayerConnector connectToPlayers( - Context context, - Looper looper, - List players, - PlayerListCallback cb) { + Context context, Looper looper, List players, PlayerListCallback cb) { if (sInjectConnector != null) { return sInjectConnector; } @@ -82,19 +78,23 @@ public class BrowsablePlayerConnector extends Handler { // Try to start connecting all the browsed player wrappers for (ResolveInfo info : players) { - BrowsedPlayerWrapper player = BrowsedPlayerWrapper.wrap( - context, - looper, - info.serviceInfo.packageName, - info.serviceInfo.name); + BrowsedPlayerWrapper player = + BrowsedPlayerWrapper.wrap( + context, looper, info.serviceInfo.packageName, info.serviceInfo.name); newConnector.mPendingPlayers.add(player); - player.connect((int status, BrowsedPlayerWrapper wrapper) -> { - // Use the handler to avoid concurrency issues - Log.d(TAG, "Browse player callback called: package=" - + info.serviceInfo.packageName - + " : status=" + status); - newConnector.obtainMessage(MSG_CONNECT_CB, status, 0, wrapper).sendToTarget(); - }); + player.connect( + (int status, BrowsedPlayerWrapper wrapper) -> { + // Use the handler to avoid concurrency issues + Log.d( + TAG, + "Browse player callback called: package=" + + info.serviceInfo.packageName + + " : status=" + + status); + newConnector + .obtainMessage(MSG_CONNECT_CB, status, 0, wrapper) + .sendToTarget(); + }); } newConnector.sendEmptyMessageDelayed(MSG_TIMEOUT, CONNECT_TIMEOUT_MS); @@ -125,62 +125,71 @@ public class BrowsablePlayerConnector extends Handler { @Override public void handleMessage(Message msg) { Log.d(TAG, "Received a message: msg.what=" + msg.what); - switch(msg.what) { - case MSG_GET_FOLDER_ITEMS_CB: { - int status = msg.arg1; - int results_size = msg.arg2; - BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj; - - // If we failed to remove the wrapper from the pending set, that - // means a timeout occurred and the callback was triggered afterwards - // or the connector was cleaned up. - if (!mPendingPlayers.remove(wrapper)) { - return; - } - - if (status == BrowsedPlayerWrapper.STATUS_SUCCESS && results_size != 0) { - Log.i(TAG, "Successfully added package to results: " - + wrapper.getPackageName()); - mResults.add(wrapper); - } - break; - } - - case MSG_CONNECT_CB: { - BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj; + switch (msg.what) { + case MSG_GET_FOLDER_ITEMS_CB: + { + int status = msg.arg1; + int results_size = msg.arg2; + BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj; - if (msg.arg1 != BrowsedPlayerWrapper.STATUS_SUCCESS) { - Log.i(TAG, wrapper.getPackageName() + " is not browsable"); // If we failed to remove the wrapper from the pending set, that // means a timeout occurred and the callback was triggered afterwards + // or the connector was cleaned up. if (!mPendingPlayers.remove(wrapper)) { return; } + + if (status == BrowsedPlayerWrapper.STATUS_SUCCESS && results_size != 0) { + Log.i( + TAG, + "Successfully added package to results: " + + wrapper.getPackageName()); + mResults.add(wrapper); + } break; } - // Check to see if the root folder has any items - Log.i(TAG, "Checking root contents for " + wrapper.getPackageName()); - wrapper.getFolderItems(wrapper.getRootId(), - (int status, String mediaId, List results) -> { - // Send the response as a message so that it is properly - // synchronized - obtainMessage(MSG_GET_FOLDER_ITEMS_CB, status, results.size(), wrapper) - .sendToTarget(); - }); - break; - } - - case MSG_TIMEOUT: { - Log.v(TAG, "Timed out waiting for players"); - removePendingPlayers(); - break; - } + case MSG_CONNECT_CB: + { + BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj; + + if (msg.arg1 != BrowsedPlayerWrapper.STATUS_SUCCESS) { + Log.i(TAG, wrapper.getPackageName() + " is not browsable"); + // If we failed to remove the wrapper from the pending set, that + // means a timeout occurred and the callback was triggered afterwards + if (!mPendingPlayers.remove(wrapper)) { + return; + } + break; + } + + // Check to see if the root folder has any items + Log.i(TAG, "Checking root contents for " + wrapper.getPackageName()); + wrapper.getFolderItems( + wrapper.getRootId(), + (int status, String mediaId, List results) -> { + // Send the response as a message so that it is properly + // synchronized + obtainMessage( + MSG_GET_FOLDER_ITEMS_CB, + status, + results.size(), + wrapper) + .sendToTarget(); + }); + break; + } + + case MSG_TIMEOUT: + { + Log.v(TAG, "Timed out waiting for players"); + removePendingPlayers(); + break; + } } if (mPendingPlayers.size() == 0) { - Log.i(TAG, "Successfully connected to " - + mResults.size() + " browsable players."); + Log.i(TAG, "Successfully connected to " + mResults.size() + " browsable players."); removeMessages(MSG_TIMEOUT); mCallback.run(mResults); } diff --git a/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java index 19c6f89e51f..2bd3c66aa26 100644 --- a/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java +++ b/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java @@ -102,20 +102,21 @@ class BrowsedPlayerWrapper { // TODO (apanicke): Investigate if there is a way to create this just by passing in the // MediaBrowser. Right now there is no obvious way to create the browser then update the // connection callback without being forced to re-create the object every time. - private BrowsedPlayerWrapper(Context context, Looper looper, String packageName, - String className) { + private BrowsedPlayerWrapper( + Context context, Looper looper, String packageName, String className) { mContext = context; mPackageName = packageName; mLooper = looper; - mWrappedBrowser = MediaBrowserFactory.make( - context, - new ComponentName(packageName, className), - new MediaConnectionCallback(), - null); + mWrappedBrowser = + MediaBrowserFactory.make( + context, + new ComponentName(packageName, className), + new MediaConnectionCallback(), + null); } - static BrowsedPlayerWrapper wrap(Context context, Looper looper, String packageName, - String className) { + static BrowsedPlayerWrapper wrap( + Context context, Looper looper, String packageName, String className) { Log.i(TAG, "Wrapping Media Browser " + packageName); BrowsedPlayerWrapper wrapper = new BrowsedPlayerWrapper(context, looper, packageName, className); @@ -125,7 +126,7 @@ class BrowsedPlayerWrapper { /** * Connect to the media application's MediaBrowserService * - * Connections are asynchronous in nature. The given callback will be invoked once the + *

Connections are asynchronous in nature. The given callback will be invoked once the * connection is established. The connection will be torn down once your callback is executed * when using this function. If you wish to control the lifecycle of the connection on your own * then use {@link #setCallbackAndConnect(ConnectionCallback)} instead. @@ -135,19 +136,19 @@ class BrowsedPlayerWrapper { */ boolean connect(ConnectionCallback cb) { if (cb == null) { - Log.wtf(TAG, "connect: Trying to connect to " + mPackageName - + "with null callback"); + Log.wtf(TAG, "connect: Trying to connect to " + mPackageName + "with null callback"); } - return setCallbackAndConnect((int status, BrowsedPlayerWrapper wrapper) -> { - cb.run(status, wrapper); - disconnect(); - }); + return setCallbackAndConnect( + (int status, BrowsedPlayerWrapper wrapper) -> { + cb.run(status, wrapper); + disconnect(); + }); } /** * Disconnect from the media application's MediaBrowserService * - * This clears any pending requests. This function is safe to call even if a connection isn't + *

This clears any pending requests. This function is safe to call even if a connection isn't * currently open. */ void disconnect() { @@ -205,26 +206,32 @@ class BrowsedPlayerWrapper { */ public boolean playItem(String mediaId) { Log.d(TAG, "playItem: Play item from media ID: " + mediaId); - return setCallbackAndConnect((int status, BrowsedPlayerWrapper wrapper) -> { - Log.d(TAG, "playItem: Connected to browsable player " + mPackageName); - MediaController controller = MediaControllerFactory.make(mContext, - wrapper.mWrappedBrowser.getSessionToken()); - MediaController.TransportControls ctrl = controller.getTransportControls(); - Log.i(TAG, "playItem: Playing " + mediaId); - ctrl.playFromMediaId(mediaId, null); - - MediaPlaybackListener mpl = new MediaPlaybackListener(mLooper, controller); - mpl.waitForPlayback((int playbackStatus) -> { - Log.i(TAG, "playItem: Media item playback returned, status: " + playbackStatus); - disconnect(); - }); - }); + return setCallbackAndConnect( + (int status, BrowsedPlayerWrapper wrapper) -> { + Log.d(TAG, "playItem: Connected to browsable player " + mPackageName); + MediaController controller = + MediaControllerFactory.make( + mContext, wrapper.mWrappedBrowser.getSessionToken()); + MediaController.TransportControls ctrl = controller.getTransportControls(); + Log.i(TAG, "playItem: Playing " + mediaId); + ctrl.playFromMediaId(mediaId, null); + + MediaPlaybackListener mpl = new MediaPlaybackListener(mLooper, controller); + mpl.waitForPlayback( + (int playbackStatus) -> { + Log.i( + TAG, + "playItem: Media item playback returned, status: " + + playbackStatus); + disconnect(); + }); + }); } /** * Request the contents of a folder item identified by the given media ID * - * Contents must be loaded from a service and are returned asynchronously. + *

Contents must be loaded from a service and are returned asynchronously. * * @param mediaId A string indicating the piece of media you would like to play * @param cb A Callback that returns the loaded contents of the requested media ID @@ -244,18 +251,22 @@ class BrowsedPlayerWrapper { } if (cb == null) { - Log.wtf(TAG, "getFolderItems: Trying to connect to " + mPackageName - + "with null browse callback"); + Log.wtf( + TAG, + "getFolderItems: Trying to connect to " + + mPackageName + + "with null browse callback"); } Log.d(TAG, "getFolderItems: Connecting to browsable player: " + mPackageName); - return setCallbackAndConnect((int status, BrowsedPlayerWrapper wrapper) -> { - Log.i(TAG, "getFolderItems: Connected to browsable player: " + mPackageName); - if (status != STATUS_SUCCESS) { - cb.run(status, "", new ArrayList()); - } - getFolderItemsInternal(mediaId, cb); - }); + return setCallbackAndConnect( + (int status, BrowsedPlayerWrapper wrapper) -> { + Log.i(TAG, "getFolderItems: Connected to browsable player: " + mPackageName); + if (status != STATUS_SUCCESS) { + cb.run(status, "", new ArrayList()); + } + getFolderItemsInternal(mediaId, cb); + }); } // Internal function to call once the Browser is connected @@ -279,7 +290,6 @@ class BrowsedPlayerWrapper { executeCallback(STATUS_SUCCESS, BrowsedPlayerWrapper.this); } - @Override public void onConnectionFailed() { Log.w(TAG, "onConnectionFailed: Connection Failed with " + mPackageName); @@ -362,8 +372,8 @@ class BrowsedPlayerWrapper { Log.d(TAG, "MediaPlayback: Waiting for media to play for " + mPackageName); mTimeoutHandler = new TimeoutHandler(mLooper, mPlaybackCallback); mController.registerCallback(this, mTimeoutHandler); - mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT, - TimeoutHandler.CALLBACK_TIMEOUT_MS); + mTimeoutHandler.sendEmptyMessageDelayed( + TimeoutHandler.MSG_TIMEOUT, TimeoutHandler.CALLBACK_TIMEOUT_MS); } else { Log.d(TAG, "MediaPlayback: Media is already playing for " + mPackageName); mPlaybackCallback.run(STATUS_SUCCESS); @@ -412,8 +422,8 @@ class BrowsedPlayerWrapper { mBrowseCallback = cb; mLooper = looper; mTimeoutHandler = new TimeoutHandler(mLooper, cb, mediaId); - mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT, - TimeoutHandler.SUBSCRIPTION_TIMEOUT_MS); + mTimeoutHandler.sendEmptyMessageDelayed( + TimeoutHandler.MSG_TIMEOUT, TimeoutHandler.SUBSCRIPTION_TIMEOUT_MS); } @Override @@ -426,8 +436,11 @@ class BrowsedPlayerWrapper { Log.d(TAG, "onChildrenLoaded: mediaId=" + parentId + " size= " + children.size()); if (mBrowseCallback == null) { - Log.w(TAG, "onChildrenLoaded: " + mPackageName - + " children loaded while callback is null"); + Log.w( + TAG, + "onChildrenLoaded: " + + mPackageName + + " children loaded while callback is null"); } // TODO (apanicke): Instead of always unsubscribing, only unsubscribe from folders @@ -438,8 +451,13 @@ class BrowsedPlayerWrapper { ArrayList return_list = new ArrayList(); for (MediaItem item : children) { - Log.d(TAG, "onChildrenLoaded: Child=\"" + item.toString() - + "\", ID=\"" + item.getMediaId() + "\""); + Log.d( + TAG, + "onChildrenLoaded: Child=\"" + + item.toString() + + "\", ID=\"" + + item.getMediaId() + + "\""); if (item.isBrowsable()) { CharSequence titleCharSequence = item.getDescription().getTitle(); diff --git a/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java b/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java index efb58f56e64..33c680e7df1 100644 --- a/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java +++ b/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java @@ -23,8 +23,8 @@ import android.util.Log; /** * Google Play Music hides some of the metadata behind a specific key in the Extras of the - * MediaDescription in the MediaSession.QueueItem. This class exists to provide alternate - * methods to allow Google Play Music to match the default behaviour of MediaPlayerWrapper. + * MediaDescription in the MediaSession.QueueItem. This class exists to provide alternate methods to + * allow Google Play Music to match the default behaviour of MediaPlayerWrapper. */ class GPMWrapper extends MediaPlayerWrapper { private static final String TAG = "AvrcpGPMWrapper"; diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java index 8eacb678258..7b6b6bbd29d 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java @@ -52,16 +52,16 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * This class is directly responsible of maintaining the list of Browsable Players as well as - * the list of Addressable Players. This variation of the list doesn't actually list all the - * available players for a getAvailableMediaPlayers request. Instead it only reports one media - * player with ID=0 and all the other browsable players are folders in the root of that player. + * This class is directly responsible of maintaining the list of Browsable Players as well as the + * list of Addressable Players. This variation of the list doesn't actually list all the available + * players for a getAvailableMediaPlayers request. Instead it only reports one media player with + * ID=0 and all the other browsable players are folders in the root of that player. * - * Changing the directory to a browsable player will allow you to traverse that player as normal. + *

Changing the directory to a browsable player will allow you to traverse that player as normal. * By only having one root player, we never have to send Addressed Player Changed notifications, * UIDs Changed notifications, or Available Players Changed notifications. * - * TODO (apanicke): Add non-browsable players as song items to the root folder. Selecting that + *

TODO (apanicke): Add non-browsable players as song items to the root folder. Selecting that * player would effectively cause player switch by sending a play command to that player. */ public class MediaPlayerList { @@ -116,6 +116,7 @@ public class MediaPlayerList { public interface MediaUpdateCallback { void run(MediaData data); + void run(boolean availablePlayers, boolean addressedPlayers, boolean uids); } @@ -127,13 +128,9 @@ public class MediaPlayerList { void run(String parentId, List items); } - /** - * Listener for PlayerSettingsManager. - */ + /** Listener for PlayerSettingsManager. */ public interface MediaPlayerSettingsEventListener { - /** - * Called when the active player has changed. - */ + /** Called when the active player has changed. */ void onActivePlayerChanged(MediaPlayerWrapper player); } @@ -224,40 +221,52 @@ public class MediaPlayerList { intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); } List playerList = - mContext - .getApplicationContext() - .getPackageManager() - .queryIntentServices(intent, PackageManager.MATCH_ALL); - - mBrowsablePlayerConnector = BrowsablePlayerConnector.connectToPlayers(mContext, mLooper, - playerList, (List players) -> { - Log.i(TAG, "init: Browsable Player list size is " + players.size()); - - // Check to see if the list has been cleaned up before this completed - if (mMediaSessionManager == null) { - return; - } - - for (BrowsedPlayerWrapper wrapper : players) { - // Generate new id and add the browsable player - if (!havePlayerId(wrapper.getPackageName())) { - mMediaPlayerIds.put(wrapper.getPackageName(), getFreeMediaPlayerId()); - } - - d("Adding Browser Wrapper for " + wrapper.getPackageName() + " with id " - + mMediaPlayerIds.get(wrapper.getPackageName())); - - mBrowsablePlayers.put(mMediaPlayerIds.get(wrapper.getPackageName()), wrapper); - - wrapper.getFolderItems(wrapper.getRootId(), - (int status, String mediaId, List results) -> { - d("Got the contents for: " + mediaId + " : num results=" - + results.size()); - }); - } - - constructCurrentPlayers(); - }); + mContext.getApplicationContext() + .getPackageManager() + .queryIntentServices(intent, PackageManager.MATCH_ALL); + + mBrowsablePlayerConnector = + BrowsablePlayerConnector.connectToPlayers( + mContext, + mLooper, + playerList, + (List players) -> { + Log.i(TAG, "init: Browsable Player list size is " + players.size()); + + // Check to see if the list has been cleaned up before this completed + if (mMediaSessionManager == null) { + return; + } + + for (BrowsedPlayerWrapper wrapper : players) { + // Generate new id and add the browsable player + if (!havePlayerId(wrapper.getPackageName())) { + mMediaPlayerIds.put( + wrapper.getPackageName(), getFreeMediaPlayerId()); + } + + d( + "Adding Browser Wrapper for " + + wrapper.getPackageName() + + " with id " + + mMediaPlayerIds.get(wrapper.getPackageName())); + + mBrowsablePlayers.put( + mMediaPlayerIds.get(wrapper.getPackageName()), wrapper); + + wrapper.getFolderItems( + wrapper.getRootId(), + (int status, String mediaId, List results) -> { + d( + "Got the contents for: " + + mediaId + + " : num results=" + + results.size()); + }); + } + + constructCurrentPlayers(); + }); } public void cleanup() { @@ -340,16 +349,20 @@ public class MediaPlayerList { BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1); String itemId = wrapper.getRootId(); - wrapper.getFolderItems(itemId, (status, id, results) -> { - if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { - cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", 0); - return; - } - cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", results.size()); - }); + wrapper.getFolderItems( + itemId, + (status, id, results) -> { + if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { + cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", 0); + return; + } + cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", results.size()); + }); return; } - /** @} */ + /** + * @} + */ cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", mBrowsablePlayers.size()); } @@ -392,8 +405,10 @@ public class MediaPlayerList { if (state == null || state.getActiveQueueItemId() == MediaSession.QueueItem.UNKNOWN_ID || queue.size() == 0) { - d("getCurrentMediaId: No active queue item Id sending empty mediaId: PlaybackState=" - + state); + d( + "getCurrentMediaId: No active queue item Id sending empty mediaId:" + + " PlaybackState=" + + state); return ""; } @@ -427,10 +442,11 @@ public class MediaPlayerList { if (mAudioPlaybackIsActive && (state == null || state.getState() != PlaybackState.STATE_PLAYING)) { return new PlaybackState.Builder() - .setState(PlaybackState.STATE_PLAYING, - state == null ? 0 : state.getPosition(), - 1.0f) - .build(); + .setState( + PlaybackState.STATE_PLAYING, + state == null ? 0 : state.getPosition(), + 1.0f) + .build(); } return state; } @@ -484,8 +500,9 @@ public class MediaPlayerList { Matcher m = regex.matcher(mediaId); if (!m.find()) { // This should never happen since we control the media ID's reported - Log.wtf(TAG, "playNowPlayingItem: Couldn't match mediaId to pattern: mediaId=" - + mediaId); + Log.wtf( + TAG, + "playNowPlayingItem: Couldn't match mediaId to pattern: mediaId=" + mediaId); } long queueItemId = Long.parseLong(m.group(1)); @@ -521,8 +538,10 @@ public class MediaPlayerList { e("playFolderItem: Failed to start playback with an empty media id."); return; } - Log.i(TAG, "playFolderItem: Empty media id, trying with the root id for " - + wrapper.getPackageName()); + Log.i( + TAG, + "playFolderItem: Empty media id, trying with the root id for " + + wrapper.getPackageName()); } wrapper.playItem(itemId); } @@ -574,16 +593,20 @@ public class MediaPlayerList { itemId = wrapper.getRootId(); } - wrapper.getFolderItems(itemId, (status, id, results) -> { - if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { - cb.run(mediaId, new ArrayList()); - return; - } - cb.run(mediaId, results); - }); + wrapper.getFolderItems( + itemId, + (status, id, results) -> { + if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { + cb.run(mediaId, new ArrayList()); + return; + } + cb.run(mediaId, results); + }); return; } - /** @} */ + /** + * @} + */ // The device is requesting the content of the root folder. This folder contains a list of // Browsable Media Players displayed as folders with their contents contained within. @@ -605,27 +628,28 @@ public class MediaPlayerList { if (haveMediaBrowser(playerIndex)) { BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(playerIndex); if (itemId.equals("")) { - Log.i(TAG, "Empty media id, getting the root for " - + wrapper.getPackageName()); + Log.i(TAG, "Empty media id, getting the root for " + wrapper.getPackageName()); itemId = wrapper.getRootId(); } - wrapper.getFolderItems(itemId, (status, id, results) -> { - if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { - cb.run(mediaId, new ArrayList()); - return; - } + wrapper.getFolderItems( + itemId, + (status, id, results) -> { + if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { + cb.run(mediaId, new ArrayList()); + return; + } - String playerPrefix = String.format("%02d", playerIndex); - for (ListItem item : results) { - if (item.isFolder) { - item.folder.mediaId = playerPrefix.concat(item.folder.mediaId); - } else { - item.song.mediaId = playerPrefix.concat(item.song.mediaId); - } - } - cb.run(mediaId, results); - }); + String playerPrefix = String.format("%02d", playerIndex); + for (ListItem item : results) { + if (item.isFolder) { + item.folder.mediaId = playerPrefix.concat(item.folder.mediaId); + } else { + item.song.mediaId = playerPrefix.concat(item.song.mediaId); + } + } + cb.run(mediaId, results); + }); return; } else { cb.run(mediaId, new ArrayList()); @@ -669,13 +693,15 @@ public class MediaPlayerList { return playerId; } - MediaPlayerWrapper newPlayer = MediaPlayerWrapperFactory.wrap( - mContext, - controller, - mLooper); + MediaPlayerWrapper newPlayer = + MediaPlayerWrapperFactory.wrap(mContext, controller, mLooper); - Log.i(TAG, "Adding wrapped media player: " + packageName + " at key: " - + mMediaPlayerIds.get(controller.getPackageName())); + Log.i( + TAG, + "Adding wrapped media player: " + + packageName + + " at key: " + + mMediaPlayerIds.get(controller.getPackageName())); mMediaPlayers.put(playerId, newPlayer); return playerId; @@ -745,11 +771,7 @@ public class MediaPlayerList { mActivePlayerId = NO_ACTIVE_PLAYER; List queue = new ArrayList(); queue.add(Util.empty_data()); - MediaData newData = new MediaData( - Util.empty_data(), - null, - queue - ); + MediaData newData = new MediaData(Util.empty_data(), null, queue); sendMediaUpdate(newData); } @@ -785,8 +807,8 @@ public class MediaPlayerList { mActivePlayerId = playerId; getActivePlayer().registerCallback(mMediaPlayerCallback); - mActivePlayerLogger.logd(TAG, "setActivePlayer(): setting player to " - + getActivePlayer().getPackageName()); + mActivePlayerLogger.logd( + TAG, "setActivePlayer(): setting player to " + getActivePlayer().getPackageName()); if (mPlayerSettingsListener != null) { mPlayerSettingsListener.onActivePlayerChanged(getActivePlayer()); @@ -811,8 +833,8 @@ public class MediaPlayerList { } /** Informs AVRCP service that there has been an update in browsable players. */ - private void sendFolderUpdate(boolean availablePlayers, boolean addressedPlayers, - boolean uids) { + private void sendFolderUpdate( + boolean availablePlayers, boolean addressedPlayers, boolean uids) { d("sendFolderUpdate"); if (mCallback == null) { return; @@ -853,49 +875,55 @@ public class MediaPlayerList { *

See {@link #onMediaKeyEventSessionChanged}. */ @VisibleForTesting - final MediaSessionManager.OnActiveSessionsChangedListener - mActiveSessionsChangedListener = + final MediaSessionManager.OnActiveSessionsChangedListener mActiveSessionsChangedListener = new MediaSessionManager.OnActiveSessionsChangedListener() { - @Override - public void onActiveSessionsChanged( - List newControllers) { - synchronized (MediaPlayerList.this) { - Log.v(TAG, "onActiveSessionsChanged: number of controllers: " - + newControllers.size()); - if (newControllers.size() == 0) { - if (mPlayerSettingsListener != null) { - mPlayerSettingsListener.onActivePlayerChanged(null); - } - return; - } + @Override + public void onActiveSessionsChanged( + List newControllers) { + synchronized (MediaPlayerList.this) { + Log.v( + TAG, + "onActiveSessionsChanged: number of controllers: " + + newControllers.size()); + if (newControllers.size() == 0) { + if (mPlayerSettingsListener != null) { + mPlayerSettingsListener.onActivePlayerChanged(null); + } + return; + } - // Apps are allowed to have multiple MediaControllers. If an app does have - // multiple controllers then newControllers contains them in highest - // priority order. Since we only want to keep the highest priority one, - // we keep track of which controllers we updated and skip over ones - // we've already looked at. - HashSet addedPackages = new HashSet(); - - for (int i = 0; i < newControllers.size(); i++) { - if ((newControllers.get(i).getFlags() - & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { - Log.d(TAG, "onActiveSessionsChanged: controller: " - + newControllers.get(i).getPackageName() - + " ignored due to global priority flag"); - continue; - } - Log.d(TAG, "onActiveSessionsChanged: controller: " - + newControllers.get(i).getPackageName()); - if (addedPackages.contains(newControllers.get(i).getPackageName())) { - continue; + // Apps are allowed to have multiple MediaControllers. If an app does have + // multiple controllers then newControllers contains them in highest + // priority order. Since we only want to keep the highest priority one, + // we keep track of which controllers we updated and skip over ones + // we've already looked at. + HashSet addedPackages = new HashSet(); + + for (int i = 0; i < newControllers.size(); i++) { + if ((newControllers.get(i).getFlags() + & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) + != 0) { + Log.d( + TAG, + "onActiveSessionsChanged: controller: " + + newControllers.get(i).getPackageName() + + " ignored due to global priority flag"); + continue; + } + Log.d( + TAG, + "onActiveSessionsChanged: controller: " + + newControllers.get(i).getPackageName()); + if (addedPackages.contains(newControllers.get(i).getPackageName())) { + continue; + } + + addedPackages.add(newControllers.get(i).getPackageName()); + addMediaPlayer(newControllers.get(i)); + } } - - addedPackages.add(newControllers.get(i).getPackageName()); - addMediaPlayer(newControllers.get(i)); } - } - } - }; + }; /** * {@link android.content.BroadcastReceiver} to catch intents indicating package add, change and @@ -910,32 +938,33 @@ public class MediaPlayerList { *

See {@link #removeMediaPlayer} and {@link * #addMediaPlayer(android.media.session.MediaController)} */ - private final BroadcastReceiver mPackageChangedBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Log.v(TAG, "mPackageChangedBroadcastReceiver: action: " + action); - - if (action.equals(Intent.ACTION_PACKAGE_REMOVED) - || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) { - if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) return; - - String packageName = intent.getData().getSchemeSpecificPart(); - if (haveMediaPlayer(packageName)) { - removeMediaPlayer(mMediaPlayerIds.get(packageName)); - } - } else if (action.equals(Intent.ACTION_PACKAGE_ADDED) - || action.equals(Intent.ACTION_PACKAGE_CHANGED)) { - String packageName = intent.getData().getSchemeSpecificPart(); - if (packageName != null) { - Log.d(TAG, "Name of package changed: " + packageName); - // TODO (apanicke): Handle either updating or adding the new package. - // Check if its browsable and send the UIDS changed to update the - // root folder + private final BroadcastReceiver mPackageChangedBroadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.v(TAG, "mPackageChangedBroadcastReceiver: action: " + action); + + if (action.equals(Intent.ACTION_PACKAGE_REMOVED) + || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) { + if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) return; + + String packageName = intent.getData().getSchemeSpecificPart(); + if (haveMediaPlayer(packageName)) { + removeMediaPlayer(mMediaPlayerIds.get(packageName)); + } + } else if (action.equals(Intent.ACTION_PACKAGE_ADDED) + || action.equals(Intent.ACTION_PACKAGE_CHANGED)) { + String packageName = intent.getData().getSchemeSpecificPart(); + if (packageName != null) { + Log.d(TAG, "Name of package changed: " + packageName); + // TODO (apanicke): Handle either updating or adding the new package. + // Check if its browsable and send the UIDS changed to update the + // root folder + } + } } - } - } - }; + }; /** * Retrieves and sends the current {@link MediaData} of the active player (if present) to the @@ -948,35 +977,32 @@ public class MediaPlayerList { PlaybackState currState = null; if (getActivePlayer() == null) { Log.d(TAG, "updateMediaForAudioPlayback: no active player"); - PlaybackState.Builder builder = new PlaybackState.Builder() - .setState(PlaybackState.STATE_STOPPED, 0L, 0f); + PlaybackState.Builder builder = + new PlaybackState.Builder().setState(PlaybackState.STATE_STOPPED, 0L, 0f); List queue = new ArrayList(); queue.add(Util.empty_data()); - currMediaData = new MediaData( - Util.empty_data(), - builder.build(), - queue - ); + currMediaData = new MediaData(Util.empty_data(), builder.build(), queue); } else { currMediaData = getActivePlayer().getCurrentMediaData(); currState = currMediaData.state; } - if (currState != null - && currState.getState() == PlaybackState.STATE_PLAYING) { + if (currState != null && currState.getState() == PlaybackState.STATE_PLAYING) { Log.i(TAG, "updateMediaForAudioPlayback: Active player is playing, drop it"); return; } if (mAudioPlaybackIsActive) { - PlaybackState.Builder builder = new PlaybackState.Builder() - .setState(PlaybackState.STATE_PLAYING, - currState == null ? 0 : currState.getPosition(), - 1.0f); + PlaybackState.Builder builder = + new PlaybackState.Builder() + .setState( + PlaybackState.STATE_PLAYING, + currState == null ? 0 : currState.getPosition(), + 1.0f); currMediaData.state = builder.build(); } - mAudioPlaybackStateLogger.logd(TAG, "updateMediaForAudioPlayback: update state=" - + currMediaData.state); + mAudioPlaybackStateLogger.logd( + TAG, "updateMediaForAudioPlayback: update state=" + currMediaData.state); sendMediaUpdate(currMediaData); } @@ -1000,35 +1026,40 @@ public class MediaPlayerList { */ private final AudioManager.AudioPlaybackCallback mAudioPlaybackCallback = new AudioManager.AudioPlaybackCallback() { - @Override - public void onPlaybackConfigChanged(List configs) { - if (configs == null) { - return; - } - boolean isActive = false; - AudioPlaybackConfiguration activeConfig = null; - for (AudioPlaybackConfiguration config : configs) { - if (config.isActive() && (config.getAudioAttributes().getUsage() - == AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) - && (config.getAudioAttributes().getContentType() - == AudioAttributes.CONTENT_TYPE_SPEECH)) { - activeConfig = config; - isActive = true; - } - } - if (isActive != mAudioPlaybackIsActive) { - mAudioPlaybackStateLogger.logd(TAG, "onPlaybackConfigChanged: " - + (mAudioPlaybackIsActive ? "Active" : "Non-active") + " -> " - + (isActive ? "Active" : "Non-active")); - if (isActive) { - mAudioPlaybackStateLogger.logd(TAG, "onPlaybackConfigChanged: " - + "active config: " + activeConfig); + @Override + public void onPlaybackConfigChanged(List configs) { + if (configs == null) { + return; + } + boolean isActive = false; + AudioPlaybackConfiguration activeConfig = null; + for (AudioPlaybackConfiguration config : configs) { + if (config.isActive() + && (config.getAudioAttributes().getUsage() + == AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) + && (config.getAudioAttributes().getContentType() + == AudioAttributes.CONTENT_TYPE_SPEECH)) { + activeConfig = config; + isActive = true; + } + } + if (isActive != mAudioPlaybackIsActive) { + mAudioPlaybackStateLogger.logd( + TAG, + "onPlaybackConfigChanged: " + + (mAudioPlaybackIsActive ? "Active" : "Non-active") + + " -> " + + (isActive ? "Active" : "Non-active")); + if (isActive) { + mAudioPlaybackStateLogger.logd( + TAG, + "onPlaybackConfigChanged: " + "active config: " + activeConfig); + } + mAudioPlaybackIsActive = isActive; + updateMediaForAudioPlayback(); + } } - mAudioPlaybackIsActive = isActive; - updateMediaForAudioPlayback(); - } - } - }; + }; /** * Callback from {@link MediaPlayerWrapper}. @@ -1040,33 +1071,34 @@ public class MediaPlayerList { */ private final MediaPlayerWrapper.Callback mMediaPlayerCallback = new MediaPlayerWrapper.Callback() { - @Override - public void mediaUpdatedCallback(MediaData data) { - if (data.metadata == null) { - Log.d(TAG, "mediaUpdatedCallback(): metadata is null"); - return; - } + @Override + public void mediaUpdatedCallback(MediaData data) { + if (data.metadata == null) { + Log.d(TAG, "mediaUpdatedCallback(): metadata is null"); + return; + } - if (data.state == null) { - Log.w(TAG, "mediaUpdatedCallback(): Tried to update with null state"); - return; - } + if (data.state == null) { + Log.w(TAG, "mediaUpdatedCallback(): Tried to update with null state"); + return; + } - if (mAudioPlaybackIsActive && (data.state.getState() != PlaybackState.STATE_PLAYING)) { - Log.d(TAG, "Some audio playbacks are still active, drop it"); - return; - } - sendMediaUpdate(data); - } + if (mAudioPlaybackIsActive + && (data.state.getState() != PlaybackState.STATE_PLAYING)) { + Log.d(TAG, "Some audio playbacks are still active, drop it"); + return; + } + sendMediaUpdate(data); + } - @Override - public void sessionUpdatedCallback(String packageName) { - if (haveMediaPlayer(packageName)) { - Log.d(TAG, "sessionUpdatedCallback(): packageName: " + packageName); - removeMediaPlayer(mMediaPlayerIds.get(packageName)); - } - } - }; + @Override + public void sessionUpdatedCallback(String packageName) { + if (haveMediaPlayer(packageName)) { + Log.d(TAG, "sessionUpdatedCallback(): packageName: " + packageName); + removeMediaPlayer(mMediaPlayerIds.get(packageName)); + } + } + }; /** * Listens for Media key events session changes. @@ -1086,51 +1118,68 @@ public class MediaPlayerList { @VisibleForTesting final MediaSessionManager.OnMediaKeyEventSessionChangedListener mMediaKeyEventSessionChangedListener = - new MediaSessionManager.OnMediaKeyEventSessionChangedListener() { - @Override - public void onMediaKeyEventSessionChanged(String packageName, - MediaSession.Token token) { - if (mMediaSessionManager == null) { - Log.w(TAG, "onMediaKeyEventSessionChanged(): Unexpected callback " - + "from the MediaSessionManager, pkg" + packageName); - return; - } - if (TextUtils.isEmpty(packageName)) { - return; - } - if (token != null) { - android.media.session.MediaController controller = - new android.media.session.MediaController(mContext, token); - if ((controller.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) - != 0) { - // Skip adding controller for GLOBAL_PRIORITY session. - Log.i(TAG, "onMediaKeyEventSessionChanged," - + " ignoring global priority session"); - return; - } - if (!haveMediaPlayer(controller.getPackageName())) { - // Since we have a controller, we can try to to recover by adding the - // player and then setting it as active. - Log.w(TAG, "onMediaKeyEventSessionChanged(Token): Addressed Player " - + "changed to a player we didn't have a session for"); - addMediaPlayer(controller); - } - - Log.i(TAG, "onMediaKeyEventSessionChanged: token=" - + controller.getPackageName()); - setActivePlayer(mMediaPlayerIds.get(controller.getPackageName())); - } else { - if (!haveMediaPlayer(packageName)) { - e("onMediaKeyEventSessionChanged(PackageName): Media key event session " - + "changed to a player we don't have a session for"); - return; + new MediaSessionManager.OnMediaKeyEventSessionChangedListener() { + @Override + public void onMediaKeyEventSessionChanged( + String packageName, MediaSession.Token token) { + if (mMediaSessionManager == null) { + Log.w( + TAG, + "onMediaKeyEventSessionChanged(): Unexpected callback " + + "from the MediaSessionManager, pkg" + + packageName); + return; + } + if (TextUtils.isEmpty(packageName)) { + return; + } + if (token != null) { + android.media.session.MediaController controller = + new android.media.session.MediaController(mContext, token); + if ((controller.getFlags() + & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) + != 0) { + // Skip adding controller for GLOBAL_PRIORITY session. + Log.i( + TAG, + "onMediaKeyEventSessionChanged," + + " ignoring global priority session"); + return; + } + if (!haveMediaPlayer(controller.getPackageName())) { + // Since we have a controller, we can try to to recover by + // adding the + // player and then setting it as active. + Log.w( + TAG, + "onMediaKeyEventSessionChanged(Token): Addressed Player" + + " changed to a player we didn't have a session" + + " for"); + addMediaPlayer(controller); + } + + Log.i( + TAG, + "onMediaKeyEventSessionChanged: token=" + + controller.getPackageName()); + setActivePlayer(mMediaPlayerIds.get(controller.getPackageName())); + } else { + if (!haveMediaPlayer(packageName)) { + e( + "onMediaKeyEventSessionChanged(PackageName): Media key" + + " event session changed to a player we don't have" + + " a session for"); + return; + } + + Log.i( + TAG, + "onMediaKeyEventSessionChanged: packageName=" + + packageName); + setActivePlayer(mMediaPlayerIds.get(packageName)); + } } - - Log.i(TAG, "onMediaKeyEventSessionChanged: packageName=" + packageName); - setActivePlayer(mMediaPlayerIds.get(packageName)); - } - } - }; + }; /** Dumps all players and browsable players currently listed in this class. */ public void dump(StringBuilder sb) { diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java index 2dd965d64e2..ae0afdeb012 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java @@ -57,11 +57,13 @@ public class MediaPlayerWrapper { @GuardedBy("mCallbackLock") private MediaControllerListener mControllerCallbacks = null; + private final Object mCallbackLock = new Object(); private Callback mRegisteredCallback = null; public interface Callback { void mediaUpdatedCallback(MediaData data); + void sessionUpdatedCallback(String packageName); } @@ -163,18 +165,17 @@ public class MediaPlayerWrapper { // We don't return the cached info here in order to always provide the freshest data. MediaData getCurrentMediaData() { - MediaData data = new MediaData( - getCurrentMetadata(), - getPlaybackState(), - getCurrentQueue()); + MediaData data = new MediaData(getCurrentMetadata(), getPlaybackState(), getCurrentQueue()); return data; } void playItemFromQueue(long qid) { // Return immediately if no queue exists. if (getQueue() == null) { - Log.w(TAG, "playItemFromQueue: Trying to play item for player that has no queue: " - + mPackageName); + Log.w( + TAG, + "playItemFromQueue: Trying to play item for player that has no queue: " + + mPackageName); return; } @@ -253,9 +254,7 @@ public class MediaPlayerWrapper { return; } - /** - * Return whether the queue, metadata, and queueID are all in sync. - */ + /** Return whether the queue, metadata, and queueID are all in sync. */ boolean isMetadataSynced() { List queue = getQueue(); if (queue != null && getActiveQueueID() != -1) { @@ -293,8 +292,8 @@ public class MediaPlayerWrapper { } /** - * Register a callback which gets called when media updates happen. The callbacks are - * called on the same Looper that was passed in to create this object. + * Register a callback which gets called when media updates happen. The callbacks are called on + * the same Looper that was passed in to create this object. */ void registerCallback(Callback callback) { if (callback == null) { @@ -308,19 +307,18 @@ public class MediaPlayerWrapper { // Update the current data since it could have changed while we weren't registered for // updates - mCurrentData = new MediaData( - Util.toMetadata(mContext, getMetadata()), - getPlaybackState(), - Util.toMetadataList(mContext, getQueue())); + mCurrentData = + new MediaData( + Util.toMetadata(mContext, getMetadata()), + getPlaybackState(), + Util.toMetadataList(mContext, getQueue())); synchronized (mCallbackLock) { mControllerCallbacks = new MediaControllerListener(mMediaController, mLooper); } } - /** - * Unregisters from updates. Note, this doesn't require the looper to be shut down. - */ + /** Unregisters from updates. Note, this doesn't require the looper to be shut down. */ void unregisterCallback() { // Prevent a race condition where a callback could be called while shutting down synchronized (mCallbackLock) { @@ -346,10 +344,11 @@ public class MediaPlayerWrapper { // Update the current data since it could be different on the new controller for the // player - mCurrentData = new MediaData( - Util.toMetadata(mContext, getMetadata()), - getPlaybackState(), - Util.toMetadataList(mContext, getQueue())); + mCurrentData = + new MediaData( + Util.toMetadata(mContext, getMetadata()), + getPlaybackState(), + Util.toMetadataList(mContext, getQueue())); mControllerCallbacks = new MediaControllerListener(mMediaController, mLooper); } @@ -357,10 +356,11 @@ public class MediaPlayerWrapper { } private void sendMediaUpdate() { - MediaData newData = new MediaData( - Util.toMetadata(mContext, getMetadata()), - getPlaybackState(), - Util.toMetadataList(mContext, getQueue())); + MediaData newData = + new MediaData( + Util.toMetadata(mContext, getMetadata()), + getPlaybackState(), + Util.toMetadataList(mContext, getQueue())); if (newData.equals(mCurrentData)) { // This may happen if the controller is fully synced by the time the @@ -371,8 +371,7 @@ public class MediaPlayerWrapper { synchronized (mCallbackLock) { if (mRegisteredCallback == null) { - Log.e(TAG, mPackageName - + ": Trying to send an update with no registered callback"); + Log.e(TAG, mPackageName + ": Trying to send an update with no registered callback"); return; } @@ -399,7 +398,7 @@ public class MediaPlayerWrapper { } Log.e(TAG, "Timeout while waiting for metadata to sync for " + mPackageName); - Log.e(TAG, " └ Current Metadata: " + Util.toMetadata(mContext, getMetadata())); + Log.e(TAG, " └ Current Metadata: " + Util.toMetadata(mContext, getMetadata())); Log.e(TAG, " └ Current Playstate: " + getPlaybackState()); List current_queue = Util.toMetadataList(mContext, getQueue()); for (int i = 0; i < current_queue.size(); i++) { @@ -446,8 +445,8 @@ public class MediaPlayerWrapper { if (!isMetadataSynced()) { d("trySendMediaUpdate(): Starting media update timeout"); - mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT, - TimeoutHandler.CALLBACK_TIMEOUT_MS); + mTimeoutHandler.sendEmptyMessageDelayed( + TimeoutHandler.MSG_TIMEOUT, TimeoutHandler.CALLBACK_TIMEOUT_MS); return; } } @@ -466,8 +465,12 @@ public class MediaPlayerWrapper { return; } - Log.v(TAG, "onMetadataChanged(): " + mPackageName + " : " - + Util.toMetadata(mContext, mediaMetadata)); + Log.v( + TAG, + "onMetadataChanged(): " + + mPackageName + + " : " + + Util.toMetadata(mContext, mediaMetadata)); if (!Objects.equals(mediaMetadata, getMetadata())) { e("The callback metadata doesn't match controller metadata"); @@ -482,8 +485,11 @@ public class MediaPlayerWrapper { // twice in a row with the only difference being that the song duration is rounded to // the nearest second. if (Objects.equals(Util.toMetadata(mContext, mediaMetadata), mCurrentData.metadata)) { - Log.w(TAG, "onMetadataChanged(): " + mPackageName - + " tried to update with no new data"); + Log.w( + TAG, + "onMetadataChanged(): " + + mPackageName + + " tried to update with no new data"); return; } @@ -509,8 +515,11 @@ public class MediaPlayerWrapper { } if (playstateEquals(state, mCurrentData.state)) { - Log.w(TAG, "onPlaybackStateChanged(): " + mPackageName - + " tried to update with no new data"); + Log.w( + TAG, + "onPlaybackStateChanged(): " + + mPackageName + + " tried to update with no new data"); return; } @@ -526,8 +535,7 @@ public class MediaPlayerWrapper { @Override public void onQueueChanged(@Nullable List queue) { if (!isPlaybackStateReady() || !isMetadataReady()) { - Log.v(TAG, "onQueueChanged(): " + mPackageName - + " tried to update with no queue"); + Log.v(TAG, "onQueueChanged(): " + mPackageName + " tried to update with no queue"); return; } @@ -539,8 +547,9 @@ public class MediaPlayerWrapper { List current_queue = Util.toMetadataList(mContext, queue); if (current_queue.equals(mCurrentData.queue)) { - Log.w(TAG, "onQueueChanged(): " + mPackageName - + " tried to update with no new data"); + Log.w( + TAG, + "onQueueChanged(): " + mPackageName + " tried to update with no new data"); return; } @@ -572,14 +581,16 @@ public class MediaPlayerWrapper { * certain amount of deviation between the position fields of the PlaybackStates. This is to * prevent matches from failing when updates happen in quick succession. * - * The maximum allowed deviation is defined by PLAYSTATE_BOUNCE_IGNORE_PERIOD and is measured + *

The maximum allowed deviation is defined by PLAYSTATE_BOUNCE_IGNORE_PERIOD and is measured * in milliseconds. */ private static final long PLAYSTATE_BOUNCE_IGNORE_PERIOD = 500; + public static boolean playstateEquals(PlaybackState a, PlaybackState b) { if (a == b) return true; - if (a != null && b != null + if (a != null + && b != null && a.getState() == b.getState() && a.getActiveQueueItemId() == b.getActiveQueueItemId() && Math.abs(a.getPosition() - b.getPosition()) < PLAYSTATE_BOUNCE_IGNORE_PERIOD) { diff --git a/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java b/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java index 1da13649bc8..43733ec15ed 100644 --- a/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java +++ b/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java @@ -23,9 +23,7 @@ import android.util.Log; import com.android.bluetooth.avrcp.AvrcpTargetService; -/** - * Manager class for player apps. - */ +/** Manager class for player apps. */ public class PlayerSettingsManager { private static final String TAG = PlayerSettingsManager.class.getSimpleName(); @@ -49,8 +47,10 @@ public class PlayerSettingsManager { MediaPlayerWrapper wrapper = mMediaPlayerList.getActivePlayer(); if (wrapper != null) { - mActivePlayerController = new MediaControllerCompat(mService, - MediaSessionCompat.Token.fromToken(wrapper.getSessionToken())); + mActivePlayerController = + new MediaControllerCompat( + mService, + MediaSessionCompat.Token.fromToken(wrapper.getSessionToken())); if (!registerMediaControllerCallback(mActivePlayerController, mControllerCallback)) { mActivePlayerController = null; } @@ -59,9 +59,7 @@ public class PlayerSettingsManager { } } - /** - * Unregister callbacks - */ + /** Unregister callbacks */ public void cleanup() { updateRemoteDevice(); if (mActivePlayerController != null) { @@ -69,16 +67,17 @@ public class PlayerSettingsManager { } } - /** - * Updates the active player controller. - */ + /** Updates the active player controller. */ private void activePlayerChanged(MediaPlayerWrapper mediaPlayerWrapper) { if (mActivePlayerController != null) { unregisterMediaControllerCallback(mActivePlayerController, mControllerCallback); } if (mediaPlayerWrapper != null) { - mActivePlayerController = new MediaControllerCompat(mService, - MediaSessionCompat.Token.fromToken(mediaPlayerWrapper.getSessionToken())); + mActivePlayerController = + new MediaControllerCompat( + mService, + MediaSessionCompat.Token.fromToken( + mediaPlayerWrapper.getSessionToken())); if (!registerMediaControllerCallback(mActivePlayerController, mControllerCallback)) { mActivePlayerController = null; updateRemoteDevice(); @@ -92,12 +91,9 @@ public class PlayerSettingsManager { /** * Sends the MediaController values of the active player to the remote device. * - * This is called when: - * - The class is created and the session is ready - * - The class is destroyed - * - The active player changed and the session is ready - * - The last active player has been removed - * - The repeat / shuffle player state changed + *

This is called when: - The class is created and the session is ready - The class is + * destroyed - The active player changed and the session is ready - The last active player has + * been removed - The repeat / shuffle player state changed */ private void updateRemoteDevice() { int repeatMode = getPlayerRepeatMode(); @@ -111,9 +107,7 @@ public class PlayerSettingsManager { mService.sendPlayerSettings(repeatMode, shuffleMode); } - /** - * Called from remote device to set the active player repeat mode. - */ + /** Called from remote device to set the active player repeat mode. */ public boolean setPlayerRepeatMode(int repeatMode) { if (mActivePlayerController == null) { return false; @@ -144,9 +138,7 @@ public class PlayerSettingsManager { } } - /** - * Called from remote device to set the active player shuffle mode. - */ + /** Called from remote device to set the active player shuffle mode. */ public boolean setPlayerShuffleMode(int shuffleMode) { if (mActivePlayerController == null) { Log.i(TAG, "setPlayerShuffleMode: no active player"); @@ -283,58 +275,36 @@ public class PlayerSettingsManager { } } - /** - * Class containing all the Shuffle/Repeat values as defined in the BT spec. - */ + /** Class containing all the Shuffle/Repeat values as defined in the BT spec. */ public static final class PlayerSettingsValues { - /** - * Repeat setting, as defined by Bluetooth specification. - */ + /** Repeat setting, as defined by Bluetooth specification. */ public static final int SETTING_REPEAT = 2; - /** - * Shuffle setting, as defined by Bluetooth specification. - */ + /** Shuffle setting, as defined by Bluetooth specification. */ public static final int SETTING_SHUFFLE = 3; - /** - * Repeat OFF state, as defined by Bluetooth specification. - */ + /** Repeat OFF state, as defined by Bluetooth specification. */ public static final int STATE_REPEAT_OFF = 1; - /** - * Single track repeat, as defined by Bluetooth specification. - */ + /** Single track repeat, as defined by Bluetooth specification. */ public static final int STATE_REPEAT_SINGLE_TRACK = 2; - /** - * All track repeat, as defined by Bluetooth specification. - */ + /** All track repeat, as defined by Bluetooth specification. */ public static final int STATE_REPEAT_ALL_TRACK = 3; - /** - * Group repeat, as defined by Bluetooth specification. - */ + /** Group repeat, as defined by Bluetooth specification. */ public static final int STATE_REPEAT_GROUP = 4; - /** - * Shuffle OFF state, as defined by Bluetooth specification. - */ + /** Shuffle OFF state, as defined by Bluetooth specification. */ public static final int STATE_SHUFFLE_OFF = 1; - /** - * All track shuffle, as defined by Bluetooth specification. - */ + /** All track shuffle, as defined by Bluetooth specification. */ public static final int STATE_SHUFFLE_ALL_TRACK = 2; - /** - * Group shuffle, as defined by Bluetooth specification. - */ + /** Group shuffle, as defined by Bluetooth specification. */ public static final int STATE_SHUFFLE_GROUP = 3; - /** - * Default state off. - */ + /** Default state off. */ public static final int STATE_DEFAULT_OFF = 1; } diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java index 1b53eec2367..fc106e9a956 100644 --- a/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java +++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java @@ -30,7 +30,7 @@ import java.io.InputStream; /** * An object to represent an image from the Media Framework * - * This object abstracts away the method used to get the bitmap and provides a way for us to + *

This object abstracts away the method used to get the bitmap and provides a way for us to * determine image equality in an application/folder/item agnostic way. */ public class Image { @@ -49,9 +49,7 @@ public class Image { // solution has picked for this image and pass this object on directly. private String mImageHandle = null; - /** - * Create an Image object from a MediaMetadata object - */ + /** Create an Image object from a MediaMetadata object */ public Image(Context context, MediaMetadata metadata) { mContext = context; @@ -83,9 +81,7 @@ public class Image { } } - /** - * Create an image out of a bundle of MediaMetadata keyed values - */ + /** Create an image out of a bundle of MediaMetadata keyed values */ public Image(Context context, Bundle bundle) { mContext = context; @@ -117,9 +113,7 @@ public class Image { } } - /** - * Create an Image object from a MediaDescription object - */ + /** Create an Image object from a MediaDescription object */ public Image(Context context, MediaDescription desc) { mContext = context; Uri uri = desc.getIconUri(); @@ -131,34 +125,26 @@ public class Image { } } - /** - * Create an Image object from a raw image uri - */ + /** Create an Image object from a raw image uri */ public Image(Context context, Uri uri) { mContext = context; setImage(uri); } - /** - * Create an Image object from a raw image - */ + /** Create an Image object from a raw image */ public Image(Context context, Bitmap image) { mContext = context; setImage(image); } - /** - * Set the image by resolving a URI to a bitmap - */ + /** Set the image by resolving a URI to a bitmap */ private void setImage(String uriString) { if (uriString == null) return; Uri uri = Uri.parse(uriString); setImage(uri); } - /** - * Set the image by resolving a URI to a bitmap - */ + /** Set the image by resolving a URI to a bitmap */ private void setImage(Uri uri) { if (uri == null) return; Bitmap image = getImageFromUri(uri); @@ -167,18 +153,14 @@ public class Image { setSource(SOURCE_URI); } - /** - * Set the image directly from a bitmap - */ + /** Set the image directly from a bitmap */ private void setImage(Bitmap image) { if (image == null) return; mImage = image; setSource(SOURCE_BITMAP); } - /** - * Get the bitmap associated with this Image - */ + /** Get the bitmap associated with this Image */ public Bitmap getImage() { return mImage; } @@ -186,7 +168,7 @@ public class Image { /** * Get an image Bitmap from a Uri * - * Used to convert Uris into the images they represent + *

Used to convert Uris into the images they represent * * @param uri A Uri pointing to an image * @return A Bitmap object representing the image at the given Uri @@ -216,7 +198,7 @@ public class Image { /** * Get the source of the image, if known * - * Images currently come from either raw bitmaps or a URI that points to a ContentProvider. + *

Images currently come from either raw bitmaps or a URI that points to a ContentProvider. * This allows us to set where it came from, largely used for debug purposes. */ public int getSource() { @@ -226,30 +208,24 @@ public class Image { /** * Set the source of the image. * - * Images currently come from either raw bitmaps or a URI that points to a ContentProvider. + *

Images currently come from either raw bitmaps or a URI that points to a ContentProvider. * This allows us to set where it came from, largely used for debug purposes. */ private void setSource(int source) { mSource = source; } - /** - * Assign a handle value from your storage solution to this image - */ + /** Assign a handle value from your storage solution to this image */ public void setImageHandle(String handle) { mImageHandle = handle; } - /** - * Get the handle value associated with this image from your storage situation - */ + /** Get the handle value associated with this image from your storage situation */ public String getImageHandle() { return mImageHandle; } - /** - * Determine if two image objects are the same. - */ + /** Determine if two image objects are the same. */ public static boolean sameAs(Image l, Image r) { if (l == null && r == null) return true; if (l == null || r == null) return false; @@ -258,9 +234,7 @@ public class Image { return bmp.sameAs(r.getImage()); } - /** - * Get a string representation of the image and its metadata - */ + /** Get a string representation of the image and its metadata */ @Override public String toString() { return ""; diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java index fb3b25ca2e7..d894ae82885 100644 --- a/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java +++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java @@ -93,14 +93,26 @@ public class Metadata implements Cloneable { @Override public String toString() { - return "{ mediaId=\"" + mediaId + "\" title=\"" + title + "\" artist=\"" + artist - + "\" album=\"" + album + "\" duration=" + duration - + " trackPosition=" + trackNum + "/" + numTracks + " image=" + image + " }"; + return "{ mediaId=\"" + + mediaId + + "\" title=\"" + + title + + "\" artist=\"" + + artist + + "\" album=\"" + + album + + "\" duration=" + + duration + + " trackPosition=" + + trackNum + + "/" + + numTracks + + " image=" + + image + + " }"; } - /** - * Replaces default values by {@code filledMetadata} non default values. - */ + /** Replaces default values by {@code filledMetadata} non default values. */ public void replaceDefaults(Metadata filledMetadata) { if (filledMetadata == null) { return; @@ -137,32 +149,24 @@ public class Metadata implements Cloneable { } } - /** - * A Builder object to populate a Metadata from various different Media Framework objects - */ + /** A Builder object to populate a Metadata from various different Media Framework objects */ public static class Builder { private Metadata mMetadata = new Metadata(); private Context mContext = null; - /** - * Set the Media ID fot the Metadata Object - */ + /** Set the Media ID fot the Metadata Object */ public Builder setMediaId(String id) { mMetadata.mediaId = id; return this; } - /** - * Set the context this builder should use when resolving images - */ + /** Set the context this builder should use when resolving images */ public Builder useContext(Context context) { mContext = context; return this; } - /** - * Extract the fields from a MediaMetadata object into a Metadata, if they exist - */ + /** Extract the fields from a MediaMetadata object into a Metadata, if they exist */ public Builder fromMediaMetadata(MediaMetadata data) { if (data == null) return this; @@ -194,10 +198,12 @@ public class Metadata implements Cloneable { if (data.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { mMetadata.duration = "" + data.getLong(MediaMetadata.METADATA_KEY_DURATION); } - if ((mContext != null && Util.areUriImagesSupported(mContext) - && (data.containsKey(MediaMetadata.METADATA_KEY_ART_URI) - || data.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI) - || data.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI))) + if ((mContext != null + && Util.areUriImagesSupported(mContext) + && (data.containsKey(MediaMetadata.METADATA_KEY_ART_URI) + || data.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI) + || data.containsKey( + MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI))) || data.containsKey(MediaMetadata.METADATA_KEY_ART) || data.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART) || data.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON)) { @@ -206,17 +212,13 @@ public class Metadata implements Cloneable { return this; } - /** - * Extract the fields from a MediaItem object into a Metadata, if they exist - */ + /** Extract the fields from a MediaItem object into a Metadata, if they exist */ public Builder fromMediaItem(MediaItem item) { if (item == null) return this; return fromMediaDescription(item.getDescription()).setMediaId(item.getMediaId()); } - /** - * Extract the fields from a MediaDescription object into a Metadata, if they exist - */ + /** Extract the fields from a MediaDescription object into a Metadata, if they exist */ public Builder fromMediaDescription(MediaDescription desc) { if (desc == null) return this; @@ -228,7 +230,8 @@ public class Metadata implements Cloneable { // Check for artwork if (desc.getIconBitmap() != null) { mMetadata.image = new Image(mContext, desc.getIconBitmap()); - } else if (mContext != null && Util.areUriImagesSupported(mContext) + } else if (mContext != null + && Util.areUriImagesSupported(mContext) && desc.getIconUri() != null) { mMetadata.image = new Image(mContext, desc.getIconUri()); } @@ -275,10 +278,12 @@ public class Metadata implements Cloneable { if (bundle.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { mMetadata.duration = "" + bundle.getLong(MediaMetadata.METADATA_KEY_DURATION); } - if ((mContext != null && Util.areUriImagesSupported(mContext) - && (bundle.containsKey(MediaMetadata.METADATA_KEY_ART_URI) - || bundle.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI) - || bundle.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI))) + if ((mContext != null + && Util.areUriImagesSupported(mContext) + && (bundle.containsKey(MediaMetadata.METADATA_KEY_ART_URI) + || bundle.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI) + || bundle.containsKey( + MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI))) || bundle.containsKey(MediaMetadata.METADATA_KEY_ART) || bundle.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART) || bundle.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON)) { @@ -287,17 +292,14 @@ public class Metadata implements Cloneable { return this; } - /** - * Elect to use default values in the Metadata in place of any missing values - */ + /** Elect to use default values in the Metadata in place of any missing values */ public Builder useDefaults() { if (mMetadata.mediaId == null) { mMetadata.mediaId = EMPTY_MEDIA_ID; } if (mMetadata.title == null) { mMetadata.title = - mContext != null ? mContext.getString(R.string.not_provided) - : EMPTY_TITLE; + mContext != null ? mContext.getString(R.string.not_provided) : EMPTY_TITLE; } if (mMetadata.artist == null) mMetadata.artist = EMPTY_ARTIST; if (mMetadata.album == null) mMetadata.album = EMPTY_ALBUM; @@ -309,9 +311,7 @@ public class Metadata implements Cloneable { return this; } - /** - * Get the final Metadata objects you're building - */ + /** Get the final Metadata objects you're building */ public Metadata build() { return mMetadata.clone(); } diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java index 75a760bb55f..adca4be6a9a 100644 --- a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java +++ b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java @@ -18,9 +18,7 @@ package com.android.bluetooth.audio_util; import android.media.session.PlaybackState; -/** - * Carries the playback status information in a custom object. - */ +/** Carries the playback status information in a custom object. */ // TODO(apanicke): Send the current active song ID along with this object so that all information // is carried by our custom types. public class PlayStatus { diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java index a653e96cc85..ada64292f71 100644 --- a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java +++ b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java @@ -16,9 +16,7 @@ package com.android.bluetooth.audio_util; -/** - * Carries Media Player Information - */ +/** Carries Media Player Information */ public class PlayerInfo { public int id; public String name; diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java index efe155f7f0c..32597edc75e 100644 --- a/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java +++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java @@ -34,17 +34,13 @@ class Util { // TODO (apanicke): Remove this prefix later, for now it makes debugging easier. public static final String NOW_PLAYING_PREFIX = "NowPlayingId"; - /** - * Get an empty set of Metadata - */ + /** Get an empty set of Metadata */ public static final Metadata empty_data() { Metadata.Builder builder = new Metadata.Builder(); return builder.useDefaults().build(); } - /** - * Determine if a set of Metadata is "empty" as defined by audio_util. - */ + /** Determine if a set of Metadata is "empty" as defined by audio_util. */ public static final boolean isEmptyData(Metadata data) { if (data == null) return true; // Note: We need both equals() and an explicit media id check because equals() does @@ -55,16 +51,14 @@ class Util { /** * Get whether or not Bluetooth is configured to support URI images or not. * - * Note that creating URI images will dramatically increase memory usage. + *

Note that creating URI images will dramatically increase memory usage. */ public static boolean areUriImagesSupported(Context context) { if (context == null) return false; return context.getResources().getBoolean(R.bool.avrcp_target_cover_art_uri_images); } - /** - * Translate a MediaItem to audio_util's Metadata - */ + /** Translate a MediaItem to audio_util's Metadata */ public static Metadata toMetadata(Context context, MediaItem item) { Metadata.Builder builder = new Metadata.Builder(); try { @@ -75,9 +69,7 @@ class Util { } } - /** - * Translate a MediaSession.QueueItem to audio_util's Metadata - */ + /** Translate a MediaSession.QueueItem to audio_util's Metadata */ public static Metadata toMetadata(Context context, MediaSession.QueueItem item) { Metadata.Builder builder = new Metadata.Builder(); @@ -95,28 +87,27 @@ class Util { return builder.build(); } - /** - * Translate a MediaMetadata to audio_util's Metadata - */ + /** Translate a MediaMetadata to audio_util's Metadata */ public static Metadata toMetadata(Context context, MediaMetadata data) { Metadata.Builder builder = new Metadata.Builder(); // This will always be currsong. The AVRCP service will overwrite the mediaId if it needs to // TODO (apanicke): Remove when the service is ready, right now it makes debugging much more // convenient try { - return builder.useContext(context).useDefaults().fromMediaMetadata(data) - .setMediaId("currsong").build(); + return builder.useContext(context) + .useDefaults() + .fromMediaMetadata(data) + .setMediaId("currsong") + .build(); } catch (Exception e) { Log.e(TAG, "Failed to build Metadata from MediaMetadata, returning empty data", e); return empty_data(); } } - /** - * Translate a list of MediaSession.QueueItem to a list of audio_util's Metadata - */ - public static List toMetadataList(Context context, - List items) { + /** Translate a list of MediaSession.QueueItem to a list of audio_util's Metadata */ + public static List toMetadataList( + Context context, List items) { ArrayList list = new ArrayList<>(); if (items == null) return list; diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java index 6dc617af69a..30d23b65577 100644 --- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java +++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java @@ -26,134 +26,103 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; /** - * Provide a mockable interface in order to test classes that use MediaBrowser. - * We need this class due to the fact that the MediaController class is marked as final and - * there is no way to currently mock final classes in Android. Once this is possible this class - * can be deleted. + * Provide a mockable interface in order to test classes that use MediaBrowser. We need this class + * due to the fact that the MediaController class is marked as final and there is no way to + * currently mock final classes in Android. Once this is possible this class can be deleted. */ public class MediaBrowser { android.media.browse.MediaBrowser mDelegate; - /** - * Wrap a real MediaBrowser object - */ + /** Wrap a real MediaBrowser object */ public MediaBrowser(android.media.browse.MediaBrowser delegate) { mDelegate = delegate; } - /** - * Create a real MediaBrowser object and wrap it - */ - public MediaBrowser(Context context, ComponentName serviceComponent, - ConnectionCallback callback, Bundle rootHints) { - mDelegate = new android.media.browse.MediaBrowser(context, serviceComponent, callback, - rootHints); + /** Create a real MediaBrowser object and wrap it */ + public MediaBrowser( + Context context, + ComponentName serviceComponent, + ConnectionCallback callback, + Bundle rootHints) { + mDelegate = + new android.media.browse.MediaBrowser( + context, serviceComponent, callback, rootHints); } - /** - * Wrapper for MediaBrowser.ConnectionCallback - */ - public abstract static class ConnectionCallback extends - android.media.browse.MediaBrowser.ConnectionCallback {} + /** Wrapper for MediaBrowser.ConnectionCallback */ + public abstract static class ConnectionCallback + extends android.media.browse.MediaBrowser.ConnectionCallback {} - /** - * Wrapper for MediaBrowser.ItemCallback - */ - public abstract static class ItemCallback extends - android.media.browse.MediaBrowser.ItemCallback {} + /** Wrapper for MediaBrowser.ItemCallback */ + public abstract static class ItemCallback + extends android.media.browse.MediaBrowser.ItemCallback {} - /** - * Wrapper for MediaBrowser.SubscriptionCallback - */ - public abstract static class SubscriptionCallback extends - android.media.browse.MediaBrowser.SubscriptionCallback { - /** - * Wrapper for MediaBrowser.SubscriptionCallback.getTimeoutHandler() - */ + /** Wrapper for MediaBrowser.SubscriptionCallback */ + public abstract static class SubscriptionCallback + extends android.media.browse.MediaBrowser.SubscriptionCallback { + /** Wrapper for MediaBrowser.SubscriptionCallback.getTimeoutHandler() */ public abstract Handler getTimeoutHandler(); } - /** - * Wrapper for MediaBrowser.connect() - */ + /** Wrapper for MediaBrowser.connect() */ public void connect() { mDelegate.connect(); } - /** - * Wrapper for MediaBrowser.disconnect() - */ + /** Wrapper for MediaBrowser.disconnect() */ public void disconnect() { mDelegate.disconnect(); } - /** - * Wrapper for MediaBrowser.getExtras() - */ + /** Wrapper for MediaBrowser.getExtras() */ public Bundle getExtras() { return mDelegate.getExtras(); } - /** - * Wrapper for MediaBrowser.getItem(String mediaId, ItemCallback callback) - */ + /** Wrapper for MediaBrowser.getItem(String mediaId, ItemCallback callback) */ public void getItem(String mediaId, ItemCallback callback) { mDelegate.getItem(mediaId, callback); } - /** - * Wrapper for MediaBrowser.getRoot() - */ + /** Wrapper for MediaBrowser.getRoot() */ public String getRoot() { return mDelegate.getRoot(); } - /** - * Wrapper for MediaBrowser.getServiceComponent() - */ + /** Wrapper for MediaBrowser.getServiceComponent() */ public ComponentName getServiceComponent() { return mDelegate.getServiceComponent(); } - /** - * Wrapper for MediaBrowser.getSessionToken() - */ + /** Wrapper for MediaBrowser.getSessionToken() */ public MediaSession.Token getSessionToken() { return mDelegate.getSessionToken(); } - /** - * Wrapper for MediaBrowser.isConnected() - */ + + /** Wrapper for MediaBrowser.isConnected() */ public boolean isConnected() { return mDelegate.isConnected(); } /** - * Wrapper for MediaBrowser.subscribe(String parentId, Bundle options, - * SubscriptionCallback callback) + * Wrapper for MediaBrowser.subscribe(String parentId, Bundle options, SubscriptionCallback + * callback) */ public void subscribe(String parentId, Bundle options, SubscriptionCallback callback) { mDelegate.subscribe(parentId, options, callback); } - /** - * Wrapper for MediaBrowser.subscribe(String parentId, SubscriptionCallback callback) - */ + /** Wrapper for MediaBrowser.subscribe(String parentId, SubscriptionCallback callback) */ public void subscribe(String parentId, SubscriptionCallback callback) { mDelegate.subscribe(parentId, callback); } - /** - * Wrapper for MediaBrowser.unsubscribe(String parentId) - */ + /** Wrapper for MediaBrowser.unsubscribe(String parentId) */ public void unsubscribe(String parentId) { mDelegate.unsubscribe(parentId); } - - /** - * Wrapper for MediaBrowser.unsubscribe(String parentId, SubscriptionCallback callback) - */ + /** Wrapper for MediaBrowser.unsubscribe(String parentId, SubscriptionCallback callback) */ public void unsubscribe(String parentId, SubscriptionCallback callback) { mDelegate.unsubscribe(parentId, callback); } @@ -163,8 +132,11 @@ public class MediaBrowser { * MediaBrowserFactory.make() */ @VisibleForTesting - public void testInit(Context context, ComponentName serviceComponent, - ConnectionCallback callback, Bundle rootHints) { + public void testInit( + Context context, + ComponentName serviceComponent, + ConnectionCallback callback, + Bundle rootHints) { // This is only used by Mockito to capture the constructor arguments on creation Log.wtf("AvrcpMockMediaBrowser", "This function should never be called"); } diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java index aa2f76c252c..4570af982a9 100644 --- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java +++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java @@ -23,10 +23,9 @@ import android.os.Bundle; import com.android.internal.annotations.VisibleForTesting; /** - * Provide a method to inject custom MediaBrowser objects for testing. By using the factory - * methods instead of calling the constructor of MediaBrowser directly, we can inject a custom - * MediaBrowser that can be used with JUnit and Mockito to set expectations and validate - * behaviour in tests. + * Provide a method to inject custom MediaBrowser objects for testing. By using the factory methods + * instead of calling the constructor of MediaBrowser directly, we can inject a custom MediaBrowser + * that can be used with JUnit and Mockito to set expectations and validate behaviour in tests. */ public final class MediaBrowserFactory { private static MediaBrowser sInjectedBrowser; @@ -36,8 +35,11 @@ public final class MediaBrowserFactory { return (delegate != null) ? new MediaBrowser(delegate) : null; } - static MediaBrowser make(Context context, ComponentName serviceComponent, - MediaBrowser.ConnectionCallback callback, Bundle rootHints) { + static MediaBrowser make( + Context context, + ComponentName serviceComponent, + MediaBrowser.ConnectionCallback callback, + Bundle rootHints) { if (sInjectedBrowser != null) { sInjectedBrowser.testInit(context, serviceComponent, callback, rootHints); return sInjectedBrowser; diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java index 232f3edbd17..a0081b21901 100644 --- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java +++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java @@ -35,10 +35,9 @@ import java.util.List; import java.util.Objects; /** - * Provide a mockable interface in order to test classes that use MediaController. - * We need this class due to the fact that the MediaController class is marked as final and - * there is no way to currently mock final classes in Android. Once this is possible this class - * can be deleted. + * Provide a mockable interface in order to test classes that use MediaController. We need this + * class due to the fact that the MediaController class is marked as final and there is no way to + * currently mock final classes in Android. Once this is possible this class can be deleted. */ public class MediaController { @NonNull public android.media.session.MediaController mDelegate; @@ -66,169 +65,123 @@ public class MediaController { return mTransportControls; } - /** - * Wrapper for MediaController.dispatchMediaButtonEvent(KeyEvent keyEvent) - */ + /** Wrapper for MediaController.dispatchMediaButtonEvent(KeyEvent keyEvent) */ public boolean dispatchMediaButtonEvent(@NonNull KeyEvent keyEvent) { return mDelegate.dispatchMediaButtonEvent(keyEvent); } - /** - * Wrapper for MediaController.getPlaybackState() - */ + /** Wrapper for MediaController.getPlaybackState() */ @Nullable public PlaybackState getPlaybackState() { return mDelegate.getPlaybackState(); } - - /** - * Wrapper for MediaController.getMetadata() - */ + /** Wrapper for MediaController.getMetadata() */ @Nullable public MediaMetadata getMetadata() { return mDelegate.getMetadata(); } - /** - * Wrapper for MediaController.getQueue() - */ + /** Wrapper for MediaController.getQueue() */ @Nullable public List getQueue() { return mDelegate.getQueue(); } - /** - * Wrapper for MediaController.getQueueTitle() - */ + /** Wrapper for MediaController.getQueueTitle() */ @Nullable public CharSequence getQueueTitle() { return mDelegate.getQueueTitle(); } - /** - * Wrapper for MediaController.getExtras() - */ + /** Wrapper for MediaController.getExtras() */ @Nullable public Bundle getExtras() { return mDelegate.getExtras(); } - /** - * Wrapper for MediaController.getRatingType() - */ + /** Wrapper for MediaController.getRatingType() */ public int getRatingType() { return mDelegate.getRatingType(); } - /** - * Wrapper for MediaController.getFlags() - */ + /** Wrapper for MediaController.getFlags() */ public long getFlags() { return mDelegate.getFlags(); } - /** - * Wrapper for MediaController.getPlaybackInfo() - */ + /** Wrapper for MediaController.getPlaybackInfo() */ @Nullable public android.media.session.MediaController.PlaybackInfo getPlaybackInfo() { return mDelegate.getPlaybackInfo(); } - - /** - * Wrapper for MediaController.getSessionActivity() - */ + /** Wrapper for MediaController.getSessionActivity() */ @Nullable public PendingIntent getSessionActivity() { return mDelegate.getSessionActivity(); } - /** - * Wrapper for MediaController.getSessionToken() - */ + /** Wrapper for MediaController.getSessionToken() */ @NonNull public MediaSession.Token getSessionToken() { return mDelegate.getSessionToken(); } - /** - * Wrapper for MediaController.setVolumeTo(int value, int flags) - */ + /** Wrapper for MediaController.setVolumeTo(int value, int flags) */ public void setVolumeTo(int value, int flags) { mDelegate.setVolumeTo(value, flags); } - /** - * Wrapper for MediaController.adjustVolume(int direction, int flags) - */ + /** Wrapper for MediaController.adjustVolume(int direction, int flags) */ public void adjustVolume(int direction, int flags) { mDelegate.adjustVolume(direction, flags); } - /** - * Wrapper for MediaController.registerCallback(Callback callback) - */ + /** Wrapper for MediaController.registerCallback(Callback callback) */ public void registerCallback(@NonNull Callback callback) { - //TODO(apanicke): Add custom callback struct to be able to analyze and + // TODO(apanicke): Add custom callback struct to be able to analyze and // delegate callbacks mDelegate.registerCallback(callback); } - /** - * Wrapper for MediaController.registerCallback(Callback callback, Handler handler) - */ + /** Wrapper for MediaController.registerCallback(Callback callback, Handler handler) */ public void registerCallback(@NonNull Callback callback, @Nullable Handler handler) { mDelegate.registerCallback(callback, handler); } - /** - * Wrapper for MediaController.unregisterCallback(Callback callback) - */ + /** Wrapper for MediaController.unregisterCallback(Callback callback) */ public void unregisterCallback(@NonNull Callback callback) { mDelegate.unregisterCallback(callback); } - /** - * Wrapper for MediaController.sendCommand(String command, Bundle args, ResultReceiver cb) - */ - public void sendCommand(@NonNull String command, @Nullable Bundle args, - @Nullable ResultReceiver cb) { + /** Wrapper for MediaController.sendCommand(String command, Bundle args, ResultReceiver cb) */ + public void sendCommand( + @NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) { mDelegate.sendCommand(command, args, cb); } - /** - * Wrapper for MediaController.getPackageName() - */ + /** Wrapper for MediaController.getPackageName() */ public String getPackageName() { return mDelegate.getPackageName(); } - /** - * Wrapper for MediaController.getTag() - */ + /** Wrapper for MediaController.getTag() */ public String getTag() { return mDelegate.getTag(); } - /** - * Wrapper for MediaController.controlsSameSession(MediaController other) - */ + /** Wrapper for MediaController.controlsSameSession(MediaController other) */ public boolean controlsSameSession(MediaController other) { return mDelegate.getSessionToken().equals(other.getWrappedInstance().getSessionToken()); } - /** - * Wrapper for MediaController.controlsSameSession(MediaController other) - */ + /** Wrapper for MediaController.controlsSameSession(MediaController other) */ public boolean controlsSameSession(android.media.session.MediaController other) { return mDelegate.getSessionToken().equals(other.getSessionToken()); } - /** - * Wrapper for MediaController.equals(Object other) - */ + /** Wrapper for MediaController.equals(Object other) */ @Override public boolean equals(Object o) { if (o instanceof android.media.session.MediaController) { @@ -240,175 +193,130 @@ public class MediaController { return false; } - /** - * Wrapper for MediaController.hashCode() - */ + /** Wrapper for MediaController.hashCode() */ @Override public int hashCode() { return Objects.hash(mDelegate); } - /** - * Wrapper for MediaController.toString() - */ + /** Wrapper for MediaController.toString() */ @Override public String toString() { MediaMetadata data = getMetadata(); MediaDescription desc = (data == null) ? null : data.getDescription(); - return "MediaController (" + getPackageName() + "@" + Integer.toHexString( - mDelegate.hashCode()) + ") " + desc; + return "MediaController (" + + getPackageName() + + "@" + + Integer.toHexString(mDelegate.hashCode()) + + ") " + + desc; } - /** - * Wrapper for MediaController.Callback - */ + /** Wrapper for MediaController.Callback */ public abstract static class Callback extends android.media.session.MediaController.Callback {} - /** - * Wrapper for MediaController.TransportControls - */ + /** Wrapper for MediaController.TransportControls */ public class TransportControls { - /** - * Wrapper for MediaController.TransportControls.prepare() - */ + /** Wrapper for MediaController.TransportControls.prepare() */ public void prepare() { mTransportDelegate.prepare(); } - /** - * Wrapper for MediaController.TransportControls.prepareFromMediaId() - */ + /** Wrapper for MediaController.TransportControls.prepareFromMediaId() */ public void prepareFromMediaId(String mediaId, Bundle extras) { mTransportDelegate.prepareFromMediaId(mediaId, extras); } - /** - * Wrapper for MediaController.TransportControls.prepareFromSearch() - */ + /** Wrapper for MediaController.TransportControls.prepareFromSearch() */ public void prepareFromSearch(String query, Bundle extras) { mTransportDelegate.prepareFromSearch(query, extras); } - /** - * Wrapper for MediaController.TransportControls.prepareFromUri() - */ + /** Wrapper for MediaController.TransportControls.prepareFromUri() */ public void prepareFromUri(Uri uri, Bundle extras) { mTransportDelegate.prepareFromUri(uri, extras); } - /** - * Wrapper for MediaController.TransportControls.play() - */ + /** Wrapper for MediaController.TransportControls.play() */ public void play() { mTransportDelegate.play(); } - /** - * Wrapper for MediaController.TransportControls.playFromMediaId() - */ + /** Wrapper for MediaController.TransportControls.playFromMediaId() */ public void playFromMediaId(String mediaId, Bundle extras) { mTransportDelegate.playFromMediaId(mediaId, extras); } - /** - * Wrapper for MediaController.TransportControls.playFromSearch() - */ + /** Wrapper for MediaController.TransportControls.playFromSearch() */ public void playFromSearch(String query, Bundle extras) { mTransportDelegate.playFromSearch(query, extras); } - /** - * Wrapper for MediaController.TransportControls.playFromUri() - */ + /** Wrapper for MediaController.TransportControls.playFromUri() */ public void playFromUri(Uri uri, Bundle extras) { mTransportDelegate.playFromUri(uri, extras); } - /** - * Wrapper for MediaController.TransportControls.skipToQueueItem() - */ + /** Wrapper for MediaController.TransportControls.skipToQueueItem() */ public void skipToQueueItem(long id) { mTransportDelegate.skipToQueueItem(id); } - /** - * Wrapper for MediaController.TransportControls.pause() - */ + /** Wrapper for MediaController.TransportControls.pause() */ public void pause() { mTransportDelegate.pause(); } - /** - * Wrapper for MediaController.TransportControls.stop() - */ + /** Wrapper for MediaController.TransportControls.stop() */ public void stop() { mTransportDelegate.stop(); } - /** - * Wrapper for MediaController.TransportControls.seekTo() - */ + /** Wrapper for MediaController.TransportControls.seekTo() */ public void seekTo(long pos) { mTransportDelegate.seekTo(pos); } - /** - * Wrapper for MediaController.TransportControls.fastForward() - */ + /** Wrapper for MediaController.TransportControls.fastForward() */ public void fastForward() { mTransportDelegate.fastForward(); } - /** - * Wrapper for MediaController.TransportControls.skipToNext() - */ + /** Wrapper for MediaController.TransportControls.skipToNext() */ public void skipToNext() { mTransportDelegate.skipToNext(); } - /** - * Wrapper for MediaController.TransportControls.rewind() - */ + /** Wrapper for MediaController.TransportControls.rewind() */ public void rewind() { mTransportDelegate.rewind(); } - /** - * Wrapper for MediaController.TransportControls.skipToPrevious() - */ + /** Wrapper for MediaController.TransportControls.skipToPrevious() */ public void skipToPrevious() { mTransportDelegate.skipToPrevious(); } - /** - * Wrapper for MediaController.TransportControls.setRating() - */ + /** Wrapper for MediaController.TransportControls.setRating() */ public void setRating(Rating rating) { mTransportDelegate.setRating(rating); } - /** - * Wrapper for MediaController.TransportControls.setPlaybackSpeed(float speed) - */ + /** Wrapper for MediaController.TransportControls.setPlaybackSpeed(float speed) */ public void setPlaybackSpeed(float speed) { mTransportDelegate.setPlaybackSpeed(speed); } - /** - * Wrapper for MediaController.TransportControls.sendCustomAction() - */ - public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction, - @Nullable Bundle args) { + /** Wrapper for MediaController.TransportControls.sendCustomAction() */ + public void sendCustomAction( + @NonNull PlaybackState.CustomAction customAction, @Nullable Bundle args) { mTransportDelegate.sendCustomAction(customAction, args); } - /** - * Wrapper for MediaController.TransportControls.sendCustomAction() - */ + /** Wrapper for MediaController.TransportControls.sendCustomAction() */ public void sendCustomAction(@NonNull String action, @Nullable Bundle args) { mTransportDelegate.sendCustomAction(action, args); } } } - diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java index 5784ee227b7..cb2798bdc32 100644 --- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java +++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java @@ -51,4 +51,3 @@ public final class MediaPlayerWrapperFactory { sInjectedWrapper = wrapper; } } - diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java index e495c4a0632..497b738bfd8 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java @@ -31,33 +31,32 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; -/** - * A class responsible for handling requests from a specific client connection - */ +/** A class responsible for handling requests from a specific client connection */ public class AvrcpBipObexServer extends ServerRequestHandler { private static final String TAG = AvrcpBipObexServer.class.getSimpleName(); private final AvrcpCoverArtService mAvrcpCoverArtService; // AVRCP Controller BIP Image Initiator/Cover Art UUID - AVRCP 1.6 Section 5.14.2.1 - private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] { - (byte) 0x71, - (byte) 0x63, - (byte) 0xDD, - (byte) 0x54, - (byte) 0x4A, - (byte) 0x7E, - (byte) 0x11, - (byte) 0xE2, - (byte) 0xB4, - (byte) 0x7C, - (byte) 0x00, - (byte) 0x50, - (byte) 0xC2, - (byte) 0x49, - (byte) 0x00, - (byte) 0x48 - }; + private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = + new byte[] { + (byte) 0x71, + (byte) 0x63, + (byte) 0xDD, + (byte) 0x54, + (byte) 0x4A, + (byte) 0x7E, + (byte) 0x11, + (byte) 0xE2, + (byte) 0xB4, + (byte) 0x7C, + (byte) 0x00, + (byte) 0x50, + (byte) 0xC2, + (byte) 0x49, + (byte) 0x00, + (byte) 0x48 + }; private static final String TYPE_GET_LINKED_THUMBNAIL = "x-bt/img-thm"; private static final String TYPE_GET_IMAGE_PROPERTIES = "x-bt/img-properties"; @@ -68,22 +67,15 @@ public class AvrcpBipObexServer extends ServerRequestHandler { private final Callback mCallback; - /** - * A set of callbacks to notify the creator of important AVRCP BIP events. - */ + /** A set of callbacks to notify the creator of important AVRCP BIP events. */ public interface Callback { - /** - * Receive a notification when this server session connects to a device - */ + /** Receive a notification when this server session connects to a device */ void onConnected(); - /** - * Receive a notification when this server session disconnects with a device - */ + /** Receive a notification when this server session disconnects with a device */ void onDisconnected(); - /** - * Receive a notification when this server session closes a connection with a device - */ + + /** Receive a notification when this server session closes a connection with a device */ void onClose(); } @@ -164,8 +156,8 @@ public class AvrcpBipObexServer extends ServerRequestHandler { } @Override - public int onSetPath(final HeaderSet request, HeaderSet reply, final boolean backup, - final boolean create) { + public int onSetPath( + final HeaderSet request, HeaderSet reply, final boolean backup, final boolean create) { return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } @@ -180,9 +172,9 @@ public class AvrcpBipObexServer extends ServerRequestHandler { /** * Determine if a given image handle is valid in format * - * An image handle a 9 character string of numbers 0-9 only. Anything else is invalid. This is - * defined in section 4.4.4 (Image Handles) of the BIP specification, which is inherited by the - * AVRCP specification. + *

An image handle a 9 character string of numbers 0-9 only. Anything else is invalid. This + * is defined in section 4.4.4 (Image Handles) of the BIP specification, which is inherited by + * the AVRCP specification. * * @return True if the image handle is valid, false otherwise. */ @@ -195,7 +187,7 @@ public class AvrcpBipObexServer extends ServerRequestHandler { return true; } - private int handleGetImageThumbnail(Operation op)throws IOException { + private int handleGetImageThumbnail(Operation op) throws IOException { HeaderSet request = op.getReceivedHeader(); String imageHandle = (String) request.getHeader(HEADER_ID_IMG_HANDLE); @@ -312,9 +304,7 @@ public class AvrcpBipObexServer extends ServerRequestHandler { return sendResponse(op, replyHeaders, imageBytes); } - /** - * Send a response to the given operation using the given headers and bytes. - */ + /** Send a response to the given operation using the given headers and bytes. */ private int sendResponse(Operation op, HeaderSet replyHeaders, byte[] bytes) { if (op != null && bytes != null && replyHeaders != null) { OutputStream outStream = null; @@ -337,7 +327,8 @@ public class AvrcpBipObexServer extends ServerRequestHandler { if (outStream != null) { try { outStream.close(); - } catch (IOException e) { } + } catch (IOException e) { + } } } // If we didn't write everything then send the error code diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java index 867706d309b..c2db89ba19d 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java @@ -33,8 +33,8 @@ import java.util.HashMap; /** * The AVRCP Cover Art Service * - * This service handles allocation of image handles and storage of images. It also owns the - * BIP OBEX server that handles requests to get AVRCP cover artwork. + *

This service handles allocation of image handles and storage of images. It also owns the BIP + * OBEX server that handles requests to get AVRCP cover artwork. */ public class AvrcpCoverArtService { private static final String TAG = AvrcpCoverArtService.class.getSimpleName(); @@ -42,8 +42,8 @@ public class AvrcpCoverArtService { private static final int COVER_ART_STORAGE_MAX_ITEMS = 32; /** - * Limiting transmit packet size because some carkits are disconnected if - * AVRCP Cover Art OBEX packet size exceed 1024 bytes. + * Limiting transmit packet size because some carkits are disconnected if AVRCP Cover Art OBEX + * packet size exceed 1024 bytes. */ private static final int MAX_TRANSMIT_PACKET_SIZE = 1024; @@ -71,7 +71,7 @@ public class AvrcpCoverArtService { /** * Start the AVRCP Cover Art Service. * - * This will start up a BIP OBEX server and record the l2cap psm in the SDP record, and begin + *

This will start up a BIP OBEX server and record the l2cap psm in the SDP record, and begin * accepting connections. */ public boolean start() { @@ -87,7 +87,7 @@ public class AvrcpCoverArtService { /** * Stop the AVRCP Cover Art Service. * - * Tear down existing connections, remove ourselved from the SDP record. + *

Tear down existing connections, remove ourselved from the SDP record. */ public boolean stop() { debug("Stopping service"); @@ -142,35 +142,27 @@ public class AvrcpCoverArtService { } } - /** - * Store an image with the service and gets the image handle it's associated with. - */ + /** Store an image with the service and gets the image handle it's associated with. */ public String storeImage(Image image) { debug("storeImage(image='" + image + "')"); if (image == null || image.getImage() == null) return null; return mStorage.storeImage(new CoverArt(image)); } - /** - * Get the image stored at the given image handle, if it exists - */ + /** Get the image stored at the given image handle, if it exists */ public CoverArt getImage(String imageHandle) { debug("getImage(" + imageHandle + ")"); return mStorage.getImage(imageHandle); } - /** - * Add a BIP L2CAP PSM to the AVRCP Target SDP Record - */ + /** Add a BIP L2CAP PSM to the AVRCP Target SDP Record */ private void registerBipServer(int psm) { debug("Add our PSM (" + psm + ") to the AVRCP Target SDP record"); mNativeInterface.registerBipServer(psm); return; } - /** - * Remove any BIP L2CAP PSM from the AVRCP Target SDP Record - */ + /** Remove any BIP L2CAP PSM from the AVRCP Target SDP Record */ private void unregisterBipServer() { debug("Remove the PSM remove the AVRCP Target SDP record"); mNativeInterface.unregisterBipServer(); @@ -180,8 +172,8 @@ public class AvrcpCoverArtService { /** * Connect a device with the server * - * Since the server cannot explicitly make clients connect, this function is internal only and - * provides a place for us to do required book keeping when we've decided to accept a client + *

Since the server cannot explicitly make clients connect, this function is internal only + * and provides a place for us to do required book keeping when we've decided to accept a client */ private boolean connect(BluetoothDevice device, BluetoothSocket socket) { debug("Connect '" + device + "'"); @@ -210,9 +202,11 @@ public class AvrcpCoverArtService { disconnect(device); } }); - BluetoothObexTransport transport = new BluetoothObexTransport(socket, - MAX_TRANSMIT_PACKET_SIZE, - BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED); + BluetoothObexTransport transport = + new BluetoothObexTransport( + socket, + MAX_TRANSMIT_PACKET_SIZE, + BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED); transport.setConnectionForCoverArt(true); try { ServerSession session = new ServerSession(transport, s, null); @@ -225,9 +219,7 @@ public class AvrcpCoverArtService { } } - /** - * Explicitly disconnect a device from our BIP server if its connected. - */ + /** Explicitly disconnect a device from our BIP server if its connected. */ public void disconnect(BluetoothDevice device) { debug("disconnect '" + device + "'"); // Closing the server session closes the underlying transport, which closes the underlying @@ -245,7 +237,7 @@ public class AvrcpCoverArtService { /** * A Socket Acceptor to handle incoming connections to our BIP Server. * - * If we are accepting connections and the device is permitted, then this class will create a + *

If we are accepting connections and the device is permitted, then this class will create a * session with our AvrcpBipObexServer. */ private class SocketAcceptor implements IObexConnectionHandler { @@ -269,9 +261,7 @@ public class AvrcpCoverArtService { } } - /** - * Dump useful debug information about this service to a string - */ + /** Dump useful debug information about this service to a string */ public void dump(StringBuilder sb) { int psm = getL2capPsm(); sb.append("AvrcpCoverArtService:"); @@ -283,16 +273,12 @@ public class AvrcpCoverArtService { sb.append("\n"); } - /** - * Print a message to DEBUG if debug output is enabled - */ + /** Print a message to DEBUG if debug output is enabled */ private void debug(String msg) { Log.d(TAG, msg); } - /** - * Print a message to ERROR - */ + /** Print a message to ERROR */ private void error(String msg) { Log.e(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java index 3348da981fe..9c53bc50ffe 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java @@ -22,9 +22,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -/** - * A class abstracting the storage method of cover art images - */ +/** A class abstracting the storage method of cover art images */ final class AvrcpCoverArtStorage { private static final String TAG = AvrcpCoverArtStorage.class.getSimpleName(); @@ -36,16 +34,12 @@ final class AvrcpCoverArtStorage { private final Map mImageHandles; private final Map mImages; - /** - * Make an image storage object with no bounds on the amount of images it can store - */ + /** Make an image storage object with no bounds on the amount of images it can store */ AvrcpCoverArtStorage() { this(0); } - /** - * Make an image storage object with a bound on the amount of images it can store - */ + /** Make an image storage object with a bound on the amount of images it can store */ AvrcpCoverArtStorage(int maxSize) { if (maxSize < 0) { throw new IllegalArgumentException("maxSize < 0"); @@ -60,9 +54,7 @@ final class AvrcpCoverArtStorage { mImages = new LinkedHashMap(0, 0.75f /* default load factor */, true); } - /** - * Store an image and get the image handle it's been associated with. - */ + /** Store an image and get the image handle it's been associated with. */ public String storeImage(CoverArt coverArt) { debug("storeImage(CoverArt='" + coverArt + "')"); if (coverArt == null || coverArt.getImage() == null) { @@ -103,9 +95,7 @@ final class AvrcpCoverArtStorage { return imageHandle; } - /** - * Get the image stored at the given image handle, if it exists - */ + /** Get the image stored at the given image handle, if it exists */ public CoverArt getImage(String imageHandle) { debug("getImage(" + imageHandle + ")"); if (imageHandle == null) return null; @@ -116,9 +106,7 @@ final class AvrcpCoverArtStorage { } } - /** - * Clear out all stored images and image handles - */ + /** Clear out all stored images and image handles */ public void clear() { synchronized (mImagesLock) { mImages.clear(); @@ -147,8 +135,8 @@ final class AvrcpCoverArtStorage { /** * Get the next available image handle value if one is available. * - * Values are integers in the domain [0, 9999999], represented as zero-padded strings. Getting - * an image handle assumes you will use it. + *

Values are integers in the domain [0, 9999999], represented as zero-padded strings. + * Getting an image handle assumes you will use it. */ private String getNextImageHandle() { synchronized (mHandlesLock) { @@ -193,16 +181,12 @@ final class AvrcpCoverArtStorage { sb.append("\n\tImage bytes: " + bytes); } - /** - * Print a message to DEBUG if debug output is enabled - */ + /** Print a message to DEBUG if debug output is enabled */ private void debug(String msg) { Log.d(TAG, msg); } - /** - * Print a message to ERROR - */ + /** Print a message to ERROR */ private void error(String msg) { Log.e(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java index 0afdeacf808..448bb600109 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java @@ -34,8 +34,7 @@ import java.util.List; import java.util.Objects; /** - * Native Interface to communicate with the JNI layer. This class should never be passed null - * data. + * Native Interface to communicate with the JNI layer. This class should never be passed null data. */ public class AvrcpNativeInterface { private static final String TAG = AvrcpNativeInterface.class.getSimpleName(); @@ -49,8 +48,10 @@ public class AvrcpNativeInterface { private AdapterService mAdapterService; private AvrcpNativeInterface() { - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when AvrcpNativeInterface init"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when AvrcpNativeInterface init"); } static AvrcpNativeInterface getInstance() { @@ -175,15 +176,19 @@ public class AvrcpNativeInterface { // anything internally. It just returns the number of items in the root folder. void setBrowsedPlayer(int playerId) { d("setBrowsedPlayer: playerId=" + playerId); - mAvrcpService.getPlayerRoot(playerId, (a, b, c, d) -> - setBrowsedPlayerResponse(a, b, c, d)); + mAvrcpService.getPlayerRoot(playerId, (a, b, c, d) -> setBrowsedPlayerResponse(a, b, c, d)); } void setBrowsedPlayerResponse(int playerId, boolean success, String rootId, int numItems) { - d("setBrowsedPlayerResponse: playerId=" + playerId - + " success=" + success - + " rootId=" + rootId - + " numItems=" + numItems); + d( + "setBrowsedPlayerResponse: playerId=" + + playerId + + " success=" + + success + + " rootId=" + + rootId + + " numItems=" + + numItems); setBrowsedPlayerResponseNative(playerId, success, rootId, numItems); } @@ -198,16 +203,24 @@ public class AvrcpNativeInterface { } void sendMediaUpdate(boolean metadata, boolean playStatus, boolean queue) { - d("sendMediaUpdate: metadata=" + metadata - + " playStatus=" + playStatus - + " queue=" + queue); + d( + "sendMediaUpdate: metadata=" + + metadata + + " playStatus=" + + playStatus + + " queue=" + + queue); sendMediaUpdateNative(metadata, playStatus, queue); } void sendFolderUpdate(boolean availablePlayers, boolean addressedPlayers, boolean uids) { - d("sendFolderUpdate: availablePlayers=" + availablePlayers - + " addressedPlayers=" + addressedPlayers - + " uids=" + uids); + d( + "sendFolderUpdate: availablePlayers=" + + availablePlayers + + " addressedPlayers=" + + addressedPlayers + + " uids=" + + uids); sendFolderUpdateNative(availablePlayers, addressedPlayers, uids); } @@ -231,13 +244,15 @@ public class AvrcpNativeInterface { } void setActiveDevice(String bdaddr) { - BluetoothDevice device = mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr)); + BluetoothDevice device = + mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr)); d("setActiveDevice: device=" + device); mAvrcpService.setActiveDevice(device); } void deviceConnected(String bdaddr, boolean absoluteVolume) { - BluetoothDevice device = mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr)); + BluetoothDevice device = + mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr)); d("deviceConnected: device=" + device + " absoluteVolume=" + absoluteVolume); if (mAvrcpService == null) { Log.w(TAG, "deviceConnected: AvrcpTargetService is null"); @@ -248,7 +263,8 @@ public class AvrcpNativeInterface { } void deviceDisconnected(String bdaddr) { - BluetoothDevice device = mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr)); + BluetoothDevice device = + mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr)); d("deviceDisconnected: device=" + device); if (mAvrcpService == null) { Log.w(TAG, "deviceDisconnected: AvrcpTargetService is null"); @@ -307,8 +323,7 @@ public class AvrcpNativeInterface { valuesArray = new byte[1]; valuesArray[0] = PlayerSettingsValues.STATE_DEFAULT_OFF; } - listPlayerSettingValuesResponseNative( - settingRequest, valuesArray); + listPlayerSettingValuesResponseNative(settingRequest, valuesArray); } /** Request from remote current values for player settings. */ diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java index 2c3096390eb..cbe855fbf0f 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java @@ -117,16 +117,21 @@ public class AvrcpTargetService extends ProfileService { boolean state = !MediaPlayerWrapper.playstateEquals(mCurrentData.state, data.state); boolean queue = !Objects.equals(mCurrentData.queue, data.queue); - Log.d(TAG, "onMediaUpdated: track_changed=" + metadata - + " state=" + state + " queue=" + queue); + Log.d( + TAG, + "onMediaUpdated: track_changed=" + + metadata + + " state=" + + state + + " queue=" + + queue); mCurrentData = data; mNativeInterface.sendMediaUpdate(metadata, state, queue); } @Override - public void run(boolean availablePlayers, boolean addressedPlayers, - boolean uids) { + public void run(boolean availablePlayers, boolean addressedPlayers, boolean uids) { if (mNativeInterface == null) return; mNativeInterface.sendFolderUpdate(availablePlayers, addressedPlayers, uids); @@ -403,7 +408,8 @@ public class AvrcpTargetService extends ProfileService { /** Returns the current play status of the active player from {@link MediaPlayerList}. */ PlayStatus getPlayState() { - return PlayStatus.fromPlaybackState(mMediaPlayerList.getCurrentPlayStatus(), + return PlayStatus.fromPlaybackState( + mMediaPlayerList.getCurrentPlayStatus(), Long.parseLong(getCurrentSongInfo().duration)); } diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java index 9a7786d6716..f96f68c29ed 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java @@ -59,8 +59,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback { private static final String VOLUME_MAP = "bluetooth_volume_map"; private static final String VOLUME_CHANGE_LOG_TITLE = "BTAudio Volume Events"; - @VisibleForTesting - static final int AVRCP_MAX_VOL = 127; + @VisibleForTesting static final int AVRCP_MAX_VOL = 127; private static final int STREAM_MUSIC = AudioManager.STREAM_MUSIC; private static final int VOLUME_CHANGE_LOGGER_SIZE = 30; private static int sDeviceMaxVolume = 0; @@ -156,8 +155,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback { // If absolute volume for the device is supported, set the volume for the device if (mDeviceMap.get(device)) { int avrcpVolume = systemToAvrcpVolume(savedVolume); - mVolumeEventLogger.logd(TAG, - "switchVolumeDevice: Updating device volume: avrcpVolume=" + avrcpVolume); + mVolumeEventLogger.logd( + TAG, "switchVolumeDevice: Updating device volume: avrcpVolume=" + avrcpVolume); mNativeInterface.sendVolumeChanged(device, avrcpVolume); } } @@ -168,8 +167,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback { *

Fills {@code mVolumeMap} with content from {@link #getVolumeMap}, removing unbonded * devices if necessary. */ - AvrcpVolumeManager(Context context, AudioManager audioManager, - AvrcpNativeInterface nativeInterface) { + AvrcpVolumeManager( + Context context, AudioManager audioManager, AvrcpNativeInterface nativeInterface) { mContext = context; mAudioManager = audioManager; mNativeInterface = nativeInterface; @@ -207,8 +206,12 @@ class AvrcpVolumeManager extends AudioDeviceCallback { return; } SharedPreferences.Editor pref = getVolumeMap().edit(); - mVolumeEventLogger.logd(TAG, "storeVolume: Storing stream volume level for device " - + device + " : " + storeVolume); + mVolumeEventLogger.logd( + TAG, + "storeVolume: Storing stream volume level for device " + + device + + " : " + + storeVolume); mVolumeMap.put(device, storeVolume); pref.putInt(device.getAddress(), storeVolume); // Always use apply() since it is asynchronous, otherwise the call can hang waiting for @@ -221,7 +224,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback { * #storeVolumeForDevice(BluetoothDevice, int)} with {@code device}. */ synchronized void storeVolumeForDevice(@NonNull BluetoothDevice device) { - int storeVolume = mAudioManager.getLastAudibleStreamVolume(STREAM_MUSIC); + int storeVolume = mAudioManager.getLastAudibleStreamVolume(STREAM_MUSIC); storeVolumeForDevice(device, storeVolume); } @@ -234,8 +237,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback { return; } SharedPreferences.Editor pref = getVolumeMap().edit(); - mVolumeEventLogger.logd(TAG, - "RemoveStoredVolume: Remove stored stream volume level for device " + device); + mVolumeEventLogger.logd( + TAG, "RemoveStoredVolume: Remove stored stream volume level for device " + device); mVolumeMap.remove(device); pref.remove(device.getAddress()); // Always use apply() since it is asynchronous, otherwise the call can hang waiting for @@ -273,14 +276,22 @@ class AvrcpVolumeManager extends AudioDeviceCallback { */ void setVolume(@NonNull BluetoothDevice device, int avrcpVolume) { int deviceVolume = avrcpToSystemVolume(avrcpVolume); - mVolumeEventLogger.logd(TAG, "setVolume:" - + " device=" + device - + " avrcpVolume=" + avrcpVolume - + " deviceVolume=" + deviceVolume - + " sDeviceMaxVolume=" + sDeviceMaxVolume); - mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, deviceVolume, + mVolumeEventLogger.logd( + TAG, + "setVolume:" + + " device=" + + device + + " avrcpVolume=" + + avrcpVolume + + " deviceVolume=" + + deviceVolume + + " sDeviceMaxVolume=" + + sDeviceMaxVolume); + mAudioManager.setStreamVolume( + AudioManager.STREAM_MUSIC, + deviceVolume, (deviceVolume != getVolume(device, -1) ? AudioManager.FLAG_SHOW_UI : 0) - | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME); + | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME); storeVolumeForDevice(device); } @@ -297,11 +308,17 @@ class AvrcpVolumeManager extends AudioDeviceCallback { return; } int avrcpVolume = systemToAvrcpVolume(deviceVolume); - mVolumeEventLogger.logd(TAG, "sendVolumeChanged:" - + " device=" + device - + " avrcpVolume=" + avrcpVolume - + " deviceVolume=" + deviceVolume - + " sDeviceMaxVolume=" + sDeviceMaxVolume); + mVolumeEventLogger.logd( + TAG, + "sendVolumeChanged:" + + " device=" + + device + + " avrcpVolume=" + + avrcpVolume + + " deviceVolume=" + + deviceVolume + + " sDeviceMaxVolume=" + + sDeviceMaxVolume); mNativeInterface.sendVolumeChanged(device, avrcpVolume); storeVolumeForDevice(device); } @@ -403,13 +420,15 @@ class AvrcpVolumeManager extends AudioDeviceCallback { sb.append(" mCurrentDevice: " + mCurrentDevice + "\n"); sb.append(" Current System Volume: " + mAudioManager.getStreamVolume(STREAM_MUSIC) + "\n"); sb.append(" Device Volume Memory Map:\n"); - sb.append(String.format(" %-17s : %-14s : %3s : %s\n", - "Device Address", "Device Name", "Vol", "AbsVol")); + sb.append( + String.format( + " %-17s : %-14s : %3s : %s\n", + "Device Address", "Device Name", "Vol", "AbsVol")); Map allKeys = getVolumeMap().getAll(); for (Map.Entry entry : allKeys.entrySet()) { Object value = entry.getValue(); - BluetoothDevice d = BluetoothAdapter.getDefaultAdapter() - .getRemoteDevice(entry.getKey()); + BluetoothDevice d = + BluetoothAdapter.getDefaultAdapter().getRemoteDevice(entry.getKey()); String deviceName = d.getName(); if (deviceName == null) { @@ -424,8 +443,10 @@ class AvrcpVolumeManager extends AudioDeviceCallback { } if (value instanceof Integer) { - sb.append(String.format(" %-17s : %-14s : %3d : %s\n", - d.getAddress(), deviceName, (Integer) value, absoluteVolume)); + sb.append( + String.format( + " %-17s : %-14s : %3d : %s\n", + d.getAddress(), deviceName, (Integer) value, absoluteVolume)); } } diff --git a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java index a0d90d77853..4fe5c89a17b 100644 --- a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java +++ b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java @@ -126,7 +126,7 @@ public class AvrcpPassthrough { case BluetoothAvrcp.PASSTHROUGH_ID_ANGLE: case BluetoothAvrcp.PASSTHROUGH_ID_SUBPICT: case BluetoothAvrcp.PASSTHROUGH_ID_VENDOR: - // Fallthrough for all unknown key mappings + // Fallthrough for all unknown key mappings default: return KeyEvent.KEYCODE_UNKNOWN; } diff --git a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java index 67378f843b8..a3ab9192e9a 100644 --- a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java +++ b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java @@ -18,9 +18,7 @@ package com.android.bluetooth.avrcp; import android.os.SystemProperties; -/** - * A class to represent an AVRCP version - */ +/** A class to represent an AVRCP version */ final class AvrcpVersion { public static final AvrcpVersion AVRCP_VERSION_1_3 = new AvrcpVersion(1, 3); public static final AvrcpVersion AVRCP_VERSION_1_4 = new AvrcpVersion(1, 4); diff --git a/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java b/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java index d20da981661..0a38467f166 100644 --- a/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java +++ b/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java @@ -33,10 +33,10 @@ import java.security.NoSuchAlgorithmException; /** * An object to represent a piece of cover artwork/ * - * This object abstracts away the actual storage method and provides a means for others to + *

This object abstracts away the actual storage method and provides a means for others to * understand available formats and get the underlying image in a particular format. * - * All return values are ready to use by a BIP server. + *

All return values are ready to use by a BIP server. */ public class CoverArt { private static final String TAG = CoverArt.class.getSimpleName(); @@ -45,9 +45,7 @@ public class CoverArt { private String mImageHandle = null; private Bitmap mImage = null; - /** - * Create a CoverArt object from an audio_util Image abstraction - */ + /** Create a CoverArt object from an audio_util Image abstraction */ CoverArt(Image image) { // Create a scaled version of the image for now, as consumers don't need // anything larger than this at the moment. Also makes each image gathered @@ -58,7 +56,7 @@ public class CoverArt { /** * Get the image handle that has been associated with this image. * - * If this returns null then you will fail to generate image properties + *

If this returns null then you will fail to generate image properties */ public String getImageHandle() { return mImageHandle; @@ -67,26 +65,22 @@ public class CoverArt { /** * Set the image handle that has been associated with this image. * - * This is required to generate image properties + *

This is required to generate image properties */ public void setImageHandle(String handle) { mImageHandle = handle; } - /** - * Covert a Bitmap to a byte array with an image format without lossy compression - */ + /** Covert a Bitmap to a byte array with an image format without lossy compression */ private byte[] toByteArray(Bitmap bitmap) { if (bitmap == null) return null; - ByteArrayOutputStream buffer = new ByteArrayOutputStream( - bitmap.getWidth() * bitmap.getHeight()); + ByteArrayOutputStream buffer = + new ByteArrayOutputStream(bitmap.getWidth() * bitmap.getHeight()); bitmap.compress(Bitmap.CompressFormat.PNG, 100, buffer); return buffer.toByteArray(); } - /** - * Get a hash code of this CoverArt image - */ + /** Get a hash code of this CoverArt image */ public String getImageHash() { byte[] image = toByteArray(mImage); if (image == null) return null; @@ -107,9 +101,7 @@ public class CoverArt { return hash; } - /** - * Get the cover artwork image bytes in the native format - */ + /** Get the cover artwork image bytes in the native format */ public byte[] getImage() { debug("GetImage(native)"); if (mImage == null) return null; @@ -118,9 +110,7 @@ public class CoverArt { return outputStream.toByteArray(); } - /** - * Get the cover artwork image bytes in the given encoding and pixel size - */ + /** Get the cover artwork image bytes in the given encoding and pixel size */ public byte[] getImage(BipImageDescriptor descriptor) { debug("GetImage(descriptor=" + descriptor); if (mImage == null) return null; @@ -135,9 +125,7 @@ public class CoverArt { return outputStream.toByteArray(); } - /** - * Determine if a given image descriptor is valid - */ + /** Determine if a given image descriptor is valid */ private boolean isDescriptorValid(BipImageDescriptor descriptor) { debug("isDescriptorValid(descriptor=" + descriptor + ")"); if (descriptor == null) return false; @@ -151,9 +139,7 @@ public class CoverArt { return false; } - /** - * Get the cover artwork image bytes as a 200 x 200 JPEG thumbnail - */ + /** Get the cover artwork image bytes as a 200 x 200 JPEG thumbnail */ public byte[] getThumbnail() { debug("GetImageThumbnail()"); if (mImage == null) return null; @@ -162,9 +148,7 @@ public class CoverArt { return outputStream.toByteArray(); } - /** - * Get the set of image properties that the cover artwork can be turned into - */ + /** Get the set of image properties that the cover artwork can be turned into */ public BipImageProperties getImageProperties() { debug("GetImageProperties()"); if (mImage == null) { @@ -187,9 +171,7 @@ public class CoverArt { return properties; } - /** - * Get the storage size of this image in bytes - */ + /** Get the storage size of this image in bytes */ public int size() { return mImage != null ? mImage.getAllocationByteCount() : 0; } @@ -199,16 +181,12 @@ public class CoverArt { return "{handle=" + mImageHandle + ", size=" + size() + " }"; } - /** - * Print a message to DEBUG if debug output is enabled - */ + /** Print a message to DEBUG if debug output is enabled */ private void debug(String msg) { Log.d(TAG, msg); } - /** - * Print a message to ERROR - */ + /** Print a message to ERROR */ private void error(String msg) { Log.e(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java index 3b54b09a3d8..dede3928bab 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java @@ -38,34 +38,35 @@ import java.lang.ref.WeakReference; * A client to a remote device's BIP Image Pull Server, as defined by a PSM passed in at * construction time. * - * Once the client connection is established you can use this client to get image properties and + *

Once the client connection is established you can use this client to get image properties and * download images. The connection to the server is held open to service multiple requests. * - * Client is good for one connection lifecycle. Please call shutdown() to clean up safely. Once a + *

Client is good for one connection lifecycle. Please call shutdown() to clean up safely. Once a * disconnection has occurred, please create a new client. */ public class AvrcpBipClient { private static final String TAG = AvrcpBipClient.class.getSimpleName(); // AVRCP Controller BIP Image Initiator/Cover Art UUID - AVRCP 1.6 Section 5.14.2.1 - private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] { - (byte) 0x71, - (byte) 0x63, - (byte) 0xDD, - (byte) 0x54, - (byte) 0x4A, - (byte) 0x7E, - (byte) 0x11, - (byte) 0xE2, - (byte) 0xB4, - (byte) 0x7C, - (byte) 0x00, - (byte) 0x50, - (byte) 0xC2, - (byte) 0x49, - (byte) 0x00, - (byte) 0x48 - }; + private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = + new byte[] { + (byte) 0x71, + (byte) 0x63, + (byte) 0xDD, + (byte) 0x54, + (byte) 0x4A, + (byte) 0x7E, + (byte) 0x11, + (byte) 0xE2, + (byte) 0xB4, + (byte) 0x7C, + (byte) 0x00, + (byte) 0x50, + (byte) 0xC2, + (byte) 0x49, + (byte) 0x00, + (byte) 0x48 + }; private static final int CONNECT = 0; private static final int DISCONNECT = 1; @@ -85,9 +86,7 @@ public class AvrcpBipClient { private final Callback mCallback; - /** - * Callback object used to be notified of when a request has been completed. - */ + /** Callback object used to be notified of when a request has been completed. */ interface Callback { /** @@ -104,8 +103,8 @@ public class AvrcpBipClient { * @param status A status code to indicate a success or error * @param properties The BipImageProperties object returned if successful, null otherwise */ - void onGetImagePropertiesComplete(int status, String imageHandle, - BipImageProperties properties); + void onGetImagePropertiesComplete( + int status, String imageHandle, BipImageProperties properties); /** * Notify of a get image operation completing @@ -141,9 +140,7 @@ public class AvrcpBipClient { mHandler = new AvrcpBipClientHandler(looper, this); } - /** - * Refreshes this client's OBEX session - */ + /** Refreshes this client's OBEX session */ public void refreshSession() { debug("Refresh client session"); if (!isConnected()) { @@ -159,9 +156,7 @@ public class AvrcpBipClient { } } - /** - * Safely disconnects the client from the server - */ + /** Safely disconnects the client from the server */ public void shutdown() { debug("Shutdown client"); try { @@ -201,11 +196,9 @@ public class AvrcpBipClient { return mPsm; } - /** - * Retrieve the image properties associated with the given imageHandle - */ + /** Retrieve the image properties associated with the given imageHandle */ public boolean getImageProperties(String imageHandle) { - RequestGetImageProperties request = new RequestGetImageProperties(imageHandle); + RequestGetImageProperties request = new RequestGetImageProperties(imageHandle); boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request)); if (!status) { error("Adding messages failed, connection state: " + isConnected()); @@ -214,11 +207,9 @@ public class AvrcpBipClient { return true; } - /** - * Download the image object associated with the given imageHandle - */ + /** Download the image object associated with the given imageHandle */ public boolean getImage(String imageHandle, BipImageDescriptor descriptor) { - RequestGetImage request = new RequestGetImage(imageHandle, descriptor); + RequestGetImage request = new RequestGetImage(imageHandle, descriptor); boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request)); if (!status) { error("Adding messages failed, connection state: " + isConnected()); @@ -227,9 +218,7 @@ public class AvrcpBipClient { return true; } - /** - * Update our client's connection state and notify of the new status - */ + /** Update our client's connection state and notify of the new status */ @VisibleForTesting void setConnectionState(int state) { int oldState = -1; @@ -237,7 +226,7 @@ public class AvrcpBipClient { oldState = mState; mState = state; } - if (oldState != state) { + if (oldState != state) { mCallback.onConnectionStateChanged(oldState, mState); } } @@ -247,9 +236,7 @@ public class AvrcpBipClient { mHandler.obtainMessage(CONNECT).sendToTarget(); } - /** - * Connects to the remote device's BIP Image Pull server - */ + /** Connects to the remote device's BIP Image Pull server */ private synchronized void connect() { debug("Connect using psm: " + mPsm); if (isConnected()) { @@ -284,9 +271,7 @@ public class AvrcpBipClient { } } - /** - * Disconnect and reconnect the OBEX session. - */ + /** Disconnect and reconnect the OBEX session. */ private synchronized void refreshObexSession() { if (mSession == null) return; @@ -359,8 +344,7 @@ public class AvrcpBipClient { private void executeRequest(BipRequest request) { if (!isConnected()) { - error("Cannot execute request " + request.toString() - + ", we're not connected"); + error("Cannot execute request " + request.toString() + ", we're not connected"); notifyCaller(request); return; } @@ -397,9 +381,7 @@ public class AvrcpBipClient { } } - /** - * Handles this AVRCP BIP Image Pull Client's requests - */ + /** Handles this AVRCP BIP Image Pull Client's requests */ private static class AvrcpBipClientHandler extends Handler { WeakReference mInst; @@ -457,27 +439,27 @@ public class AvrcpBipClient { @Override public String toString() { - return ""; + return ""; } - /** - * Print to debug if debug is enabled for this class - */ + /** Print to debug if debug is enabled for this class */ private void debug(String msg) { Log.d(TAG, "[" + mDevice + "] " + msg); } - /** - * Print to warn - */ + /** Print to warn */ private void warn(String msg) { Log.w(TAG, "[" + mDevice + "] " + msg); } - /** - * Print to error - */ + /** Print to error */ private void error(String msg) { Log.e(TAG, "[" + mDevice + "] " + msg); } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java index 8330f626c22..e0dd4f9632f 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java @@ -49,19 +49,16 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -/** - * Provides Bluetooth AVRCP Controller profile, as a service in the Bluetooth application. - */ +/** Provides Bluetooth AVRCP Controller profile, as a service in the Bluetooth application. */ public class AvrcpControllerService extends ProfileService { static final String TAG = AvrcpControllerService.class.getSimpleName(); static final int MAXIMUM_CONNECTED_DEVICES = 5; - /** - * Owned Components - */ + /** Owned Components */ private static final String ON_ERROR_SETTINGS_ACTIVITY = BluetoothPrefs.class.getCanonicalName(); + private static final String COVER_ART_PROVIDER = AvrcpCoverArtProvider.class.getCanonicalName(); /* Folder/Media Item scopes. @@ -115,18 +112,24 @@ public class AvrcpControllerService extends ProfileService { private class ImageDownloadCallback implements AvrcpCoverArtManager.Callback { @Override - public void onImageDownloadComplete(BluetoothDevice device, - AvrcpCoverArtManager.DownloadEvent event) { - Log.d(TAG, "Image downloaded [device: " + device + ", uuid: " + event.getUuid() - + ", uri: " + event.getUri()); + public void onImageDownloadComplete( + BluetoothDevice device, AvrcpCoverArtManager.DownloadEvent event) { + Log.d( + TAG, + "Image downloaded [device: " + + device + + ", uuid: " + + event.getUuid() + + ", uri: " + + event.getUri()); AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine == null) { Log.e(TAG, "No state machine found for device " + device); mCoverArtManager.removeImage(device, event.getUuid()); return; } - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_IMAGE_DOWNLOADED, - event); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_IMAGE_DOWNLOADED, event); } } @@ -195,18 +198,14 @@ public class AvrcpControllerService extends ProfileService { sService = service; } - /** - * Get the current active device - */ + /** Get the current active device */ public BluetoothDevice getActiveDevice() { synchronized (mActiveDeviceLock) { return mActiveDevice; } } - /** - * Set the current active device, notify devices of activity status - */ + /** Set the current active device, notify devices of activity status */ @VisibleForTesting boolean setActiveDevice(BluetoothDevice device) { Log.d(TAG, "setActiveDevice(device=" + device + ")"); @@ -250,7 +249,6 @@ public class AvrcpControllerService extends ProfileService { return false; } - protected void getCurrentMetadataIfNoCoverArt(BluetoothDevice device) { if (device == null) return; AvrcpControllerStateMachine stateMachine = getStateMachine(device); @@ -316,10 +314,17 @@ public class AvrcpControllerService extends ProfileService { } } - Log.d(TAG, "getContents(" + parentMediaId + "): " - + (requestedNode == null - ? "Failed to find node" - : "node=" + requestedNode + ", device=" + requestedNode.getDevice())); + Log.d( + TAG, + "getContents(" + + parentMediaId + + "): " + + (requestedNode == null + ? "Failed to find node" + : "node=" + + requestedNode + + ", device=" + + requestedNode.getDevice())); // If we don't find a node in the tree then do not have any way to browse for the contents. // Return an empty list instead. @@ -346,18 +351,21 @@ public class AvrcpControllerService extends ProfileService { */ return new BrowseResult(contents, BrowseResult.DOWNLOAD_PENDING); } - Log.d(TAG, "getContents(" + parentMediaId + "): return node, contents=" - + requestedNode.getContents()); + Log.d( + TAG, + "getContents(" + + parentMediaId + + "): return node, contents=" + + requestedNode.getContents()); return new BrowseResult(contents, BrowseResult.SUCCESS); } - @Override protected IProfileServiceBinder initBinder() { return new AvrcpControllerServiceBinder(this); } - //Binder object: Must be static class or memory leak may occur + // Binder object: Must be static class or memory leak may occur @VisibleForTesting static class AvrcpControllerServiceBinder extends IBluetoothAvrcpController.Stub implements IProfileServiceBinder { @@ -537,8 +545,8 @@ public class AvrcpControllerService extends ProfileService { item.setCoverArtUuid(mCoverArtManager.getUuidForHandle(device, handle)); } } - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED, - item); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED, item); } } @@ -550,7 +558,8 @@ public class AvrcpControllerService extends ProfileService { if (stateMachine != null) { stateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_POS_CHANGED, - songLen, currSongPosition); + songLen, + currSongPosition); } } @@ -596,7 +605,8 @@ public class AvrcpControllerService extends ProfileService { void onAvailablePlayerChanged(BluetoothDevice device) { AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED); } } @@ -617,16 +627,16 @@ public class AvrcpControllerService extends ProfileService { AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, - itemsList); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, itemsList); } } void handleGetPlayerItemsRsp(BluetoothDevice device, List itemsList) { AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, - itemsList); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, itemsList); } } @@ -634,8 +644,8 @@ public class AvrcpControllerService extends ProfileService { void handleChangeFolderRsp(BluetoothDevice device, int count) { AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_FOLDER_PATH, - count); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_FOLDER_PATH, count); } } @@ -643,8 +653,8 @@ public class AvrcpControllerService extends ProfileService { void handleSetBrowsedPlayerRsp(BluetoothDevice device, int items, int depth) { AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { - stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_SET_BROWSED_PLAYER, - items, depth); + stateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_SET_BROWSED_PLAYER, items, depth); } } @@ -697,9 +707,7 @@ public class AvrcpControllerService extends ProfileService { return true; } - /** - * Remove state machine from device map once it is no longer needed. - */ + /** Remove state machine from device map once it is no longer needed. */ public void removeStateMachine(AvrcpControllerStateMachine stateMachine) { if (stateMachine == null) { return; @@ -713,7 +721,7 @@ public class AvrcpControllerService extends ProfileService { } public List getConnectedDevices() { - return getDevicesMatchingConnectionStates(new int[]{BluetoothAdapter.STATE_CONNECTED}); + return getDevicesMatchingConnectionStates(new int[] {BluetoothAdapter.STATE_CONNECTED}); } protected AvrcpControllerStateMachine getStateMachine(BluetoothDevice device) { @@ -764,14 +772,19 @@ public class AvrcpControllerService extends ProfileService { } } } - Log.d(TAG, "getDevicesMatchingConnectionStates(states=" + Arrays.toString(states) - + "): Found " + deviceList.toString()); + Log.d( + TAG, + "getDevicesMatchingConnectionStates(states=" + + Arrays.toString(states) + + "): Found " + + deviceList.toString()); return deviceList; } synchronized int getConnectionState(BluetoothDevice device) { AvrcpControllerStateMachine stateMachine = mDeviceStateMap.get(device); - return (stateMachine == null) ? BluetoothProfile.STATE_DISCONNECTED + return (stateMachine == null) + ? BluetoothProfile.STATE_DISCONNECTED : stateMachine.getState(); } @@ -782,8 +795,8 @@ public class AvrcpControllerService extends ProfileService { ProfileService.println(sb, "Active Device = " + mActiveDevice); for (AvrcpControllerStateMachine stateMachine : mDeviceStateMap.values()) { - ProfileService.println(sb, - "==== StateMachine for " + stateMachine.getDevice() + " ===="); + ProfileService.println( + sb, "==== StateMachine for " + stateMachine.getDevice() + " ===="); stateMachine.dump(sb); } sb.append("\n BrowseTree:\n"); diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java index 0fe95238fc8..7a380bba459 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java @@ -56,18 +56,18 @@ import java.util.Set; class AvrcpControllerStateMachine extends StateMachine { static final String TAG = AvrcpControllerStateMachine.class.getSimpleName(); - //0->99 Events from Outside + // 0->99 Events from Outside public static final int CONNECT = 1; public static final int DISCONNECT = 2; public static final int ACTIVE_DEVICE_CHANGE = 3; public static final int AUDIO_FOCUS_STATE_CHANGE = 4; - //100->199 Internal Events + // 100->199 Internal Events protected static final int CLEANUP = 100; private static final int CONNECT_TIMEOUT = 101; static final int MESSAGE_INTERNAL_ABS_VOL_TIMEOUT = 102; - //200->299 Events from Native + // 200->299 Events from Native static final int STACK_EVENT = 200; static final int MESSAGE_INTERNAL_CMD_TIMEOUT = 201; @@ -90,14 +90,14 @@ class AvrcpControllerStateMachine extends StateMachine { static final int MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED = 219; static final int MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM = 220; - //300->399 Events for Browsing + // 300->399 Events for Browsing static final int MESSAGE_GET_FOLDER_ITEMS = 300; static final int MESSAGE_PLAY_ITEM = 301; static final int MSG_AVRCP_PASSTHRU = 302; static final int MSG_AVRCP_SET_SHUFFLE = 303; static final int MSG_AVRCP_SET_REPEAT = 304; - //400->499 Events for Cover Artwork + // 400->499 Events for Cover Artwork static final int MESSAGE_PROCESS_IMAGE_DOWNLOADED = 400; /* @@ -139,10 +139,10 @@ class AvrcpControllerStateMachine extends StateMachine { GetFolderList mGetFolderList = null; - //Number of items to get in a single fetch + // Number of items to get in a single fetch static final int ITEM_PAGE_SIZE = 20; static final int CMD_TIMEOUT_MILLIS = 10000; - static final int ABS_VOL_TIMEOUT_MILLIS = 1000; //1s + static final int ABS_VOL_TIMEOUT_MILLIS = 1000; // 1s AvrcpControllerStateMachine( BluetoothDevice device, @@ -215,9 +215,7 @@ class AvrcpControllerStateMachine extends StateMachine { return mDevice; } - /** - * send the connection event asynchronously - */ + /** send the connection event asynchronously */ public boolean connect(StackEvent event) { if (event.mBrowsingConnected) { onBrowsingConnected(); @@ -227,16 +225,12 @@ class AvrcpControllerStateMachine extends StateMachine { return true; } - /** - * send the Disconnect command asynchronously - */ + /** send the Disconnect command asynchronously */ public void disconnect() { sendMessage(DISCONNECT); } - /** - * Get the current playing track - */ + /** Get the current playing track */ public AvrcpItem getCurrentTrack() { return mAddressedPlayer.getCurrentTrack(); } @@ -257,13 +251,15 @@ class AvrcpControllerStateMachine extends StateMachine { * @param sb output string */ public void dump(StringBuilder sb) { - ProfileService.println(sb, "mDevice: " + mDevice + "(" - + Utils.getName(mDevice) + ") " + this.toString()); + ProfileService.println( + sb, "mDevice: " + mDevice + "(" + Utils.getName(mDevice) + ") " + this.toString()); ProfileService.println(sb, "isActive: " + isActive()); ProfileService.println(sb, "Control: " + mRemoteControlConnected); ProfileService.println(sb, "Browsing: " + mBrowsingConnected); - ProfileService.println(sb, "Cover Art: " - + (mCoverArtManager.getState(mDevice) == BluetoothProfile.STATE_CONNECTED)); + ProfileService.println( + sb, + "Cover Art: " + + (mCoverArtManager.getState(mDevice) == BluetoothProfile.STATE_CONNECTED)); ProfileService.println(sb, "Addressed Player ID: " + mAddressedPlayerId); ProfileService.println(sb, "Available Players (" + mAvailablePlayerList.size() + "): "); @@ -285,17 +281,18 @@ class AvrcpControllerStateMachine extends StateMachine { return mDevice.equals(mService.getActiveDevice()); } - /** - * Attempt to set the active status for this device - */ + /** Attempt to set the active status for this device */ public void setDeviceState(int state) { sendMessage(ACTIVE_DEVICE_CHANGE, state); } @Override protected void unhandledMessage(Message msg) { - warn("Unhandled message, state=" + getCurrentState() + "msg.what=" - + eventToString(msg.what)); + warn( + "Unhandled message, state=" + + getCurrentState() + + "msg.what=" + + eventToString(msg.what)); } synchronized void onBrowsingConnected() { @@ -322,7 +319,8 @@ class AvrcpControllerStateMachine extends StateMachine { synchronized void connectCoverArt() { // Called from "connected" state, which assumes either control or browse is connected - if (mCoverArtManager != null && mCoverArtPsm != 0 + if (mCoverArtManager != null + && mCoverArtPsm != 0 && mCoverArtManager.getState(mDevice) != BluetoothProfile.STATE_CONNECTED) { debug("Attempting to connect to AVRCP BIP, psm: " + mCoverArtPsm); mCoverArtManager.connect(mDevice, /* psm */ mCoverArtPsm); @@ -330,7 +328,8 @@ class AvrcpControllerStateMachine extends StateMachine { } synchronized void refreshCoverArt() { - if (mCoverArtManager != null && mCoverArtPsm != 0 + if (mCoverArtManager != null + && mCoverArtPsm != 0 && mCoverArtManager.getState(mDevice) == BluetoothProfile.STATE_CONNECTED) { debug("Attempting to refresh AVRCP BIP OBEX session, psm: " + mCoverArtPsm); mCoverArtManager.refreshSession(mDevice); @@ -363,8 +362,8 @@ class AvrcpControllerStateMachine extends StateMachine { } /** - * Queries the browse tree for unused uuids and removes the associated images from storage - * if the uuid is not used by the current track. + * Queries the browse tree for unused uuids and removes the associated images from storage if + * the uuid is not used by the current track. */ synchronized void removeUnusedArtworkFromBrowseTree() { debug("removeUnusedArtworkFromBrowseTree()"); @@ -384,8 +383,7 @@ class AvrcpControllerStateMachine extends StateMachine { // updates are fine at any time int scope = node.getScope(); if (scope != AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING - || (scope == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING - && isActive())) { + || (scope == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING && isActive())) { BluetoothMediaBrowserService.notifyChanged(node); } } @@ -452,7 +450,6 @@ class AvrcpControllerStateMachine extends StateMachine { } } - class Connected extends State { private int mCurrentlyHeldKey = 0; @@ -486,14 +483,15 @@ class AvrcpControllerStateMachine extends StateMachine { // If we switch to a device that is playing and we don't have focus, pause int focusState = getFocusState(); if (mAddressedPlayer.getPlaybackState().getState() - == PlaybackStateCompat.STATE_PLAYING + == PlaybackStateCompat.STATE_PLAYING && focusState == AudioManager.AUDIOFOCUS_NONE) { - sendMessage(MSG_AVRCP_PASSTHRU, + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); } } else { - sendMessage(MSG_AVRCP_PASSTHRU, - AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); mShouldSendPlayOnFocusRecovery = false; } return true; @@ -506,7 +504,8 @@ class AvrcpControllerStateMachine extends StateMachine { // Begin playing audio again if we paused the remote if (mShouldSendPlayOnFocusRecovery) { debug("Connected: Regained focus, establishing play status"); - sendMessage(MSG_AVRCP_PASSTHRU, + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PLAY); } mShouldSendPlayOnFocusRecovery = false; @@ -517,9 +516,11 @@ class AvrcpControllerStateMachine extends StateMachine { // note we should recover if (mAddressedPlayer.getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING) { - debug("Connected: Transient loss, temporarily pause with intent to " - + "recover"); - sendMessage(MSG_AVRCP_PASSTHRU, + debug( + "Connected: Transient loss, temporarily pause with intent" + + " to recover"); + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); mShouldSendPlayOnFocusRecovery = true; } @@ -531,7 +532,8 @@ class AvrcpControllerStateMachine extends StateMachine { debug("Connected: Lost focus, send a courtesy pause"); if (mAddressedPlayer.getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING) { - sendMessage(MSG_AVRCP_PASSTHRU, + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); } mShouldSendPlayOnFocusRecovery = false; @@ -541,8 +543,7 @@ class AvrcpControllerStateMachine extends StateMachine { case MESSAGE_PROCESS_SET_ABS_VOL_CMD: removeMessages(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT); - sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT, - ABS_VOL_TIMEOUT_MILLIS); + sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT, ABS_VOL_TIMEOUT_MILLIS); handleAbsVolumeRequest(msg.arg1, msg.arg2); return true; @@ -560,7 +561,7 @@ class AvrcpControllerStateMachine extends StateMachine { return true; case MESSAGE_PLAY_ITEM: - //Set Addressed Player + // Set Addressed Player processPlayItem((BrowseTree.BrowseNode) msg.obj); return true; @@ -593,12 +594,13 @@ class AvrcpControllerStateMachine extends StateMachine { return true; case MESSAGE_PROCESS_PLAY_STATUS_CHANGED: - debug("Connected: Playback status = " - + AvrcpControllerUtils.playbackStateToString(msg.arg1)); + debug( + "Connected: Playback status = " + + AvrcpControllerUtils.playbackStateToString(msg.arg1)); mAddressedPlayer.setPlayStatus(msg.arg1); if (!isActive()) { - sendMessage(MSG_AVRCP_PASSTHRU, - AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); return true; } @@ -606,18 +608,19 @@ class AvrcpControllerStateMachine extends StateMachine { int focusState = getFocusState(); if (focusState == AudioManager.ERROR) { - sendMessage(MSG_AVRCP_PASSTHRU, - AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); return true; } if (mAddressedPlayer.getPlaybackState().getState() - == PlaybackStateCompat.STATE_PLAYING + == PlaybackStateCompat.STATE_PLAYING && focusState == AudioManager.AUDIOFOCUS_NONE) { if (shouldRequestFocus()) { mSessionCallbacks.onPrepare(); } else { - sendMessage(MSG_AVRCP_PASSTHRU, + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); } } @@ -633,16 +636,20 @@ class AvrcpControllerStateMachine extends StateMachine { case MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED: int oldAddressedPlayerId = mAddressedPlayerId; mAddressedPlayerId = msg.arg1; - debug("Connected: AddressedPlayer changed " + oldAddressedPlayerId + " -> " - + mAddressedPlayerId); + debug( + "Connected: AddressedPlayer changed " + + oldAddressedPlayerId + + " -> " + + mAddressedPlayerId); // The now playing list is tied to the addressed player by specification in // AVRCP 5.9.1. A new addressed player means our now playing content is now // invalid mBrowseTree.mNowPlayingNode.setCached(false); if (isActive()) { - debug("Connected: Addressed player change has invalidated the now playing" - + " list"); + debug( + "Connected: Addressed player change has invalidated the now playing" + + " list"); BluetoothMediaBrowserService.notifyChanged(mBrowseTree.mNowPlayingNode); } removeUnusedArtworkFromBrowseTree(); @@ -652,8 +659,9 @@ class AvrcpControllerStateMachine extends StateMachine { // isn't there then we need to ensure that a default Addressed AvrcpPlayer is // created to represent it. It can be updated if/when we do fetch the player. if (!mAvailablePlayerList.contains(mAddressedPlayerId)) { - debug("Connected: Available player set does not contain the new Addressed" - + " Player"); + debug( + "Connected: Available player set does not contain the new Addressed" + + " Player"); AvrcpPlayer.Builder apb = new AvrcpPlayer.Builder(); apb.setDevice(mDevice); apb.setPlayerId(mAddressedPlayerId); @@ -738,7 +746,6 @@ class AvrcpControllerStateMachine extends StateMachine { default: return super.processMessage(msg); } - } private void processPlayItem(BrowseTree.BrowseNode node) { @@ -750,8 +757,11 @@ class AvrcpControllerStateMachine extends StateMachine { } private synchronized void passThru(int cmd) { - debug("Connected: Send passthrough command, id= " + cmd + ", key=" - + AvrcpControllerUtils.passThruIdToString(cmd)); + debug( + "Connected: Send passthrough command, id= " + + cmd + + ", key=" + + AvrcpControllerUtils.passThruIdToString(cmd)); // Some keys should be held until the next event. if (mCurrentlyHeldKey != 0) { mNativeInterface.sendPassThroughCommand( @@ -865,8 +875,7 @@ class AvrcpControllerStateMachine extends StateMachine { case MESSAGE_PROCESS_GET_FOLDER_ITEMS: ArrayList folderList = (ArrayList) msg.obj; int endIndicator = mBrowseNode.getExpectedChildren() - 1; - debug("GetFolderList: End " + endIndicator - + " received " + folderList.size()); + debug("GetFolderList: End " + endIndicator + " received " + folderList.size()); // Queue up image download if the item has an image and we don't have it yet // Only do this if the feature is enabled. @@ -884,7 +893,8 @@ class AvrcpControllerStateMachine extends StateMachine { debug("GetFolderList: Added " + newSize + " items to the browse tree"); notifyChanged(mBrowseNode); - if (mBrowseNode.getChildrenCount() >= endIndicator || folderList.size() == 0 + if (mBrowseNode.getChildrenCount() >= endIndicator + || folderList.size() == 0 || mAbort) { // If we have fetched all the elements or if the remotes sends us 0 elements // (which can lead us into a loop since mCurrInd does not proceed) we simply @@ -955,12 +965,14 @@ class AvrcpControllerStateMachine extends StateMachine { // will replace it and re-download metadata. If not, we'll re-use the old // player to save the metadata queries. if (!mAvailablePlayerList.contains(mAddressedPlayerId)) { - debug("GetFolderList: Available player set doesn't contain the" - + " addressed player"); + debug( + "GetFolderList: Available player set doesn't contain the" + + " addressed player"); mAvailablePlayerList.put(mAddressedPlayerId, mAddressedPlayer); } else { - debug("GetFolderList: Update addressed player with new available player" - + " metadata"); + debug( + "GetFolderList: Update addressed player with new available" + + " player metadata"); mAddressedPlayer = mAvailablePlayerList.get(mAddressedPlayerId); mNativeInterface.getCurrentMetadata(mDeviceAddress); mNativeInterface.getPlaybackState(mDeviceAddress); @@ -1004,8 +1016,11 @@ class AvrcpControllerStateMachine extends StateMachine { mAbort = true; } deferMessage(msg); - debug("GetFolderList: Enqueue new request for node=" + requested - + ", abort=" + mAbort); + debug( + "GetFolderList: Enqueue new request for node=" + + requested + + ", abort=" + + mAbort); } else { debug("GetFolderList: Ignore request, node=" + requested); } @@ -1013,8 +1028,9 @@ class AvrcpControllerStateMachine extends StateMachine { default: // All of these messages should be handled by parent state immediately. - debug("GetFolderList: Passing message to parent state, type=" - + eventToString(msg.what)); + debug( + "GetFolderList: Passing message to parent state, type=" + + eventToString(msg.what)); return false; } return true; @@ -1024,14 +1040,13 @@ class AvrcpControllerStateMachine extends StateMachine { * shouldAbort calculates the cases where fetching the current directory is no longer * necessary. * - * @return true: a new folder in the same scope - * a new player while fetching contents of a folder - * false: other cases, specifically Now Playing while fetching a folder + * @return true: a new folder in the same scope a new player while fetching contents of a + * folder false: other cases, specifically Now Playing while fetching a folder */ private boolean shouldAbort(int currentScope, int fetchScope) { if ((currentScope == fetchScope) || (currentScope == AvrcpControllerService.BROWSE_SCOPE_VFS - && fetchScope == AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST)) { + && fetchScope == AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST)) { return true; } return false; @@ -1039,11 +1054,23 @@ class AvrcpControllerStateMachine extends StateMachine { private void fetchContents(BrowseTree.BrowseNode target) { int start = target.getChildrenCount(); - int end = Math.min(target.getExpectedChildren(), target.getChildrenCount() - + ITEM_PAGE_SIZE) - 1; - debug("GetFolderList: fetchContents(title=" + target.getID() + ", scope=" - + target.getScope() + ", start=" + start + ", end=" + end + ", expected=" - + target.getExpectedChildren() + ")"); + int end = + Math.min( + target.getExpectedChildren(), + target.getChildrenCount() + ITEM_PAGE_SIZE) + - 1; + debug( + "GetFolderList: fetchContents(title=" + + target.getID() + + ", scope=" + + target.getScope() + + ", start=" + + start + + ", end=" + + end + + ", expected=" + + target.getExpectedChildren() + + ")"); switch (target.getScope()) { case AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST: mNativeInterface.getPlayerList(mDeviceAddress, start, end); @@ -1055,8 +1082,7 @@ class AvrcpControllerStateMachine extends StateMachine { mNativeInterface.getFolderList(mDeviceAddress, start, end); break; default: - error("GetFolderList: Scope " + target.getScope() - + " cannot be handled here."); + error("GetFolderList: Scope " + target.getScope() + " cannot be handled here."); } } @@ -1073,10 +1099,11 @@ class AvrcpControllerStateMachine extends StateMachine { */ private void navigateToFolderOrRetrieve(BrowseTree.BrowseNode target) { mNextStep = mBrowseTree.getNextStepToFolder(target); - debug("GetFolderList: NAVIGATING From " - + mBrowseTree.getCurrentBrowsedFolder().toString() - + ", NAVIGATING Toward " - + target.toString()); + debug( + "GetFolderList: NAVIGATING From " + + mBrowseTree.getCurrentBrowsedFolder().toString() + + ", NAVIGATING Toward " + + target.toString()); if (mNextStep == null) { return; } else if (target.equals(mBrowseTree.mNowPlayingNode) @@ -1142,9 +1169,9 @@ class AvrcpControllerStateMachine extends StateMachine { } /** - * Handle a request to align our local volume with the volume of a remote device. If - * we're assuming the source volume is fixed then a response of ABS_VOL_MAX will always be - * sent and no volume adjustment action will be taken on the sink side. + * Handle a request to align our local volume with the volume of a remote device. If we're + * assuming the source volume is fixed then a response of ABS_VOL_MAX will always be sent and no + * volume adjustment action will be taken on the sink side. * * @param absVol A volume level based on a domain of [0, ABS_VOL_MAX] * @param label Volume notification label @@ -1156,8 +1183,7 @@ class AvrcpControllerStateMachine extends StateMachine { absVol = ABS_VOL_BASE; } else { removeMessages(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT); - sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT, - ABS_VOL_TIMEOUT_MILLIS); + sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT, ABS_VOL_TIMEOUT_MILLIS); setAbsVolume(absVol); } mNativeInterface.sendAbsVolRsp(mDeviceAddress, absVol, label); @@ -1188,8 +1214,8 @@ class AvrcpControllerStateMachine extends StateMachine { * no action is required */ if (reqLocalVolume != curLocalVolume) { - mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, reqLocalVolume, - AudioManager.FLAG_SHOW_UI); + mAudioManager.setStreamVolume( + AudioManager.STREAM_MUSIC, reqLocalVolume, AudioManager.FLAG_SHOW_UI); } } @@ -1204,8 +1230,7 @@ class AvrcpControllerStateMachine extends StateMachine { } private boolean shouldDownloadBrowsedImages() { - return mService.getResources() - .getBoolean(R.bool.avrcp_controller_cover_art_browsed_images); + return mService.getResources().getBoolean(R.bool.avrcp_controller_cover_art_browsed_images); } private void downloadImageIfNeeded(AvrcpItem track) { @@ -1231,112 +1256,119 @@ class AvrcpControllerStateMachine extends StateMachine { return focusState; } - MediaSessionCompat.Callback mSessionCallbacks = new MediaSessionCompat.Callback() { - @Override - public void onPlay() { - debug("onPlay"); - onPrepare(); - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PLAY); - } - - @Override - public void onPause() { - debug("onPause"); - // If we receive a local pause/stop request and send it out then we need to signal that - // the intent is to stay paused if we recover focus from a transient loss - if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { - debug("Received a pause while in a transient loss. Do not recover anymore."); - mShouldSendPlayOnFocusRecovery = false; - } - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); - } + MediaSessionCompat.Callback mSessionCallbacks = + new MediaSessionCompat.Callback() { + @Override + public void onPlay() { + debug("onPlay"); + onPrepare(); + sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PLAY); + } - @Override - public void onSkipToNext() { - debug("onSkipToNext"); - onPrepare(); - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FORWARD); - } + @Override + public void onPause() { + debug("onPause"); + // If we receive a local pause/stop request and send it out then we need to + // signal that + // the intent is to stay paused if we recover focus from a transient loss + if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { + debug( + "Received a pause while in a transient loss. Do not recover" + + " anymore."); + mShouldSendPlayOnFocusRecovery = false; + } + sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); + } - @Override - public void onSkipToPrevious() { - debug("onSkipToPrevious"); - onPrepare(); - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_BACKWARD); - } + @Override + public void onSkipToNext() { + debug("onSkipToNext"); + onPrepare(); + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FORWARD); + } - @Override - public void onSkipToQueueItem(long id) { - debug("onSkipToQueueItem(id=" + id + ")"); - onPrepare(); - BrowseTree.BrowseNode node = mBrowseTree.getTrackFromNowPlayingList((int) id); - if (node != null) { - sendMessage(MESSAGE_PLAY_ITEM, node); - } - } + @Override + public void onSkipToPrevious() { + debug("onSkipToPrevious"); + onPrepare(); + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_BACKWARD); + } - @Override - public void onStop() { - debug("onStop"); - // If we receive a local pause/stop request and send it out then we need to signal that - // the intent is to stay paused if we recover focus from a transient loss - if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { - debug("Received a stop while in a transient loss. Do not recover anymore."); - mShouldSendPlayOnFocusRecovery = false; - } - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_STOP); - } + @Override + public void onSkipToQueueItem(long id) { + debug("onSkipToQueueItem(id=" + id + ")"); + onPrepare(); + BrowseTree.BrowseNode node = mBrowseTree.getTrackFromNowPlayingList((int) id); + if (node != null) { + sendMessage(MESSAGE_PLAY_ITEM, node); + } + } - @Override - public void onPrepare() { - debug("onPrepare"); - A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService(); - if (a2dpSinkService != null) { - a2dpSinkService.requestAudioFocus(mDevice, true); - } - } + @Override + public void onStop() { + debug("onStop"); + // If we receive a local pause/stop request and send it out then we need to + // signal that + // the intent is to stay paused if we recover focus from a transient loss + if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { + debug("Received a stop while in a transient loss. Do not recover anymore."); + mShouldSendPlayOnFocusRecovery = false; + } + sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_STOP); + } - @Override - public void onRewind() { - debug("onRewind"); - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_REWIND); - } + @Override + public void onPrepare() { + debug("onPrepare"); + A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService(); + if (a2dpSinkService != null) { + a2dpSinkService.requestAudioFocus(mDevice, true); + } + } - @Override - public void onFastForward() { - debug("onFastForward"); - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FF); - } + @Override + public void onRewind() { + debug("onRewind"); + sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_REWIND); + } - @Override - public void onPlayFromMediaId(String mediaId, Bundle extras) { - debug("onPlayFromMediaId(mediaId=" + mediaId + ")"); - // Play the item if possible. - onPrepare(); - BrowseTree.BrowseNode node = mBrowseTree.findBrowseNodeByID(mediaId); - if (node != null) { - // node was found on this bluetooth device - sendMessage(MESSAGE_PLAY_ITEM, node); - } else { - // node was not found on this device, pause here, and play on another device - sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); - mService.playItem(mediaId); - } - } + @Override + public void onFastForward() { + debug("onFastForward"); + sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FF); + } - @Override - public void onSetRepeatMode(int repeatMode) { - debug("onSetRepeatMode(repeatMode=" + repeatMode + ")"); - sendMessage(MSG_AVRCP_SET_REPEAT, repeatMode); - } + @Override + public void onPlayFromMediaId(String mediaId, Bundle extras) { + debug("onPlayFromMediaId(mediaId=" + mediaId + ")"); + // Play the item if possible. + onPrepare(); + BrowseTree.BrowseNode node = mBrowseTree.findBrowseNodeByID(mediaId); + if (node != null) { + // node was found on this bluetooth device + sendMessage(MESSAGE_PLAY_ITEM, node); + } else { + // node was not found on this device, pause here, and play on another device + sendMessage( + MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); + mService.playItem(mediaId); + } + } - @Override - public void onSetShuffleMode(int shuffleMode) { - debug("onSetShuffleMode(shuffleMode=" + shuffleMode + ")"); - sendMessage(MSG_AVRCP_SET_SHUFFLE, shuffleMode); + @Override + public void onSetRepeatMode(int repeatMode) { + debug("onSetRepeatMode(repeatMode=" + repeatMode + ")"); + sendMessage(MSG_AVRCP_SET_REPEAT, repeatMode); + } - } - }; + @Override + public void onSetShuffleMode(int shuffleMode) { + debug("onSetShuffleMode(shuffleMode=" + shuffleMode + ")"); + sendMessage(MSG_AVRCP_SET_SHUFFLE, shuffleMode); + } + }; protected void broadcastConnectionStateChanged(int currentState) { if (mMostRecentState == currentState) { diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java index 017ecc44554..f8e6308ebfa 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java @@ -18,14 +18,10 @@ package com.android.bluetooth.avrcpcontroller; import android.support.v4.media.session.PlaybackStateCompat; -/** - * A package global set of utilities for the AVRCP Controller implementation to leverage - */ +/** A package global set of utilities for the AVRCP Controller implementation to leverage */ public final class AvrcpControllerUtils { - /** - * Convert an AVRCP Passthrough command id to a human readable version of the key - */ + /** Convert an AVRCP Passthrough command id to a human readable version of the key */ public static String passThruIdToString(int id) { StringBuilder sb = new StringBuilder(); switch (id) { @@ -64,9 +60,7 @@ public final class AvrcpControllerUtils { return sb.toString(); } - /** - * Convert an entire PlaybackStateCompat to a string that contains human readable states - */ + /** Convert an entire PlaybackStateCompat to a string that contains human readable states */ public static String playbackStateCompatToString(PlaybackStateCompat playbackState) { if (playbackState == null) { return null; @@ -87,9 +81,7 @@ public final class AvrcpControllerUtils { return sb.toString(); } - /** - * Convert a playback state constant to a human readable version of the state - */ + /** Convert a playback state constant to a human readable version of the state */ public static String playbackStateToString(int playbackState) { StringBuilder sb = new StringBuilder(); switch (playbackState) { diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java index b251ab000be..e0331f6a785 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java @@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentHashMap; * Manager of all AVRCP Controller connections to remote devices' BIP servers for retrieving cover * art. * - * When given an image handle and device, this manager will negotiate the downloaded image + *

When given an image handle and device, this manager will negotiate the downloaded image * properties, download the image, and place it into a Content Provider for others to retrieve from */ public class AvrcpCoverArtManager { @@ -60,13 +60,16 @@ public class AvrcpCoverArtManager { public class DownloadEvent { final String mImageUuid; final Uri mUri; + public DownloadEvent(String uuid, Uri uri) { mImageUuid = uuid; mUri = uri; } + public String getUuid() { return mImageUuid; } + public Uri getUri() { return mUri; } @@ -83,10 +86,10 @@ public class AvrcpCoverArtManager { } /** - * A thread-safe collection of BIP connection specific imformation meant to be cleared each - * time a client disconnects from the Target's BIP OBEX server. + * A thread-safe collection of BIP connection specific imformation meant to be cleared each time + * a client disconnects from the Target's BIP OBEX server. * - * Currently contains the mapping of image handles seen to assigned UUIDs. + *

Currently contains the mapping of image handles seen to assigned UUIDs. */ private class AvrcpBipSession { private Map mUuids = new ConcurrentHashMap<>(1); /* handle -> UUID */ @@ -118,7 +121,7 @@ public class AvrcpCoverArtManager { /** * Validate an image handle meets the AVRCP and BIP specifications * - * By the BIP specification that AVRCP uses, "Image handles are 7 character long strings + *

By the BIP specification that AVRCP uses, "Image handles are 7 character long strings * containing only the digits 0 to 9." * * @return True if the input string is a valid image handle @@ -137,8 +140,7 @@ public class AvrcpCoverArtManager { mService = service; mCoverArtStorage = new AvrcpCoverArtStorage(mService); mCallback = callback; - mDownloadScheme = - SystemProperties.get(AVRCP_CONTROLLER_COVER_ART_SCHEME, SCHEME_THUMBNAIL); + mDownloadScheme = SystemProperties.get(AVRCP_CONTROLLER_COVER_ART_SCHEME, SCHEME_THUMBNAIL); mCoverArtStorage.clear(); } @@ -199,7 +201,7 @@ public class AvrcpCoverArtManager { /** * Cleanup all cover art related resources * - * Please call when you've committed to shutting down the service. + *

Please call when you've committed to shutting down the service. */ public synchronized void cleanup() { debug("Clean up and shutdown"); @@ -220,21 +222,21 @@ public class AvrcpCoverArtManager { return client.getState(); } - /** + /** * Get the UUID for an image handle coming from a particular device. * - * This UUID is used to request and track downloads. + *

This UUID is used to request and track downloads. * - * Image handles are only good for the life of the BIP client. Since this connection is torn - * down frequently by specification, we have a layer of indirection to the images in the form - * of an UUID. This UUID will allow images to be identified outside the connection lifecycle. - * It also allows handles to be reused by the target in ways that won't impact image consumer's + *

Image handles are only good for the life of the BIP client. Since this connection is torn + * down frequently by specification, we have a layer of indirection to the images in the form of + * an UUID. This UUID will allow images to be identified outside the connection lifecycle. It + * also allows handles to be reused by the target in ways that won't impact image consumer's * cache schemes. * * @param device The Bluetooth device you want a handle from * @param handle The image handle you want a UUID for * @return A string UUID by which the handle can be identified during the life of the BIP - * connection. + * connection. */ public String getUuidForHandle(BluetoothDevice device, String handle) { AvrcpBipSession session = getSession(device); @@ -245,7 +247,7 @@ public class AvrcpCoverArtManager { /** * Get the handle thats associated with a particular UUID. * - * The handle must have been seen during this connection. + *

The handle must have been seen during this connection. * * @param device The Bluetooth device you want a handle from * @param uuid The UUID you want the associated handle for @@ -280,16 +282,15 @@ public class AvrcpCoverArtManager { /** * Download an image from a remote device and make it findable via the given uri * - * Downloading happens in three steps: - * 1) Get the available image formats by requesting the Image Properties - * 2) Determine the specific format we want the image in and turn it into an image descriptor - * 3) Get the image using the chosen descriptor + *

Downloading happens in three steps: 1) Get the available image formats by requesting the + * Image Properties 2) Determine the specific format we want the image in and turn it into an + * image descriptor 3) Get the image using the chosen descriptor * - * Getting image properties and the image are both asynchronous in nature. + *

Getting image properties and the image are both asynchronous in nature. * * @param device The remote Bluetooth device you wish to download from * @param imageUuid The UUID associated with the image you wish to download. This will be - * translated into an image handle. + * translated into an image handle. * @return A Uri that will be assign to the image once the download is complete */ public Uri downloadImage(BluetoothDevice device, String imageUuid) { @@ -365,8 +366,8 @@ public class AvrcpCoverArtManager { * Determines our preferred download descriptor from the list of available image download * formats presented in the image properties object. * - * Our goal is ensure the image arrives in a format Android can consume and to minimize transfer - * size if possible. + *

Our goal is ensure the image arrives in a format Android can consume and to minimize + * transfer size if possible. * * @param properties The set of available formats and image is downloadable in * @return A descriptor containing the desirable download format @@ -377,10 +378,10 @@ public class AvrcpCoverArtManager { } BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder(); switch (mDownloadScheme) { - // BIP Specification says a blank/null descriptor signals to pull the native format + // BIP Specification says a blank/null descriptor signals to pull the native format case SCHEME_NATIVE: return null; - // AVRCP 1.6.2 defined "thumbnail" size is guaranteed so we'll do that for now + // AVRCP 1.6.2 defined "thumbnail" size is guaranteed so we'll do that for now case SCHEME_THUMBNAIL: default: builder.setEncoding(BipEncoding.JPEG); @@ -390,9 +391,7 @@ public class AvrcpCoverArtManager { return builder.build(); } - /** - * Callback for facilitating image download - */ + /** Callback for facilitating image download */ class BipClientCallback implements AvrcpBipClient.Callback { final BluetoothDevice mDevice; @@ -422,11 +421,15 @@ public class AvrcpCoverArtManager { } @Override - public void onGetImagePropertiesComplete(int status, String imageHandle, - BipImageProperties properties) { + public void onGetImagePropertiesComplete( + int status, String imageHandle, BipImageProperties properties) { if (status != ResponseCodes.OBEX_HTTP_OK || properties == null) { - warn(mDevice + ": GetImageProperties() failed - Handle: " + imageHandle - + ", Code: " + status); + warn( + mDevice + + ": GetImageProperties() failed - Handle: " + + imageHandle + + ", Code: " + + status); return; } BipImageDescriptor descriptor = determineImageDescriptor(properties); @@ -434,8 +437,11 @@ public class AvrcpCoverArtManager { AvrcpBipClient client = getClient(mDevice); if (client == null) { - warn(mDevice + ": Could not getImage() for " + imageHandle - + " because client has disconnected."); + warn( + mDevice + + ": Could not getImage() for " + + imageHandle + + " because client has disconnected."); return; } client.getImage(imageHandle, descriptor); @@ -444,13 +450,23 @@ public class AvrcpCoverArtManager { @Override public void onGetImageComplete(int status, String imageHandle, BipImage image) { if (status != ResponseCodes.OBEX_HTTP_OK) { - warn(mDevice + ": GetImage() failed - Handle: " + imageHandle - + ", Code: " + status); + warn( + mDevice + + ": GetImage() failed - Handle: " + + imageHandle + + ", Code: " + + status); return; } String imageUuid = getUuidForHandle(mDevice, imageHandle); - debug(mDevice + ": Received image data for handle: " + imageHandle - + ", uuid: " + imageUuid + ", image: " + image); + debug( + mDevice + + ": Received image data for handle: " + + imageHandle + + ", uuid: " + + imageUuid + + ", image: " + + image); Uri uri = mCoverArtStorage.addImage(mDevice, imageUuid, image.getImage()); if (uri == null) { error("Could not store downloaded image"); @@ -479,23 +495,17 @@ public class AvrcpCoverArtManager { return s; } - /** - * Print to debug if debug is enabled for this class - */ + /** Print to debug if debug is enabled for this class */ private void debug(String msg) { Log.d(TAG, msg); } - /** - * Print to warn - */ + /** Print to warn */ private void warn(String msg) { Log.w(TAG, msg); } - /** - * Print to error - */ + /** Print to error */ private void error(String msg) { Log.e(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java index ea73cf8b4d7..71728e29db3 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java @@ -33,15 +33,15 @@ import java.io.IOException; /** * A provider of downloaded cover art images. * - * Cover art images are downloaded from remote devices and are promised to be "good" for the life of - * a connection. + *

Cover art images are downloaded from remote devices and are promised to be "good" for the life + * of a connection. * - * Android applications are provided a Uri with their MediaMetadata and MediaItem objects that + *

Android applications are provided a Uri with their MediaMetadata and MediaItem objects that * points back to this provider. Uris are in the following format: * - * content://com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider// + *

content://com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider// * - * It's expected by the Media framework that artwork at URIs will be available using the + *

It's expected by the Media framework that artwork at URIs will be available using the * ContentResolver#openInputStream and BitmapFactory#decodeStream functions. Our provider must * enable that usage pattern. */ @@ -50,8 +50,7 @@ public class AvrcpCoverArtProvider extends ContentProvider { private BluetoothAdapter mAdapter; - public AvrcpCoverArtProvider() { - } + public AvrcpCoverArtProvider() {} static final String AUTHORITY = "com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider"; static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY); @@ -65,9 +64,12 @@ public class AvrcpCoverArtProvider extends ContentProvider { */ public static Uri getImageUri(BluetoothDevice device, String imageUuid) { if (device == null || imageUuid == null || "".equals(imageUuid)) return null; - Uri uri = CONTENT_URI.buildUpon().appendQueryParameter("device", device.getAddress()) - .appendQueryParameter("uuid", imageUuid) - .build(); + Uri uri = + CONTENT_URI + .buildUpon() + .appendQueryParameter("device", device.getAddress()) + .appendQueryParameter("uuid", imageUuid) + .build(); debug("getImageUri -> " + uri.toString()); return uri; } @@ -97,19 +99,20 @@ public class AvrcpCoverArtProvider extends ContentProvider { } final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); - Thread transferThread = new Thread() { - public void run() { - try { - FileOutputStream fout = - new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]); - image.compress(Bitmap.CompressFormat.PNG, 100, fout); - fout.flush(); - fout.close(); - } catch (IOException e) { - /* Something bad must have happened writing the image data */ - } - } - }; + Thread transferThread = + new Thread() { + public void run() { + try { + FileOutputStream fout = + new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]); + image.compress(Bitmap.CompressFormat.PNG, 100, fout); + fout.flush(); + fout.close(); + } catch (IOException e) { + /* Something bad must have happened writing the image data */ + } + } + }; transferThread.start(); return pipe[0]; } @@ -150,7 +153,11 @@ public class AvrcpCoverArtProvider extends ContentProvider { } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { return null; } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java index 765112ff69e..402134098ad 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java @@ -25,9 +25,7 @@ import android.util.Log; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -/** - * An abstraction of the cover art image storage mechanism. - */ +/** An abstraction of the cover art image storage mechanism. */ public class AvrcpCoverArtStorage { private static final String TAG = AvrcpCoverArtStorage.class.getSimpleName(); @@ -42,9 +40,7 @@ public class AvrcpCoverArtStorage { private final Map> mDeviceImages = new ConcurrentHashMap<>(1); - /** - * Create and initialize this Cover Art storage interface - */ + /** Create and initialize this Cover Art storage interface */ public AvrcpCoverArtStorage(Context context) { mContext = context; } @@ -141,9 +137,7 @@ public class AvrcpCoverArtStorage { mDeviceImages.remove(device); } - /** - * Clear the entirety of storage - */ + /** Clear the entirety of storage */ public void clear() { debug("Clearing all images"); mDeviceImages.clear(); diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java index 59fbd604ad2..7d248b00581 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java @@ -29,7 +29,7 @@ import java.util.Objects; /** * An object representing a single item returned from an AVRCP folder listing in the VFS scope. * - * This object knows how to turn itself into each of the Android Media Framework objects so the + *

This object knows how to turn itself into each of the Android Media Framework objects so the * metadata can easily be shared with the system. */ public class AvrcpItem { @@ -94,8 +94,7 @@ public class AvrcpItem { // Our own internal Uri value that points to downloaded cover art image private Uri mImageUri; - private AvrcpItem() { - } + private AvrcpItem() {} public BluetoothDevice getDevice() { return mDevice; @@ -177,9 +176,7 @@ public class AvrcpItem { mImageUri = uri; } - /** - * Convert this item an Android Media Framework MediaMetadata - */ + /** Convert this item an Android Media Framework MediaMetadata */ public MediaMetadataCompat toMediaMetadata() { MediaMetadataCompat.Builder metaDataBuilder = new MediaMetadataCompat.Builder(); Uri coverArtUri = getCoverArtLocation(); @@ -202,9 +199,7 @@ public class AvrcpItem { return metaDataBuilder.build(); } - /** - * Convert this item an Android Media Framework MediaItem - */ + /** Convert this item an Android Media Framework MediaItem */ public MediaItem toMediaItem() { MediaDescriptionCompat.Builder descriptionBuilder = new MediaDescriptionCompat.Builder(); @@ -237,12 +232,35 @@ public class AvrcpItem { @Override public String toString() { - return "AvrcpItem{mUuid=" + mUuid + ", mUid=" + mUid + ", mItemType=" + mItemType - + ", mType=" + mType + ", mDisplayableName=" + mDisplayableName - + ", mTitle=" + mTitle + " mPlayingTime=" + mPlayingTime + " mTrack=" - + mTrackNumber + "/" + mTotalNumberOfTracks + ", mPlayable=" + mPlayable - + ", mBrowsable=" + mBrowsable + ", mCoverArtHandle=" + getCoverArtHandle() - + ", mImageUuid=" + mImageUuid + ", mImageUri" + mImageUri + "}"; + return "AvrcpItem{mUuid=" + + mUuid + + ", mUid=" + + mUid + + ", mItemType=" + + mItemType + + ", mType=" + + mType + + ", mDisplayableName=" + + mDisplayableName + + ", mTitle=" + + mTitle + + " mPlayingTime=" + + mPlayingTime + + " mTrack=" + + mTrackNumber + + "/" + + mTotalNumberOfTracks + + ", mPlayable=" + + mPlayable + + ", mBrowsable=" + + mBrowsable + + ", mCoverArtHandle=" + + getCoverArtHandle() + + ", mImageUuid=" + + mImageUuid + + ", mImageUri" + + mImageUri + + "}"; } @Override @@ -275,9 +293,7 @@ public class AvrcpItem { && Objects.equals(mImageUri, other.getCoverArtLocation()); } - /** - * Builder for an AvrcpItem - */ + /** Builder for an AvrcpItem */ public static class Builder { private static final String TAG = "AvrcpItem.Builder"; @@ -298,7 +314,7 @@ public class AvrcpItem { * item attributes * * @param attrIds The array of AVRCP specification defined IDs in the order they match to - * the value string attrMap + * the value string attrMap * @param attrMap The mapped values for each ID * @return This object so you can continue building */ @@ -351,7 +367,7 @@ public class AvrcpItem { /** * Set the item type for the AvrcpItem you are building * - * Type can be one of PLAYER, FOLDER, or MEDIA + *

Type can be one of PLAYER, FOLDER, or MEDIA * * @param itemType The item type as an AvrcpItem.* type value * @return This object, so you can continue building @@ -364,7 +380,7 @@ public class AvrcpItem { /** * Set the type for the AvrcpItem you are building * - * This is the type of the PLAYER, FOLDER, or MEDIA item. + *

This is the type of the PLAYER, FOLDER, or MEDIA item. * * @param type The type as one of the AvrcpItem.MEDIA_* or FOLDER_* types * @return This object, so you can continue building diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java index 2922f2c8179..7a2800eb3e6 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java @@ -73,8 +73,8 @@ class AvrcpPlayer { mId = id; mName = name; mPlayerFeatures = Arrays.copyOf(playerFeatures, playerFeatures.length); - PlaybackStateCompat.Builder playbackStateBuilder = new PlaybackStateCompat.Builder() - .setActions(mAvailableActions); + PlaybackStateCompat.Builder playbackStateBuilder = + new PlaybackStateCompat.Builder().setActions(mAvailableActions); mPlaybackStateCompat = playbackStateBuilder.build(); updateAvailableActions(); setPlayStatus(playStatus); @@ -94,9 +94,10 @@ class AvrcpPlayer { public void setPlayTime(int playTime) { mPlayTime = playTime; - mPlaybackStateCompat = new PlaybackStateCompat.Builder(mPlaybackStateCompat).setState( - mPlayStatus, mPlayTime, - mPlaySpeed).build(); + mPlaybackStateCompat = + new PlaybackStateCompat.Builder(mPlaybackStateCompat) + .setState(mPlayStatus, mPlayTime, mPlaySpeed) + .build(); } public long getPlayTime() { @@ -105,8 +106,10 @@ class AvrcpPlayer { public void setPlayStatus(int playStatus) { if (mPlayTime != PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN) { - mPlayTime += mPlaySpeed * (SystemClock.elapsedRealtime() - - mPlaybackStateCompat.getLastPositionUpdateTime()); + mPlayTime += + mPlaySpeed + * (SystemClock.elapsedRealtime() + - mPlaybackStateCompat.getLastPositionUpdateTime()); } mPlayStatus = playStatus; switch (mPlayStatus) { @@ -127,9 +130,10 @@ class AvrcpPlayer { break; } - mPlaybackStateCompat = new PlaybackStateCompat.Builder(mPlaybackStateCompat).setState( - mPlayStatus, mPlayTime, - mPlaySpeed).build(); + mPlaybackStateCompat = + new PlaybackStateCompat.Builder(mPlaybackStateCompat) + .setState(mPlayStatus, mPlayTime, mPlaySpeed) + .build(); } public void setSupportedPlayerApplicationSettings( @@ -143,10 +147,12 @@ class AvrcpPlayer { Log.d(TAG, "Play application settings changed, settings=" + playerApplicationSettings); mCurrentPlayerApplicationSettings = playerApplicationSettings; MediaSessionCompat session = BluetoothMediaBrowserService.getSession(); - session.setRepeatMode(mCurrentPlayerApplicationSettings.getSetting( - PlayerApplicationSettings.REPEAT_STATUS)); - session.setShuffleMode(mCurrentPlayerApplicationSettings.getSetting( - PlayerApplicationSettings.SHUFFLE_STATUS)); + session.setRepeatMode( + mCurrentPlayerApplicationSettings.getSetting( + PlayerApplicationSettings.REPEAT_STATUS)); + session.setShuffleMode( + mCurrentPlayerApplicationSettings.getSetting( + PlayerApplicationSettings.SHUFFLE_STATUS)); } public int getPlayStatus() { @@ -171,9 +177,10 @@ class AvrcpPlayer { public synchronized void updateCurrentTrack(AvrcpItem update) { if (update != null) { long trackNumber = update.getTrackNumber(); - mPlaybackStateCompat = new PlaybackStateCompat.Builder( - mPlaybackStateCompat).setActiveQueueItemId( - trackNumber - 1).build(); + mPlaybackStateCompat = + new PlaybackStateCompat.Builder(mPlaybackStateCompat) + .setActiveQueueItemId(trackNumber - 1) + .build(); } mCurrentTrack = update; } @@ -224,22 +231,28 @@ class AvrcpPlayer { PlayerApplicationSettings.SHUFFLE_STATUS)) { mAvailableActions |= PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE; } - mPlaybackStateCompat = new PlaybackStateCompat.Builder(mPlaybackStateCompat) - .setActions(mAvailableActions).build(); + mPlaybackStateCompat = + new PlaybackStateCompat.Builder(mPlaybackStateCompat) + .setActions(mAvailableActions) + .build(); Log.d(TAG, "Supported Actions = " + mAvailableActions); } @Override public String toString() { - return ""; + + AvrcpControllerUtils.playbackStateCompatToString(mPlaybackStateCompat) + + ">"; } - /** - * A Builder object for an AvrcpPlayer - */ + /** A Builder object for an AvrcpPlayer */ public static class Builder { private BluetoothDevice mDevice = null; private int mPlayerId = AvrcpPlayer.DEFAULT_ID; diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java index c4f54f02f99..538c7446135 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java @@ -41,17 +41,15 @@ import java.util.List; /** * Implements the MediaBrowserService interface to AVRCP and A2DP * - * This service provides a means for external applications to access A2DP and AVRCP. - * The applications are expected to use MediaBrowser (see API) and all the music + *

This service provides a means for external applications to access A2DP and AVRCP. The + * applications are expected to use MediaBrowser (see API) and all the music * browsing/playback/metadata can be controlled via MediaBrowser and MediaController. * - * The current behavior of MediaSessionCompat exposed by this service is as follows: - * 1. MediaSessionCompat is active (i.e. SystemUI and other overview UIs can see updates) when - * device is connected and first starts playing. Before it starts playing we do not activate the - * session. - * 1.1 The session is active throughout the duration of connection. - * 2. The session is de-activated when the device disconnects. It will be connected again when (1) - * happens. + *

The current behavior of MediaSessionCompat exposed by this service is as follows: 1. + * MediaSessionCompat is active (i.e. SystemUI and other overview UIs can see updates) when device + * is connected and first starts playing. Before it starts playing we do not activate the session. + * 1.1 The session is active throughout the duration of connection. 2. The session is de-activated + * when the device disconnects. It will be connected again when (1) happens. */ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { private static final String TAG = BluetoothMediaBrowserService.class.getSimpleName(); @@ -117,8 +115,9 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { // Create and configure the MediaSessionCompat mSession = new MediaSessionCompat(this, TAG); setSessionToken(mSession.getSessionToken()); - mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS - | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); + mSession.setFlags( + MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS + | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mSession.setQueueTitle(getString(R.string.bluetooth_a2dp_sink_queue_name)); mSession.setQueue(mMediaQueue); setErrorPlaybackState(); @@ -139,17 +138,15 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } /** - * BrowseResult is used to return the contents of a node along with a status. The status is - * used to indicate success, a pending download, or error conditions. BrowseResult is used in + * BrowseResult is used to return the contents of a node along with a status. The status is used + * to indicate success, a pending download, or error conditions. BrowseResult is used in * onLoadChildren() and getContents() in BluetoothMediaBrowserService and in getContents() in - * AvrcpControllerService. - * The following statuses have been implemented: - * 1. SUCCESS - Contents have been retrieved successfully. - * 2. DOWNLOAD_PENDING - Download is in progress and may or may not have contents to return. - * 3. NO_DEVICE_CONNECTED - If no device is connected there are no contents to be retrieved. - * 4. ERROR_MEDIA_ID_INVALID - Contents could not be retrieved as the media ID is invalid. - * 5. ERROR_NO_AVRCP_SERVICE - Contents could not be retrieved as AvrcpControllerService is not - * connected. + * AvrcpControllerService. The following statuses have been implemented: 1. SUCCESS - Contents + * have been retrieved successfully. 2. DOWNLOAD_PENDING - Download is in progress and may or + * may not have contents to return. 3. NO_DEVICE_CONNECTED - If no device is connected there are + * no contents to be retrieved. 4. ERROR_MEDIA_ID_INVALID - Contents could not be retrieved as + * the media ID is invalid. 5. ERROR_NO_AVRCP_SERVICE - Contents could not be retrieved as + * AvrcpControllerService is not connected. */ public static class BrowseResult { // Possible statuses for onLoadChildren @@ -206,20 +203,21 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { private void setErrorPlaybackState() { Bundle extras = new Bundle(); - extras.putString(ERROR_RESOLUTION_ACTION_LABEL, - getString(R.string.bluetooth_connect_action)); + extras.putString( + ERROR_RESOLUTION_ACTION_LABEL, getString(R.string.bluetooth_connect_action)); Intent launchIntent = new Intent(); launchIntent.setAction(BluetoothPrefs.BLUETOOTH_SETTING_ACTION); launchIntent.addCategory(BluetoothPrefs.BLUETOOTH_SETTING_CATEGORY); int flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE; - PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, - launchIntent, flags); + PendingIntent pendingIntent = + PendingIntent.getActivity(getApplicationContext(), 0, launchIntent, flags); extras.putParcelable(ERROR_RESOLUTION_ACTION_INTENT, pendingIntent); - PlaybackStateCompat errorState = new PlaybackStateCompat.Builder() - .setErrorMessage(getString(R.string.bluetooth_disconnected)) - .setExtras(extras) - .setState(PlaybackStateCompat.STATE_ERROR, 0, 0) - .build(); + PlaybackStateCompat errorState = + new PlaybackStateCompat.Builder() + .setErrorMessage(getString(R.string.bluetooth_disconnected)) + .setExtras(extras) + .setState(PlaybackStateCompat.STATE_ERROR, 0, 0) + .build(); mSession.setPlaybackState(errorState); } @@ -232,8 +230,8 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } @Override - public synchronized void onLoadChildren(final String parentMediaId, - final Result> result) { + public synchronized void onLoadChildren( + final String parentMediaId, final Result> result) { Log.d(TAG, "Request for contents, id= " + parentMediaId); BrowseResult contents = getContents(parentMediaId); byte status = contents.getStatus(); @@ -242,8 +240,14 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { Log.i(TAG, "Download pending - no results, id= " + parentMediaId); result.detach(); } else { - Log.d(TAG, "Received Contents, id= " + parentMediaId + ", status= " - + contents.getStatusString() + ", results=" + results); + Log.d( + TAG, + "Received Contents, id= " + + parentMediaId + + ", status= " + + contents.getStatusString() + + ", results=" + + results); result.sendResult(results); } } @@ -260,9 +264,9 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { mMediaQueue.clear(); if (songList != null && songList.size() > 0) { for (MediaItem song : songList) { - mMediaQueue.add(new MediaSessionCompat.QueueItem( - song.getDescription(), - mMediaQueue.size())); + mMediaQueue.add( + new MediaSessionCompat.QueueItem( + song.getDescription(), mMediaQueue.size())); } mSession.setQueue(mMediaQueue); } else { @@ -314,8 +318,10 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } static synchronized void notifyChanged(PlaybackStateCompat playbackState) { - Log.d(TAG, "Playback State Changed, state=" - + AvrcpControllerUtils.playbackStateCompatToString(playbackState)); + Log.d( + TAG, + "Playback State Changed, state=" + + AvrcpControllerUtils.playbackStateCompatToString(playbackState)); if (sBluetoothMediaBrowserService != null) { sBluetoothMediaBrowserService.mSession.setPlaybackState(playbackState); } else { @@ -323,9 +329,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } } - /** - * Send AVRCP Play command - */ + /** Send AVRCP Play command */ public static synchronized void play() { if (sBluetoothMediaBrowserService != null) { sBluetoothMediaBrowserService.mSession.getController().getTransportControls().play(); @@ -334,9 +338,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } } - /** - * Send AVRCP Pause command - */ + /** Send AVRCP Pause command */ public static synchronized void pause() { if (sBluetoothMediaBrowserService != null) { sBluetoothMediaBrowserService.mSession.getController().getTransportControls().pause(); @@ -345,9 +347,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } } - /** - * Get playback state - */ + /** Get playback state */ public static synchronized PlaybackStateCompat getPlaybackState() { if (sBluetoothMediaBrowserService != null) { MediaSessionCompat session = sBluetoothMediaBrowserService.getSession(); @@ -360,9 +360,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { return null; } - /** - * Get object for controlling playback - */ + /** Get object for controlling playback */ public static synchronized MediaControllerCompat.TransportControls getTransportControls() { if (sBluetoothMediaBrowserService != null) { return sBluetoothMediaBrowserService.mSession.getController().getTransportControls(); @@ -372,9 +370,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } } - /** - * Set Media session active whenever we have Focus of any kind - */ + /** Set Media session active whenever we have Focus of any kind */ public static synchronized void setActive(boolean active) { if (sBluetoothMediaBrowserService != null) { Log.d(TAG, "Setting the session active state to:" + active); @@ -386,6 +382,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { /** * Checks if the media session is active or not. + * * @return true if media session is active, false otherwise. */ @VisibleForTesting @@ -395,9 +392,8 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } return false; } - /** - * Get Media session for updating state - */ + + /** Get Media session for updating state */ public static synchronized MediaSessionCompat getSession() { if (sBluetoothMediaBrowserService != null) { return sBluetoothMediaBrowserService.mSession; @@ -407,9 +403,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } } - /** - * Reset the state of BluetoothMediaBrowserService to that before a device connected - */ + /** Reset the state of BluetoothMediaBrowserService to that before a device connected */ public static synchronized void reset() { if (sBluetoothMediaBrowserService != null) { sBluetoothMediaBrowserService.clearNowPlayingQueue(); @@ -422,9 +416,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { } } - /** - * Get the state of the BluetoothMediaBrowserService as a debug string - */ + /** Get the state of the BluetoothMediaBrowserService as a debug string */ public static synchronized String dump() { StringBuilder sb = new StringBuilder(); sb.append(TAG + ":"); @@ -439,24 +431,30 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { if (metadata != null) { sb.append("\n track={"); sb.append("title=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE)); - sb.append(", artist=" - + metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST)); + sb.append( + ", artist=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST)); sb.append(", album=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM)); - sb.append(", duration=" - + metadata.getString(MediaMetadataCompat.METADATA_KEY_DURATION)); - sb.append(", track_number=" - + metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER)); - sb.append(", total_tracks=" - + metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS)); + sb.append( + ", duration=" + + metadata.getString(MediaMetadataCompat.METADATA_KEY_DURATION)); + sb.append( + ", track_number=" + + metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER)); + sb.append( + ", total_tracks=" + + metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS)); sb.append(", genre=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE)); - sb.append(", album_art=" - + metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)); + sb.append( + ", album_art=" + + metadata.getString( + MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)); sb.append("}"); } else { sb.append("\n track=" + metadata); } - sb.append("\n playbackState=" - + AvrcpControllerUtils.playbackStateCompatToString(playbackState)); + sb.append( + "\n playbackState=" + + AvrcpControllerUtils.playbackStateCompatToString(playbackState)); sb.append("\n queue=" + queue); sb.append("\n internal_queue=" + sBluetoothMediaBrowserService.mMediaQueue); sb.append("\n session active state=").append(isActive()); diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java b/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java index 4d3973597bd..b8dab9f78fd 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java @@ -38,18 +38,8 @@ import java.util.UUID; /** * An object that holds the browse tree of available media from a remote device. * - * Browsing hierarchy follows the AVRCP specification's description of various scopes and - * looks like follows: - * Root: - * Player1: - * Now_Playing: - * MediaItem1 - * MediaItem2 - * Folder1 - * Folder2 - * .... - * Player2 - * .... + *

Browsing hierarchy follows the AVRCP specification's description of various scopes and looks + * like follows: Root: Player1: Now_Playing: MediaItem1 MediaItem2 Folder1 Folder2 .... Player2 .... */ public class BrowseTree { private static final String TAG = BrowseTree.class.getSimpleName(); @@ -64,6 +54,7 @@ public class BrowseTree { // Static instance of Folder ID <-> Folder Instance (for navigation purposes) @VisibleForTesting final HashMap mBrowseMap = new HashMap(); + private BrowseNode mCurrentBrowseNode; private BrowseNode mCurrentBrowsedPlayer; private BrowseNode mCurrentAddressedPlayer; @@ -78,13 +69,23 @@ public class BrowseTree { BrowseTree(BluetoothDevice device) { if (device == null) { - mRootNode = new BrowseNode(new AvrcpItem.Builder() - .setUuid(ROOT).setTitle(ROOT).setBrowsable(true).build()); + mRootNode = + new BrowseNode( + new AvrcpItem.Builder() + .setUuid(ROOT) + .setTitle(ROOT) + .setBrowsable(true) + .build()); mRootNode.setCached(true); } else if (!Flags.randomizeDeviceLevelMediaIds()) { - mRootNode = new BrowseNode(new AvrcpItem.Builder().setDevice(device) - .setUuid(ROOT + device.getAddress().toString()) - .setTitle(Utils.getName(device)).setBrowsable(true).build()); + mRootNode = + new BrowseNode( + new AvrcpItem.Builder() + .setDevice(device) + .setUuid(ROOT + device.getAddress().toString()) + .setTitle(Utils.getName(device)) + .setBrowsable(true) + .build()); } else { mRootNode = new BrowseNode( @@ -102,12 +103,21 @@ public class BrowseTree { mRootNode.mBrowseScope = AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST; mRootNode.setExpectedChildren(DEFAULT_FOLDER_SIZE); - mNavigateUpNode = new BrowseNode(new AvrcpItem.Builder() - .setUuid(UP).setTitle(UP).setBrowsable(true).build()); - - mNowPlayingNode = new BrowseNode(new AvrcpItem.Builder() - .setUuid(NOW_PLAYING_PREFIX).setTitle(NOW_PLAYING_PREFIX) - .setBrowsable(true).build()); + mNavigateUpNode = + new BrowseNode( + new AvrcpItem.Builder() + .setUuid(UP) + .setTitle(UP) + .setBrowsable(true) + .build()); + + mNowPlayingNode = + new BrowseNode( + new AvrcpItem.Builder() + .setUuid(NOW_PLAYING_PREFIX) + .setTitle(NOW_PLAYING_PREFIX) + .setBrowsable(true) + .build()); mNowPlayingNode.mBrowseScope = AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING; mNowPlayingNode.setExpectedChildren(DEFAULT_FOLDER_SIZE); mBrowseMap.put(mRootNode.getID(), mRootNode); @@ -363,9 +373,13 @@ public class BrowseTree { @Override public synchronized String toString() { - return "[Id: " + getID() - + " Name: " + getMediaItem().getDescription().getTitle() - + " Size: " + mChildren.size() + "]"; + return "[Id: " + + getID() + + " Name: " + + getMediaItem().getDescription().getTitle() + + " Size: " + + mChildren.size() + + "]"; } // Returns true if target is a descendant of this. @@ -452,9 +466,7 @@ public class BrowseTree { mCoverArtMap.get(handle).add(nodeId); } - /** - * Indicate that a node in the tree no longer needs a specific piece of cover art. - */ + /** Indicate that a node in the tree no longer needs a specific piece of cover art. */ synchronized void indicateCoverArtUnused(String nodeId, String handle) { if (mCoverArtMap.containsKey(handle) && mCoverArtMap.get(handle).contains(nodeId)) { mCoverArtMap.get(handle).remove(nodeId); @@ -483,8 +495,8 @@ public class BrowseTree { /** * Adds the Uri of a newly downloaded image to all tree nodes using that specific handle. - * Returns the set of parent nodes that have children impacted by the new art so clients can - * be notified of the change. + * Returns the set of parent nodes that have children impacted by the new art so clients can be + * notified of the change. */ synchronized Set notifyImageDownload(String uuid, Uri uri) { Log.d(TAG, "Received downloaded image handle to cascade to BrowseNodes using it"); @@ -505,9 +517,7 @@ public class BrowseTree { return parents; } - /** - * Dump the state of the AVRCP browse tree - */ + /** Dump the state of the AVRCP browse tree */ public void dump(StringBuilder sb) { mRootNode.toTreeString(0, sb); sb.append("\n Image handles in use (" + mCoverArtMap.size() + "):"); @@ -556,8 +566,7 @@ public class BrowseTree { static BrowseNode getEldestChild(BrowseNode ancestor, BrowseNode target) { // ancestor is an ancestor of target BrowseNode descendant = target; - Log.d(TAG, "NAVIGATING ancestor" + ancestor.toString() + "Target" - + target.toString()); + Log.d(TAG, "NAVIGATING ancestor" + ancestor.toString() + "Target" + target.toString()); while (!ancestor.equals(descendant.mParent)) { descendant = descendant.mParent; if (descendant == null) { diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java b/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java index c4a5d643dec..f39f36d210e 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java @@ -37,24 +37,16 @@ class PlayerApplicationSettings { static final byte REPEAT_STATUS = 0x02; static final byte SHUFFLE_STATUS = 0x03; - @VisibleForTesting - static final byte JNI_REPEAT_STATUS_OFF = 0x01; - @VisibleForTesting - static final byte JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT = 0x02; - @VisibleForTesting - static final byte JNI_REPEAT_STATUS_ALL_TRACK_REPEAT = 0x03; - @VisibleForTesting - static final byte JNI_REPEAT_STATUS_GROUP_REPEAT = 0x04; + @VisibleForTesting static final byte JNI_REPEAT_STATUS_OFF = 0x01; + @VisibleForTesting static final byte JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT = 0x02; + @VisibleForTesting static final byte JNI_REPEAT_STATUS_ALL_TRACK_REPEAT = 0x03; + @VisibleForTesting static final byte JNI_REPEAT_STATUS_GROUP_REPEAT = 0x04; - @VisibleForTesting - static final byte JNI_SHUFFLE_STATUS_OFF = 0x01; - @VisibleForTesting - static final byte JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE = 0x02; - @VisibleForTesting - static final byte JNI_SHUFFLE_STATUS_GROUP_SHUFFLE = 0x03; + @VisibleForTesting static final byte JNI_SHUFFLE_STATUS_OFF = 0x01; + @VisibleForTesting static final byte JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE = 0x02; + @VisibleForTesting static final byte JNI_SHUFFLE_STATUS_GROUP_SHUFFLE = 0x03; - @VisibleForTesting - static final byte JNI_STATUS_INVALID = -1; + @VisibleForTesting static final byte JNI_STATUS_INVALID = -1; /* * Hash map of current settings. @@ -96,7 +88,8 @@ class PlayerApplicationSettings { for (int i = 0; i < btAvrcpAttributeList.length; ) { byte attrId = btAvrcpAttributeList[i++]; - newObj.mSettings.put(attrId, + newObj.mSettings.put( + attrId, mapAttribIdValtoAvrcpPlayerSetting(attrId, btAvrcpAttributeList[i++])); } } catch (ArrayIndexOutOfBoundsException exception) { @@ -207,8 +200,10 @@ class PlayerApplicationSettings { @Override public String toString() { return ""; } } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java b/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java index 1f96bd29a96..c303d529ff4 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java @@ -42,8 +42,8 @@ final class StackEvent { } } - static StackEvent connectionStateChanged(boolean remoteControlConnected, - boolean browsingConnected) { + static StackEvent connectionStateChanged( + boolean remoteControlConnected, boolean browsingConnected) { StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED); event.mRemoteControlConnected = remoteControlConnected; event.mBrowsingConnected = browsingConnected; diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java index 3760cb0f709..656e91f2567 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java @@ -24,11 +24,10 @@ import java.util.Objects; /** * Represents BIP attachment metadata arriving from a GetImageProperties request. * - * Content type is the only spec-required field. + *

Content type is the only spec-required field. * - * Examples: - * - * + *

Examples: */ public class BipAttachmentFormat { private static final String TAG = "avrcpcontroller.BipAttachmentFormat"; @@ -36,39 +35,36 @@ public class BipAttachmentFormat { /** * MIME content type of the image attachment, i.e. "text/plain" * - * This is required by the specification + *

This is required by the specification */ private final String mContentType; - /** - * MIME character set of the image attachment, i.e. "ISO-8859-1" - */ + /** MIME character set of the image attachment, i.e. "ISO-8859-1" */ private final String mCharset; /** * File name of the image attachment * - * This is required by the specification + *

This is required by the specification */ private final String mName; - /** - * Size of the image attachment in bytes - */ + /** Size of the image attachment in bytes */ private final int mSize; - /** - * Date the image attachment was created - */ + /** Date the image attachment was created */ private final BipDateTime mCreated; - /** - * Date the image attachment was last modified - */ + /** Date the image attachment was last modified */ private final BipDateTime mModified; - public BipAttachmentFormat(String contentType, String charset, String name, String size, - String created, String modified) { + public BipAttachmentFormat( + String contentType, + String charset, + String name, + String size, + String created, + String modified) { if (contentType == null) { throw new ParseException("ContentType is required and must be valid"); } @@ -98,8 +94,13 @@ public class BipAttachmentFormat { mModified = bipModified; } - public BipAttachmentFormat(String contentType, String charset, String name, int size, - Date created, Date modified) { + public BipAttachmentFormat( + String contentType, + String charset, + String name, + int size, + Date created, + Date modified) { mContentType = Objects.requireNonNull(contentType, "Content-Type cannot be null"); mName = Objects.requireNonNull(name, "Name cannot be null"); mCharset = charset; diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java index bd648a4cf35..cd7aa3fc627 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java @@ -27,18 +27,13 @@ import java.util.regex.Pattern; /** * An object representing a DateTime sent over the Basic Imaging Profile * - * Date-time format is as follows: + *

Date-time format is as follows: * - * YYYYMMDDTHHMMSSZ, where - * Y/M/D/H/M/S - years, months, days, hours, minutes, seconds - * T - A delimiter - * Z - An optional, but recommended, character indicating the time is in UTC. If UTC - * is not used then we're to assume "local timezone" instead. + *

YYYYMMDDTHHMMSSZ, where Y/M/D/H/M/S - years, months, days, hours, minutes, seconds T - A + * delimiter Z - An optional, but recommended, character indicating the time is in UTC. If UTC is + * not used then we're to assume "local timezone" instead. * - * Example date-time values: - * 20000101T000000Z - * 20000101T235959Z - * 20000101T000000 + *

Example date-time values: 20000101T000000Z 20000101T235959Z 20000101T000000 */ public class BipDateTime { private static final String TAG = "avrcpcontroller.BipDateTime"; @@ -49,12 +44,12 @@ public class BipDateTime { public BipDateTime(String time) { try { /* - * Match groups for the timestamp are numbered as follows: - * - * YYYY MM DD T HH MM SS Z - * ^^^^ ^^ ^^ ^^ ^^ ^^ ^ - * 1 2 3 4 5 6 7 - */ + * Match groups for the timestamp are numbered as follows: + * + * YYYY MM DD T HH MM SS Z + * ^^^^ ^^ ^^ ^^ ^^ ^^ ^ + * 1 2 3 4 5 6 7 + */ Pattern p = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})([Z])?"); Matcher m = p.matcher(time); @@ -66,15 +61,17 @@ public class BipDateTime { builder.setLenient(false); /* Note that Calendar months are zero-based in Java framework */ - builder.setDate(Integer.parseInt(m.group(1)), /* year */ - Integer.parseInt(m.group(2)) - 1, /* month */ - Integer.parseInt(m.group(3))); /* day of month */ + builder.setDate( + Integer.parseInt(m.group(1)), /* year */ + Integer.parseInt(m.group(2)) - 1, /* month */ + Integer.parseInt(m.group(3))); /* day of month */ /* Note the timestamp doesn't have milliseconds and we're explicitly setting to 0 */ - builder.setTimeOfDay(Integer.parseInt(m.group(4)), /* hours */ - Integer.parseInt(m.group(5)), /* minutes */ - Integer.parseInt(m.group(6)), /* seconds */ - 0); /* milliseconds */ + builder.setTimeOfDay( + Integer.parseInt(m.group(4)), /* hours */ + Integer.parseInt(m.group(5)), /* minutes */ + Integer.parseInt(m.group(6)), /* seconds */ + 0); /* milliseconds */ /* If the 7th group is matched then we have UTC based timestamp */ if (m.group(7) != null) { @@ -137,15 +134,25 @@ public class BipDateTime { TimeZone utc = TimeZone.getTimeZone("UTC"); utc.setRawOffset(0); cal.setTimeZone(utc); - return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02dZ", cal.get(Calendar.YEAR), - cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE), - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), + return String.format( + Locale.US, + "%04d%02d%02dT%02d%02d%02dZ", + cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH) + 1, + cal.get(Calendar.DATE), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); } else { cal.setTimeZone(TimeZone.getDefault()); - return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d", cal.get(Calendar.YEAR), - cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE), - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), + return String.format( + Locale.US, + "%04d%02d%02dT%02d%02d%02d", + cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH) + 1, + cal.get(Calendar.DATE), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); } } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java index c4c401ebf79..4de8caf7edb 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java @@ -23,22 +23,17 @@ import java.util.HashMap; /** * Represents an encoding method in which a BIP image is available. * - * The encodings supported by this profile include: - * - JPEG - * - GIF - * - WBMP - * - PNG - * - JPEG2000 - * - BMP - * - USR-xxx + *

The encodings supported by this profile include: - JPEG - GIF - WBMP - PNG - JPEG2000 - BMP - + * USR-xxx * - * The tag USR-xxx is used to represent proprietary encodings. The tag shall begin with the string - * “USR-” but the implementer assigns the characters of the second half of the string. This tag can - * be used by a manufacturer to enable its devices to exchange images under a proprietary encoding. + *

The tag USR-xxx is used to represent proprietary encodings. The tag shall begin with the + * string “USR-” but the implementer assigns the characters of the second half of the string. This + * tag can be used by a manufacturer to enable its devices to exchange images under a proprietary + * encoding. * - * Example proprietary encoding: + *

Example proprietary encoding: * - * - USR-NOKIA-FORMAT1 + *

- USR-NOKIA-FORMAT1 */ public class BipEncoding { public static final int JPEG = 0; @@ -51,6 +46,7 @@ public class BipEncoding { public static final int UNKNOWN = 7; // i.e 'not assigned' or 'not assigned anything valid' private static final HashMap sEncodingNamesToIds = new HashMap(); + static { sEncodingNamesToIds.put("JPEG", JPEG); sEncodingNamesToIds.put("GIF", GIF); @@ -61,6 +57,7 @@ public class BipEncoding { } private static final SparseArray sIdsToEncodingNames = new SparseArray(); + static { sIdsToEncodingNames.put(JPEG, "JPEG"); sIdsToEncodingNames.put(GIF, "GIF"); @@ -71,14 +68,10 @@ public class BipEncoding { sIdsToEncodingNames.put(UNKNOWN, "UNKNOWN"); } - /** - * The integer ID of the type that this encoding is - */ + /** The integer ID of the type that this encoding is */ private final int mType; - /** - * If an encoding is type USR_XXX then it has an extension that defines the encoding - */ + /** If an encoding is type USR_XXX then it has an extension that defines the encoding */ private final String mProprietaryEncodingId; /** @@ -110,7 +103,7 @@ public class BipEncoding { * * @param encoding A constant representing an available encoding * @param proprietaryId A string representing the Id of a propreitary encoding. Only used if the - * encoding type is BipEncoding.USR_XXX + * encoding type is BipEncoding.USR_XXX */ public BipEncoding(int encoding, String proprietaryId) { if (encoding < 0 || encoding > USR_XXX) { @@ -121,8 +114,8 @@ public class BipEncoding { String proprietaryEncodingId = null; if (mType == USR_XXX) { if (proprietaryId == null) { - throw new IllegalArgumentException("Received invalid user defined encoding id '" - + proprietaryId + "'"); + throw new IllegalArgumentException( + "Received invalid user defined encoding id '" + proprietaryId + "'"); } proprietaryEncodingId = proprietaryId.toUpperCase(); } @@ -154,18 +147,18 @@ public class BipEncoding { /** * Determines if an encoding is supported by Android's Graphics Framework * - * Android's Bitmap/BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats. + *

Android's Bitmap/BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats. * * @return True if the encoding is supported, False otherwise. */ public boolean isAndroidSupported() { - return mType == BipEncoding.JPEG || mType == BipEncoding.PNG || mType == BipEncoding.BMP + return mType == BipEncoding.JPEG + || mType == BipEncoding.PNG + || mType == BipEncoding.BMP || mType == BipEncoding.GIF; } - /** - * Determine the encoding type based on an input string - */ + /** Determine the encoding type based on an input string */ private static int determineEncoding(String encoding) { Integer type = (Integer) sEncodingNamesToIds.get(encoding); if (type != null) return type.intValue(); diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java index cb31f43da5e..29936696ec1 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java @@ -24,7 +24,7 @@ import java.io.InputStream; /** * An image object sent over BIP. * - * The image is sent as bytes in the payload of a GetImage request. The format of those bytes is + *

The image is sent as bytes in the payload of a GetImage request. The format of those bytes is * determined by the BipImageDescriptor used when making the request. */ public class BipImage { diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java index a2bee5f3fbd..c38019b1284 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java @@ -33,31 +33,29 @@ import java.io.UnsupportedEncodingException; * Contains the metadata that describes either (1) the desired size of a image to be downloaded or * (2) the extact size of an image to be uploaded. * - * When using this to assert the size of an image to download/pull, it's best to derive this + *

When using this to assert the size of an image to download/pull, it's best to derive this * specific descriptor from any of the available BipImageFormat options returned from a * RequestGetImageProperties. Note that if a BipImageFormat is not of a fixed size type then you * must arrive on a desired fixed size for this descriptor. * - * When using this to denote the size of an image when pushing an image for transfer this descriptor - * must match the metadata of the image being sent. + *

When using this to denote the size of an image when pushing an image for transfer this + * descriptor must match the metadata of the image being sent. * - * Note, the encoding and pixel values are mandatory by specification. The version number is fixed. - * All other values are optional. The transformation field is to have *one* selected option in it. + *

Note, the encoding and pixel values are mandatory by specification. The version number is + * fixed. All other values are optional. The transformation field is to have *one* selected option + * in it. * - * Example: - * < image-descriptor version=“1.0” > - * < image encoding=“JPEG” pixel=“1280*960” size=“500000”/> - * < /image-descriptor > + *

Example: < image-descriptor version=“1.0” > < image encoding=“JPEG” pixel=“1280*960” + * size=“500000”/> < /image-descriptor > */ public class BipImageDescriptor { private static final String TAG = "avrcpcontroller.BipImageDescriptor"; private static final String sVersion = "1.0"; - /** - * A Builder for an ImageDescriptor object - */ + /** A Builder for an ImageDescriptor object */ public static class Builder { private BipImageDescriptor mImageDescriptor = new BipImageDescriptor(); + /** * Set the encoding for the descriptor you're building using a BipEncoding object * @@ -147,14 +145,10 @@ public class BipImageDescriptor { } } - /** - * The encoding of the image, required by the specification - */ + /** The encoding of the image, required by the specification */ private BipEncoding mEncoding = null; - /** - * The width and height of the image, required by the specification - */ + /** The width and height of the image, required by the specification */ private BipPixel mPixel = null; /** @@ -163,15 +157,13 @@ public class BipImageDescriptor { */ private BipTransformation mTransformation = null; - /** - * The size in bytes of the image - */ + /** The size in bytes of the image */ private int mSize = -1; /** * The max size in bytes of the image. * - * Optional, used only when describing an image to pull + *

Optional, used only when describing an image to pull */ private int mMaxSize = -1; @@ -195,8 +187,9 @@ public class BipImageDescriptor { mPixel = new BipPixel(xpp.getAttributeValue(null, "pixel")); mSize = parseInt(xpp.getAttributeValue(null, "size")); mMaxSize = parseInt(xpp.getAttributeValue(null, "maxsize")); - mTransformation = new BipTransformation( - xpp.getAttributeValue(null, "transformation")); + mTransformation = + new BipTransformation( + xpp.getAttributeValue(null, "transformation")); } else { Log.w(TAG, "Unrecognized tag in x-bt/img-Description object: " + tag); } @@ -275,8 +268,10 @@ public class BipImageDescriptor { @Override public String toString() { if (mEncoding == null || mPixel == null) { - error("Missing required fields [ " + (mEncoding == null ? "encoding " : "") - + (mPixel == null ? "pixel " : "")); + error( + "Missing required fields [ " + + (mEncoding == null ? "encoding " : "") + + (mPixel == null ? "pixel " : "")); return null; } StringWriter writer = new StringWriter(); diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java index 43cbef9dd78..0572e814166 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java @@ -24,16 +24,15 @@ import java.util.Objects; * Describes a single native or variant format available for an image, coming from a * BipImageProperties object. * - * This is not an object by specification, per say. It abstracts all the various native and variant - * formats available in a given set of image properties. + *

This is not an object by specification, per say. It abstracts all the various native and + * variant formats available in a given set of image properties. * - * This BipImageFormat can be used to choose a specific BipImageDescriptor when downloading an image + *

This BipImageFormat can be used to choose a specific BipImageDescriptor when downloading an + * image * - * Examples: - * - * - * - * + *

Examples: */ public class BipImageFormat { private static final String TAG = "avrcpcontroller.BipImageFormat"; @@ -41,46 +40,34 @@ public class BipImageFormat { public static final int FORMAT_NATIVE = 0; public static final int FORMAT_VARIANT = 1; - /** - * Create a native BipImageFormat from the given string fields - */ + /** Create a native BipImageFormat from the given string fields */ public static BipImageFormat parseNative(String encoding, String pixel, String size) { return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, null, null); } - /** - * Create a variant BipImageFormat from the given string fields - */ - public static BipImageFormat parseVariant(String encoding, String pixel, String maxSize, - String transformation) { - return new BipImageFormat(BipImageFormat.FORMAT_VARIANT, encoding, pixel, null, maxSize, - transformation); + /** Create a variant BipImageFormat from the given string fields */ + public static BipImageFormat parseVariant( + String encoding, String pixel, String maxSize, String transformation) { + return new BipImageFormat( + BipImageFormat.FORMAT_VARIANT, encoding, pixel, null, maxSize, transformation); } - /** - * Create a native BipImageFormat from the given parameters - */ + /** Create a native BipImageFormat from the given parameters */ public static BipImageFormat createNative(BipEncoding encoding, BipPixel pixel, int size) { return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, -1, null); } - /** - * Create a variant BipImageFormat from the given parameters - */ - public static BipImageFormat createVariant(BipEncoding encoding, BipPixel pixel, int maxSize, - BipTransformation transformation) { - return new BipImageFormat(BipImageFormat.FORMAT_VARIANT, encoding, pixel, -1, maxSize, - transformation); + /** Create a variant BipImageFormat from the given parameters */ + public static BipImageFormat createVariant( + BipEncoding encoding, BipPixel pixel, int maxSize, BipTransformation transformation) { + return new BipImageFormat( + BipImageFormat.FORMAT_VARIANT, encoding, pixel, -1, maxSize, transformation); } - /** - * The 'flavor' of this image format, from the format constants above. - */ + /** The 'flavor' of this image format, from the format constants above. */ private final int mFormatType; - /** - * The encoding method in which this image is available, required by the specification - */ + /** The encoding method in which this image is available, required by the specification */ private final BipEncoding mEncoding; /** @@ -90,30 +77,35 @@ public class BipImageFormat { private final BipPixel mPixel; /** - * The list of supported image transformation methods, any of: - * - 'stretch' : Image server is capable of stretching the image to fit a space - * - 'fill' : Image server is capable of filling the image padding data to fit a space - * - 'crop' : Image server is capable of cropping the image down to fit a space + * The list of supported image transformation methods, any of: - 'stretch' : Image server is + * capable of stretching the image to fit a space - 'fill' : Image server is capable of filling + * the image padding data to fit a space - 'crop' : Image server is capable of cropping the + * image down to fit a space * - * Used by the variant type only + *

Used by the variant type only */ private final BipTransformation mTransformation; /** * Size in bytes of the image. * - * Used by the native type only + *

Used by the native type only */ private final int mSize; /** * The estimated maximum size of an image after a transformation is performed. * - * Used by the variant type only + *

Used by the variant type only */ private final int mMaxSize; - private BipImageFormat(int type, BipEncoding encoding, BipPixel pixel, int size, int maxSize, + private BipImageFormat( + int type, + BipEncoding encoding, + BipPixel pixel, + int size, + int maxSize, BipTransformation transformation) { mFormatType = type; mEncoding = Objects.requireNonNull(encoding, "Encoding cannot be null"); @@ -123,7 +115,12 @@ public class BipImageFormat { mMaxSize = maxSize; } - private BipImageFormat(int type, String encoding, String pixel, String size, String maxSize, + private BipImageFormat( + int type, + String encoding, + String pixel, + String size, + String maxSize, String transformation) { mFormatType = type; mEncoding = new BipEncoding(encoding); @@ -183,10 +180,14 @@ public class BipImageFormat { @Override public String toString() { - if (mEncoding == null || mEncoding.getType() == BipEncoding.UNKNOWN || mPixel == null + if (mEncoding == null + || mEncoding.getType() == BipEncoding.UNKNOWN + || mPixel == null || mPixel.getType() == BipPixel.TYPE_UNKNOWN) { - error("Missing required fields [ " + (mEncoding == null ? "encoding " : "") - + (mPixel == null ? "pixel " : "")); + error( + "Missing required fields [ " + + (mEncoding == null ? "encoding " : "") + + (mPixel == null ? "pixel " : "")); return null; } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java index 94ae058d2e0..e5b1e5b8838 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java @@ -35,39 +35,33 @@ import java.util.Objects; * Represents the return value of a BIP GetImageProperties request, giving a detailed description of * an image and its available descriptors before download. * - * Format is as described by version 1.2.1 of the Basic Image Profile Specification. The + *

Format is as described by version 1.2.1 of the Basic Image Profile Specification. The * specification describes three types of metadata that can arrive with an image -- native, variant - * and attachment. Native describes which native formats a particular image is available in. - * Variant describes which other types of encodings/sizes can be created from the native image using - * various transformations. Attachments describes other items that can be downloaded that are - * associated with the image (text, sounds, etc.) + * and attachment. Native describes which native formats a particular image is available in. Variant + * describes which other types of encodings/sizes can be created from the native image using various + * transformations. Attachments describes other items that can be downloaded that are associated + * with the image (text, sounds, etc.) * - * The specification requires that - * 1. The fixed version string of "1.0" is used - * 2. There is an image handle - * 3. The "imaging thumbnail format" is included. This is defined for BIP in section 4.4.3 - * (160x120 JPEG) and redefined for AVRCP in section 5.14.2.2.1 I (200x200 JPEG). It can be - * either a native or variant format. + *

The specification requires that 1. The fixed version string of "1.0" is used 2. There is an + * image handle 3. The "imaging thumbnail format" is included. This is defined for BIP in section + * 4.4.3 (160x120 JPEG) and redefined for AVRCP in section 5.14.2.2.1 I (200x200 JPEG). It can be + * either a native or variant format. * - * Example: - * - * - * - * - * - * - * - * + *

Example: + * */ public class BipImageProperties { private static final String TAG = "avrcpcontroller.BipImageProperties"; private static final String sVersion = "1.0"; - /** - * A Builder for a BipImageProperties object - */ + /** A Builder for a BipImageProperties object */ public static class Builder { private BipImageProperties mProperties = new BipImageProperties(); + /** * Set the image handle field for the object you're building * @@ -133,14 +127,10 @@ public class BipImageProperties { } } - /** - * The image handle associated with this set of properties. - */ + /** The image handle associated with this set of properties. */ private String mImageHandle = null; - /** - * The version of the properties object, used to encode and decode. - */ + /** The version of the properties object, used to encode and decode. */ private String mVersion = null; /** @@ -148,15 +138,12 @@ public class BipImageProperties { */ private String mFriendlyName = null; - /** - * Whether we have the required imaging thumbnail format - */ + /** Whether we have the required imaging thumbnail format */ private boolean mHasThumbnailFormat = false; - /** - * The various sets of available formats. - */ + /** The various sets of available formats. */ private ArrayList mNativeFormats; + private ArrayList mVariantFormats; private ArrayList mAttachments; @@ -207,8 +194,8 @@ public class BipImageProperties { String created = xpp.getAttributeValue(null, "created"); String modified = xpp.getAttributeValue(null, "modified"); addAttachment( - new BipAttachmentFormat(contentType, charset, name, size, - created, modified)); + new BipAttachmentFormat( + contentType, charset, name, size, created, modified)); } else { warn("Unrecognized tag in x-bt/img-properties object: " + tag); } @@ -254,8 +241,12 @@ public class BipImageProperties { private void addNativeFormat(BipImageFormat format) { Objects.requireNonNull(format); if (format.getType() != BipImageFormat.FORMAT_NATIVE) { - throw new IllegalArgumentException("Format type '" + format.getType() - + "' but expected '" + BipImageFormat.FORMAT_NATIVE + "'"); + throw new IllegalArgumentException( + "Format type '" + + format.getType() + + "' but expected '" + + BipImageFormat.FORMAT_NATIVE + + "'"); } mNativeFormats.add(format); @@ -267,8 +258,12 @@ public class BipImageProperties { private void addVariantFormat(BipImageFormat format) { Objects.requireNonNull(format); if (format.getType() != BipImageFormat.FORMAT_VARIANT) { - throw new IllegalArgumentException("Format type '" + format.getType() - + "' but expected '" + BipImageFormat.FORMAT_VARIANT + "'"); + throw new IllegalArgumentException( + "Format type '" + + format.getType() + + "' but expected '" + + BipImageFormat.FORMAT_VARIANT + + "'"); } mVariantFormats.add(format); @@ -399,7 +394,7 @@ public class BipImageProperties { /** * Serialize this object into a byte array * - * Objects that are not valid will fail to serialize and return null. + *

Objects that are not valid will fail to serialize and return null. * * @return Byte array representing this object, ready to send over OBEX, or null on error. */ @@ -415,10 +410,8 @@ public class BipImageProperties { /** * Determine if the contents of this BipImageProperties object are valid and meet the - * specification requirements: - * 1. Include the fixed 1.0 version - * 2. Include an image handle - * 3. Have the thumbnail format as either the native or variant + * specification requirements: 1. Include the fixed 1.0 version 2. Include an image handle 3. + * Have the thumbnail format as either the native or variant * * @return True if our contents are valid, false otherwise */ diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java index bba0cefaeb5..f3be13363d8 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java @@ -22,27 +22,27 @@ import java.util.regex.Pattern; /** * The pixel size or range of pixel sizes in which the image is available * - * A FIXED size is represented as the following, where W is width and H is height. The domain - * of values is [0, 65535] + *

A FIXED size is represented as the following, where W is width and H is height. The domain of + * values is [0, 65535] * - * W*H + *

W*H * - * A RESIZABLE size that allows a modified aspect ratio is represented as the following, where - * W_1*H_1 is the minimum width and height pair and W2*H2 is the maximum width and height pair. - * The domain of values is [0, 65535] + *

A RESIZABLE size that allows a modified aspect ratio is represented as the following, where + * W_1*H_1 is the minimum width and height pair and W2*H2 is the maximum width and height pair. The + * domain of values is [0, 65535] * - * W_1*H_1-W2*H2 + *

W_1*H_1-W2*H2 * - * A RESIZABLE size that allows a fixed aspect ratio is represented as the following, where - * W_1 is the minimum width and W2*H2 is the maximum width and height pair. - * The domain of values is [0, 65535] + *

A RESIZABLE size that allows a fixed aspect ratio is represented as the following, where W_1 + * is the minimum width and W2*H2 is the maximum width and height pair. The domain of values is [0, + * 65535] * - * W_1**-W2*H2 + *

W_1**-W2*H2 * - * For each possible intermediate width value, the corresponding height is calculated using the + *

For each possible intermediate width value, the corresponding height is calculated using the * formula * - * H=(W*H2)/W2 + *

H=(W*H2)/W2 */ public class BipPixel { private static final String TAG = "avrcpcontroller.BipPixel"; @@ -64,37 +64,33 @@ public class BipPixel { private final int mMaxWidth; private final int mMaxHeight; - /** - * Create a fixed size BipPixel object - */ + /** Create a fixed size BipPixel object */ public static BipPixel createFixed(int width, int height) { return new BipPixel(TYPE_FIXED, width, height, width, height); } - /** - * Create a resizable modifiable aspect ratio BipPixel object - */ - public static BipPixel createResizableModified(int minWidth, int minHeight, int maxWidth, - int maxHeight) { - return new BipPixel(TYPE_RESIZE_MODIFIED_ASPECT_RATIO, minWidth, minHeight, maxWidth, - maxHeight); + /** Create a resizable modifiable aspect ratio BipPixel object */ + public static BipPixel createResizableModified( + int minWidth, int minHeight, int maxWidth, int maxHeight) { + return new BipPixel( + TYPE_RESIZE_MODIFIED_ASPECT_RATIO, minWidth, minHeight, maxWidth, maxHeight); } - /** - * Create a resizable fixed aspect ratio BipPixel object - */ + /** Create a resizable fixed aspect ratio BipPixel object */ public static BipPixel createResizableFixed(int minWidth, int maxWidth, int maxHeight) { int minHeight = (minWidth * maxHeight) / maxWidth; - return new BipPixel(TYPE_RESIZE_FIXED_ASPECT_RATIO, minWidth, minHeight, - maxWidth, maxHeight); + return new BipPixel( + TYPE_RESIZE_FIXED_ASPECT_RATIO, minWidth, minHeight, maxWidth, maxHeight); } /** * Directly create a BipPixel object knowing your exact type and dimensions. Internal use only */ private BipPixel(int type, int minWidth, int minHeight, int maxWidth, int maxHeight) { - if (isDimensionInvalid(minWidth) || isDimensionInvalid(maxWidth) - || isDimensionInvalid(minHeight) || isDimensionInvalid(maxHeight)) { + if (isDimensionInvalid(minWidth) + || isDimensionInvalid(maxWidth) + || isDimensionInvalid(minHeight) + || isDimensionInvalid(maxHeight)) { throw new IllegalArgumentException("Dimension's must be in [0, " + PIXEL_MAX + "]"); } @@ -105,9 +101,7 @@ public class BipPixel { mMaxHeight = maxHeight; } - /** - * Create a BipPixel object from an Image Format pixel attribute string - */ + /** Create a BipPixel object from an Image Format pixel attribute string */ public BipPixel(String pixel) { int type = TYPE_UNKNOWN; int minWidth = -1; @@ -129,8 +123,8 @@ public class BipPixel { } break; case TYPE_RESIZE_MODIFIED_ASPECT_RATIO: - Pattern modifiedRatio = Pattern.compile( - "^(\\d{1,5})\\*(\\d{1,5})-(\\d{1,5})\\*(\\d{1,5})$"); + Pattern modifiedRatio = + Pattern.compile("^(\\d{1,5})\\*(\\d{1,5})-(\\d{1,5})\\*(\\d{1,5})$"); Matcher m2 = modifiedRatio.matcher(pixel); if (m2.matches()) { type = TYPE_RESIZE_MODIFIED_ASPECT_RATIO; @@ -157,8 +151,10 @@ public class BipPixel { if (type == TYPE_UNKNOWN) { throw new ParseException("Failed to determine type of '" + pixel + "'"); } - if (isDimensionInvalid(minWidth) || isDimensionInvalid(maxWidth) - || isDimensionInvalid(minHeight) || isDimensionInvalid(maxHeight)) { + if (isDimensionInvalid(minWidth) + || isDimensionInvalid(maxWidth) + || isDimensionInvalid(minHeight) + || isDimensionInvalid(maxHeight)) { throw new ParseException("Parsed dimensions must be in [0, " + PIXEL_MAX + "]"); } @@ -193,8 +189,8 @@ public class BipPixel { * Determines the type of the pixel string by counting the number of '*' delimiters in the * string. * - * Note that the overall maximum size of any pixel string is 23 characters in length due to the - * max size of each dimension + *

Note that the overall maximum size of any pixel string is 23 characters in length due to + * the max size of each dimension * * @return The corresponding type we should assume the given pixel string is */ diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java index 82b9fe97293..88fca6aa1a8 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java @@ -27,9 +27,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; -/** - * This is a base class for implementing AVRCP Controller Basic Image Profile (BIP) requests - */ +/** This is a base class for implementing AVRCP Controller Basic Image Profile (BIP) requests */ abstract class BipRequest { private static final String TAG = BipRequest.class.getSimpleName(); @@ -53,15 +51,15 @@ abstract class BipRequest { /** * A function that returns the type of the request. * - * Used to determine type instead of using 'instanceof' + *

Used to determine type instead of using 'instanceof' */ public abstract int getType(); /** * A single point of entry for kicking off a AVRCP BIP request. * - * Child classes are expected to implement this interface, filling in the details of the request - * (headers, operation type, error handling, etc). + *

Child classes are expected to implement this interface, filling in the details of the + * request (headers, operation type, error handling, etc). */ public abstract void execute(ClientSession session) throws IOException; @@ -90,9 +88,7 @@ abstract class BipRequest { debug("GET final response code is '" + mResponseCode + "'"); } - /** - * A generica PUT operation, providing overridable hooks to read response headers. - */ + /** A generica PUT operation, providing overridable hooks to read response headers. */ protected void executePut(ClientSession session, byte[] body) throws IOException { debug("Exeucting PUT"); setOperation(null); @@ -157,23 +153,17 @@ abstract class BipRequest { return TAG + " (type: " + getType() + ", mResponseCode: " + mResponseCode + ")"; } - /** - * Print to debug if debug is enabled for this class - */ + /** Print to debug if debug is enabled for this class */ protected void debug(String msg) { Log.d(TAG, msg); } - /** - * Print to warn - */ + /** Print to warn */ protected void warn(String msg) { Log.w(TAG, msg); } - /** - * Print to error - */ + /** Print to error */ protected void error(String msg) { Log.e(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java index 9922f61f6df..bb2e7ecb496 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java @@ -24,20 +24,15 @@ import java.util.HashSet; * Represents the set of possible transformations available for a variant of an image to get the * image to a particular pixel size. * - * The transformations supported by BIP v1.2.1 include: - * - Stretch - * - Fill - * - Crop + *

The transformations supported by BIP v1.2.1 include: - Stretch - Fill - Crop * - * Example in an image properties/format: - * - * - * + *

Example in an image properties/format: * - * Example in an image descriptor: - * - * - * + *

Example in an image descriptor: */ public class BipTransformation { private static final String TAG = "avrcpcontroller.BipTransformation"; @@ -49,15 +44,10 @@ public class BipTransformation { public final HashSet mSupportedTransformations = new HashSet(3); - /** - * Create an empty set of BIP Transformations - */ - public BipTransformation() { - } + /** Create an empty set of BIP Transformations */ + public BipTransformation() {} - /** - * Create a set of BIP Transformations from an attribute value from an Image Format string - */ + /** Create a set of BIP Transformations from an attribute value from an Image Format string */ public BipTransformation(String transformations) { if (transformations == null) return; @@ -81,16 +71,12 @@ public class BipTransformation { } } - /** - * Create a set of BIP Transformations from a single supported transformation - */ + /** Create a set of BIP Transformations from a single supported transformation */ public BipTransformation(int transformation) { addTransformation(transformation); } - /** - * Create a set of BIP Transformations from a set of supported transformations - */ + /** Create a set of BIP Transformations from a set of supported transformations */ public BipTransformation(int[] transformations) { for (int transformation : transformations) { addTransformation(transformation); @@ -104,8 +90,8 @@ public class BipTransformation { */ public void addTransformation(int transformation) { if (!isValid(transformation)) { - throw new IllegalArgumentException("Invalid transformation ID '" + transformation - + "'"); + throw new IllegalArgumentException( + "Invalid transformation ID '" + transformation + "'"); } mSupportedTransformations.add(transformation); } @@ -117,8 +103,8 @@ public class BipTransformation { */ public void removeTransformation(int transformation) { if (!isValid(transformation)) { - throw new IllegalArgumentException("Invalid transformation ID '" + transformation - + "'"); + throw new IllegalArgumentException( + "Invalid transformation ID '" + transformation + "'"); } mSupportedTransformations.remove(transformation); } @@ -127,7 +113,7 @@ public class BipTransformation { * Determine if a given transformations is valid * * @param transformation The integer encoding ID of the transformation. Should be one of the - * BipTransformation.* constants, but doesn't *have* to be + * BipTransformation.* constants, but doesn't *have* to be * @return True if the transformation constant is valid, False otherwise */ private boolean isValid(int transformation) { diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java index 8dbb736e188..bd23be29721 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java @@ -16,9 +16,7 @@ package com.android.bluetooth.avrcpcontroller; -/** - * Thrown when has parsing. - */ +/** Thrown when has parsing. */ public class ParseException extends RuntimeException { public ParseException(String msg) { super(msg); diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java index fc5f49960b4..79ad37c21d2 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java @@ -30,8 +30,7 @@ import java.io.InputStream; public class RequestGetImage extends BipRequest { // Expected inputs private final String mImageHandle; - @VisibleForTesting - final BipImageDescriptor mImageDescriptor; + @VisibleForTesting final BipImageDescriptor mImageDescriptor; // Expected return type private static final String TYPE = "x-bt/img-img"; diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java index ad809e0997a..1b6fa1836b9 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java @@ -59,8 +59,11 @@ public class RequestGetImageProperties extends BipRequest { protected void readResponse(InputStream stream) throws IOException { try { mImageProperties = new BipImageProperties(stream); - debug("Response GetImageProperties - handle: " + mImageHandle + ", properties: " - + mImageProperties.toString()); + debug( + "Response GetImageProperties - handle: " + + mImageHandle + + ", properties: " + + mImageProperties.toString()); } catch (ParseException e) { error("Failed to parse incoming properties object"); mImageProperties = null; diff --git a/android/app/src/com/android/bluetooth/bas/BatteryService.java b/android/app/src/com/android/bluetooth/bas/BatteryService.java index 94d505bee38..b062849a63e 100644 --- a/android/app/src/com/android/bluetooth/bas/BatteryService.java +++ b/android/app/src/com/android/bluetooth/bas/BatteryService.java @@ -48,9 +48,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -/** - * A profile service that connects to the Battery service (BAS) of BLE devices - */ +/** A profile service that connects to the Battery service (BAS) of BLE devices */ public class BatteryService extends ProfileService { private static final String TAG = "BatteryService"; @@ -85,10 +83,14 @@ public class BatteryService extends ProfileService { throw new IllegalStateException("start() called twice"); } - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when BatteryService starts"); - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when BatteryService starts"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when BatteryService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when BatteryService starts"); mHandler = new Handler(Looper.getMainLooper()); mStateMachines.clear(); @@ -117,7 +119,6 @@ public class BatteryService extends ProfileService { mStateMachines.clear(); } - if (mStateMachinesThread != null) { try { mStateMachinesThread.quitSafely(); @@ -142,9 +143,7 @@ public class BatteryService extends ProfileService { Log.d(TAG, "cleanup()"); } - /** - * Gets the BatteryService instance - */ + /** Gets the BatteryService instance */ public static synchronized BatteryService getBatteryService() { if (sBatteryService == null) { Log.w(TAG, "getBatteryService(): service is NULL"); @@ -158,22 +157,18 @@ public class BatteryService extends ProfileService { return sBatteryService; } - /** - * Sets the battery service instance. It should be called only for testing purpose. - */ + /** Sets the battery service instance. It should be called only for testing purpose. */ @VisibleForTesting public static synchronized void setBatteryService(BatteryService instance) { Log.d(TAG, "setBatteryService(): set to: " + instance); sBatteryService = instance; } - /** - * Connects to the battery service of the given device. - */ + /** Connects to the battery service of the given device. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "connect(): " + device); if (device == null) { Log.w(TAG, "Ignore connecting to null device"); @@ -186,8 +181,7 @@ public class BatteryService extends ProfileService { } ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device); if (!Utils.arrayContains(featureUuids, BluetoothUuid.BATTERY)) { - Log.e(TAG, "Cannot connect to " + device - + " : Remote does not have Battery UUID"); + Log.e(TAG, "Cannot connect to " + device + " : Remote does not have Battery UUID"); return false; } @@ -204,8 +198,8 @@ public class BatteryService extends ProfileService { } /** - * Connects to the battery service of the given device if possible. - * If it's impossible, it doesn't try without logging errors. + * Connects to the battery service of the given device if possible. If it's impossible, it + * doesn't try without logging errors. */ public boolean connectIfPossible(BluetoothDevice device) { if (device == null @@ -217,13 +211,11 @@ public class BatteryService extends ProfileService { return connect(device); } - /** - * Disconnects from the battery service of the given device. - */ + /** Disconnects from the battery service of the given device. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "disconnect(): " + device); if (device == null) { Log.w(TAG, "Ignore disconnecting to null device"); @@ -241,12 +233,13 @@ public class BatteryService extends ProfileService { /** * Gets devices that battery service is connected. + * * @return */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public List getConnectedDevices() { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); synchronized (mStateMachines) { List devices = new ArrayList<>(); for (BatteryStateMachine sm : mStateMachines.values()) { @@ -259,8 +252,8 @@ public class BatteryService extends ProfileService { } /** - * Check whether it can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether it can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -284,16 +277,19 @@ public class BatteryService extends ProfileService { return true; } - /** - * Called when the connection state of a state machine is changed - */ + /** Called when the connection state of a state machine is changed */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public void handleConnectionStateChanged(BatteryStateMachine sm, - int fromState, int toState) { + public void handleConnectionStateChanged(BatteryStateMachine sm, int fromState, int toState) { BluetoothDevice device = sm.getDevice(); if ((sm == null) || (fromState == toState)) { - Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device - + " fromState=" + fromState + " toState=" + toState); + Log.e( + TAG, + "connectionStateChanged: unexpected invocation. device=" + + device + + " fromState=" + + fromState + + " toState=" + + toState); return; } @@ -309,8 +305,8 @@ public class BatteryService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) List getDevicesMatchingConnectionStates(int[] states) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); ArrayList devices = new ArrayList<>(); if (states == null) { return devices; @@ -353,13 +349,10 @@ public class BatteryService extends ProfileService { } } - /** - * Gets the connection state of the given device's battery service - */ + /** Gets the connection state of the given device's battery service */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, - "Need BLUETOOTH_CONNECT permission"); + enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission"); synchronized (mStateMachines) { BatteryStateMachine sm = mStateMachines.get(device); if (sm == null) { @@ -370,15 +363,14 @@ public class BatteryService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device the remote device * @param connectionPolicy is the connection policy to set to for this profile @@ -386,11 +378,11 @@ public class BatteryService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.BATTERY, - connectionPolicy); + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.BATTERY, connectionPolicy); if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { connect(device); } else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { @@ -399,21 +391,18 @@ public class BatteryService extends ProfileService { return true; } - /** - * Gets the connection policy for the battery service of the given device. - */ + /** Gets the connection policy for the battery service of the given device. */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.BATTERY); } - /** - * Called when the battery level of the device is notified. - */ + + /** Called when the battery level of the device is notified. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void handleBatteryChanged(BluetoothDevice device, int batteryLevel) { - mAdapterService.setBatteryLevel(device, batteryLevel, /*isBas=*/ true); + mAdapterService.setBatteryLevel(device, batteryLevel, /* isBas= */ true); } private BatteryStateMachine getOrCreateStateMachine(BluetoothDevice device) { @@ -428,8 +417,10 @@ public class BatteryService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_BATTERY_STATE_MACHINES) { - Log.e(TAG, "Maximum number of Battery state machines reached: " - + MAX_BATTERY_STATE_MACHINES); + Log.e( + TAG, + "Maximum number of Battery state machines reached: " + + MAX_BATTERY_STATE_MACHINES); return null; } Log.d(TAG, "Creating a new state machine for " + device); @@ -480,8 +471,9 @@ public class BatteryService extends ProfileService { synchronized (mStateMachines) { BatteryStateMachine sm = mStateMachines.remove(device); if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); + Log.w( + TAG, + "removeStateMachine: device " + device + " does not have a state machine"); return; } Log.i(TAG, "removeGatt: removing bluetooth gatt for device: " + device); @@ -490,9 +482,7 @@ public class BatteryService extends ProfileService { } } - /** - * Binder object: must be a static class or memory leak may occur - */ + /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting static class BluetoothBatteryBinder extends IBluetoothBattery.Stub implements IProfileServiceBinder { diff --git a/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java b/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java index 218cff125e1..cd0332f1736 100644 --- a/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java +++ b/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java @@ -44,9 +44,7 @@ import java.lang.ref.WeakReference; import java.util.Scanner; import java.util.UUID; -/** - * It manages Battery service of a BLE device - */ +/** It manages Battery service of a BLE device */ public class BatteryStateMachine extends StateMachine { private static final String TAG = "BatteryStateMachine"; @@ -63,8 +61,7 @@ public class BatteryStateMachine extends StateMachine { private static final int CONNECT_TIMEOUT = 201; // NOTE: the value is not "final" - it is modified in the unit tests - @VisibleForTesting - static int sConnectTimeoutMs = 30000; // 30s + @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s private Disconnected mDisconnected; private Connecting mConnecting; @@ -103,17 +100,13 @@ public class BatteryStateMachine extends StateMachine { return sm; } - /** - * Quits the state machine - */ + /** Quits the state machine */ public void doQuit() { log("doQuit for device " + mDevice); quitNow(); } - /** - * Cleans up the resources the state machine held. - */ + /** Cleans up the resources the state machine held. */ public void cleanup() { log("cleanup for device " + mDevice); if (mBluetoothGatt != null) { @@ -163,9 +156,7 @@ public class BatteryStateMachine extends StateMachine { return Integer.toString(state); } - /** - * Dumps battery state machine state. - */ + /** Dumps battery state machine state. */ public void dump(StringBuilder sb) { ProfileService.println(sb, "mDevice: " + mDevice); ProfileService.println(sb, " StateMachine: " + this); @@ -173,7 +164,7 @@ public class BatteryStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); @@ -204,8 +195,13 @@ public class BatteryStateMachine extends StateMachine { } void dispatchConnectionStateChanged(int fromState, int toState) { - log("Connection state " + mDevice + ": " + profileStateToString(fromState) - + "->" + profileStateToString(toState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(fromState) + + "->" + + profileStateToString(toState)); BatteryService service = mServiceRef.get(); if (service != null) { @@ -232,9 +228,15 @@ public class BatteryStateMachine extends StateMachine { Log.w(TAG, "Trying connectGatt with existing BluetoothGatt instance."); mBluetoothGatt.close(); } - mBluetoothGatt = mDevice.connectGatt(service, /*autoConnect=*/false, - mGattCallback, TRANSPORT_LE, /*opportunistic=*/true, - PHY_LE_1M_MASK | PHY_LE_2M_MASK, getHandler()); + mBluetoothGatt = + mDevice.connectGatt( + service, + /* autoConnect= */ false, + mGattCallback, + TRANSPORT_LE, + /* opportunistic= */ true, + PHY_LE_1M_MASK | PHY_LE_2M_MASK, + getHandler()); return mBluetoothGatt != null; } @@ -274,8 +276,7 @@ public class BatteryStateMachine extends StateMachine { @Override public void enter() { - log(TAG, "Enter (" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); if (mBluetoothGatt != null) { mBluetoothGatt.close(); @@ -284,22 +285,20 @@ public class BatteryStateMachine extends StateMachine { if (mLastConnectionState != BluetoothProfile.STATE_DISCONNECTED) { // Don't broadcast during startup - dispatchConnectionStateChanged(mLastConnectionState, - BluetoothProfile.STATE_DISCONNECTED); + dispatchConnectionStateChanged( + mLastConnectionState, BluetoothProfile.STATE_DISCONNECTED); } } @Override public void exit() { - log(TAG, "Exit (" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log(TAG, "Process message(" + mDevice + "): " + messageWhatToString( - message.what)); + log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(message.what)); BatteryService service = mServiceRef.get(); switch (message.what) { @@ -309,13 +308,15 @@ public class BatteryStateMachine extends StateMachine { if (connectGatt()) { transitionTo(mConnecting); } else { - Log.w(TAG, "Battery connecting request rejected due to " - + "GATT connection rejection: " + mDevice); + Log.w( + TAG, + "Battery connecting request rejected due to " + + "GATT connection rejection: " + + mDevice); } } else { // Reject the request and stay in Disconnected state - Log.w(TAG, "Battery connecting request rejected: " - + mDevice); + Log.w(TAG, "Battery connecting request rejected: " + mDevice); } break; case DISCONNECT: @@ -346,24 +347,22 @@ public class BatteryStateMachine extends StateMachine { @VisibleForTesting class Connecting extends State { private static final String TAG = "BASM_Connecting"; + @Override public void enter() { - log(TAG, "Enter (" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); dispatchConnectionStateChanged(mLastConnectionState, BluetoothProfile.STATE_CONNECTING); } @Override public void exit() { - log(TAG, "Exit (" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; } @Override public boolean processMessage(Message message) { - log(TAG, "process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log(TAG, "process message(" + mDevice + "): " + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -409,31 +408,29 @@ public class BatteryStateMachine extends StateMachine { @VisibleForTesting class Disconnecting extends State { private static final String TAG = "BASM_Disconnecting"; + @Override public void enter() { - log(TAG, "Enter (" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); - dispatchConnectionStateChanged(mLastConnectionState, - BluetoothProfile.STATE_DISCONNECTING); + dispatchConnectionStateChanged( + mLastConnectionState, BluetoothProfile.STATE_DISCONNECTING); } @Override public void exit() { - log(TAG, "Exit (" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log(TAG, "Process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(message.what)); switch (message.what) { - //TODO: Check if connect while disconnecting is okay. - // It is related to CONNECT_TIMEOUT as well. + // TODO: Check if connect while disconnecting is okay. + // It is related to CONNECT_TIMEOUT as well. case CONNECT: Log.w(TAG, "CONNECT ignored: " + mDevice); break; @@ -460,17 +457,17 @@ public class BatteryStateMachine extends StateMachine { Log.i(TAG, "Disconnected: " + mDevice); transitionTo(mDisconnected); break; - case BluetoothGatt.STATE_CONNECTED: { - // Reject the connection and stay in Disconnecting state - Log.w(TAG, "Incoming Battery connected request rejected: " - + mDevice); - if (mBluetoothGatt != null) { - mBluetoothGatt.disconnect(); - } else { - transitionTo(mDisconnected); + case BluetoothGatt.STATE_CONNECTED: + { + // Reject the connection and stay in Disconnecting state + Log.w(TAG, "Incoming Battery connected request rejected: " + mDevice); + if (mBluetoothGatt != null) { + mBluetoothGatt.disconnect(); + } else { + transitionTo(mDisconnected); + } + break; } - break; - } default: Log.e(TAG, "Incorrect state: " + state); break; @@ -481,10 +478,10 @@ public class BatteryStateMachine extends StateMachine { @VisibleForTesting class Connected extends State { private static final String TAG = "BASM_Connected"; + @Override public void enter() { - log(TAG, "Enter (" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); dispatchConnectionStateChanged(mLastConnectionState, BluetoothProfile.STATE_CONNECTED); if (mBluetoothGatt != null) { @@ -494,8 +491,7 @@ public class BatteryStateMachine extends StateMachine { @Override public void exit() { - log(TAG, "Exit (" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); // Reset the battery level only after connected resetBatteryLevel(); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; @@ -503,8 +499,7 @@ public class BatteryStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { - log(TAG, "Process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -577,16 +572,19 @@ public class BatteryStateMachine extends StateMachine { } @Override - public void onCharacteristicChanged(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic, byte[] value) { + public void onCharacteristicChanged( + BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) { if (GATT_BATTERY_LEVEL_CHARACTERISTIC_UUID.equals(characteristic.getUuid())) { updateBatteryLevel(value); } } @Override - public void onCharacteristicRead(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic, byte[] value, int status) { + public void onCharacteristicRead( + BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, + byte[] value, + int status) { if (status != BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "Read characteristic failure on " + gatt + " " + characteristic); return; @@ -597,18 +595,19 @@ public class BatteryStateMachine extends StateMachine { BluetoothGattDescriptor cccd = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID); if (cccd != null) { - gatt.setCharacteristicNotification(characteristic, /*enable=*/true); + gatt.setCharacteristicNotification(characteristic, /* enable= */ true); gatt.writeDescriptor(cccd, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } else { - Log.w(TAG, "No CCCD for battery level characteristic, " - + "it won't be notified"); + Log.w( + TAG, + "No CCCD for battery level characteristic, " + "it won't be notified"); } } } @Override - public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, - int status) { + public void onDescriptorWrite( + BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { if (status != BluetoothGatt.GATT_SUCCESS) { Log.w(TAG, "Failed to write descriptor " + descriptor.getUuid()); } diff --git a/android/app/src/com/android/bluetooth/bass_client/BaseData.java b/android/app/src/com/android/bluetooth/bass_client/BaseData.java index f98dda279c2..bd5a4dba5d3 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BaseData.java +++ b/android/app/src/com/android/bluetooth/bass_client/BaseData.java @@ -30,9 +30,7 @@ import java.util.Map; import java.util.MissingResourceException; import java.util.Set; -/** - * Helper class to parse the Broadcast Announcement BASE data - */ +/** Helper class to parse the Broadcast Announcement BASE data */ class BaseData { private static final String TAG = "Bassclient-BaseData"; private static final byte UNKNOWN_CODEC = (byte) 0xFE; @@ -143,8 +141,11 @@ class BaseData { if (keyMetadataDiff != null) { Iterator itr = keyMetadataDiff.iterator(); for (int k = 0; itr.hasNext(); k++) { - log("keyMetadataDiff:[" + k + "]:" - + Arrays.toString(itr.next().getBytes())); + log( + "keyMetadataDiff:[" + + k + + "]:" + + Arrays.toString(itr.next().getBytes())); } } log("END: Level2: Key Metadata differentiators"); @@ -152,8 +153,11 @@ class BaseData { if (keyCodecCfgDiff != null) { Iterator itr = keyCodecCfgDiff.iterator(); for (int k = 0; itr.hasNext(); k++) { - log("LEVEL2: keyCodecCfgDiff:[" + k + "]:" - + Arrays.toString(itr.next().getBytes())); + log( + "LEVEL2: keyCodecCfgDiff:[" + + k + + "]:" + + Arrays.toString(itr.next().getBytes())); } } log("END: Level2: Key CodecConfig differentiators"); @@ -164,8 +168,11 @@ class BaseData { if (keyCodecCfgDiff != null) { Iterator itr = keyCodecCfgDiff.iterator(); for (int k = 0; itr.hasNext(); k++) { - log("LEVEL3: keyCodecCfgDiff:[" + k + "]:" - + Arrays.toString(itr.next().getBytes())); + log( + "LEVEL3: keyCodecCfgDiff:[" + + k + + "]:" + + Arrays.toString(itr.next().getBytes())); } } log("END: Level3: Key CodecConfig differentiators"); @@ -176,8 +183,11 @@ class BaseData { } } - BaseData(BaseInformation levelOne, ArrayList levelTwo, - ArrayList levelThree, int numOfBISIndices) { + BaseData( + BaseInformation levelOne, + ArrayList levelTwo, + ArrayList levelThree, + int numOfBISIndices) { mLevelOne = levelOne; mLevelTwo = levelTwo; mLevelThree = levelThree; @@ -204,8 +214,7 @@ class BaseData { levelOne.print(); log("levelOne subgroups" + levelOne.numSubGroups); for (int i = 0; i < (int) levelOne.numSubGroups; i++) { - Pair pair1 = - parseLevelTwo(serviceData, i, offset); + Pair pair1 = parseLevelTwo(serviceData, i, offset); BaseInformation node2 = pair1.first; if (node2 == null) { Log.e(TAG, "Error: parsing Level 2"); @@ -216,8 +225,7 @@ class BaseData { node2.print(); offset = pair1.second; for (int k = 0; k < node2.numSubGroups; k++) { - Pair pair2 = - parseLevelThree(serviceData, offset); + Pair pair2 = parseLevelThree(serviceData, offset); BaseInformation node3 = pair2.first; offset = pair2.second; if (node3 == null) { @@ -232,8 +240,8 @@ class BaseData { return new BaseData(levelOne, levelTwo, levelThree, numOfBISIndices); } - private static Pair - parseLevelTwo(byte[] serviceData, int groupIndex, int offset) { + private static Pair parseLevelTwo( + byte[] serviceData, int groupIndex, int offset) { log("Parsing Level 2"); BaseInformation node = new BaseInformation(); node.level = METADATA_LEVEL2; @@ -241,13 +249,16 @@ class BaseData { node.numSubGroups = serviceData[offset++]; if (serviceData[offset] == (byte) UNKNOWN_CODEC) { // Place It in the last byte of codecID - System.arraycopy(serviceData, offset, node.codecId, - METADATA_CODEC_LENGTH - 1, METADATA_UNKNOWN_CODEC_LENGTH); + System.arraycopy( + serviceData, + offset, + node.codecId, + METADATA_CODEC_LENGTH - 1, + METADATA_UNKNOWN_CODEC_LENGTH); offset += METADATA_UNKNOWN_CODEC_LENGTH; log("codecId is FE"); } else { - System.arraycopy(serviceData, offset, node.codecId, - 0, METADATA_CODEC_LENGTH); + System.arraycopy(serviceData, offset, node.codecId, 0, METADATA_CODEC_LENGTH); offset += METADATA_CODEC_LENGTH; } node.codecConfigLength = serviceData[offset++] & 0xff; @@ -265,8 +276,7 @@ class BaseData { return new Pair(node, offset); } - private static Pair - parseLevelThree(byte[] serviceData, int offset) { + private static Pair parseLevelThree(byte[] serviceData, int offset) { log("Parsing Level 3"); BaseInformation node = new BaseInformation(); node.level = METADATA_LEVEL3; @@ -280,15 +290,15 @@ class BaseData { return new Pair(node, offset); } - static void consolidateBaseofLevelTwo(ArrayList levelTwo, - ArrayList levelThree) { + static void consolidateBaseofLevelTwo( + ArrayList levelTwo, ArrayList levelThree) { int startIdx = 0; int children = 0; for (int i = 0; i < levelTwo.size(); i++) { startIdx = startIdx + children; children = children + levelTwo.get(i).numSubGroups; - consolidateBaseofLevelThree(levelTwo, levelThree, - i, startIdx, levelTwo.get(i).numSubGroups); + consolidateBaseofLevelThree( + levelTwo, levelThree, i, startIdx, levelTwo.get(i).numSubGroups); } // Eliminate Duplicates at Level 3 for (int i = 0; i < levelThree.size(); i++) { @@ -339,14 +349,21 @@ class BaseData { } } - static void consolidateBaseofLevelThree(ArrayList levelTwo, - ArrayList levelThree, int parentSubgroup, int startIdx, int numNodes) { + static void consolidateBaseofLevelThree( + ArrayList levelTwo, + ArrayList levelThree, + int parentSubgroup, + int startIdx, + int numNodes) { for (int i = startIdx; i < startIdx + numNodes || i < levelThree.size(); i++) { levelThree.get(i).subGroupId = levelTwo.get(parentSubgroup).subGroupId; log("Copy Codec Id from Level2 Parent" + parentSubgroup); System.arraycopy( levelTwo.get(parentSubgroup).consolidatedCodecId, - 0, levelThree.get(i).consolidatedCodecId, 0, 5); + 0, + levelThree.get(i).consolidatedCodecId, + 0, + 5); // Metadata clone from Parent levelThree.get(i).consolidatedMetadata = new LinkedHashSet(levelTwo.get(parentSubgroup).consolidatedMetadata); @@ -366,7 +383,7 @@ class BaseData { return mNumBISIndices; } - public BaseInformation getLevelOne() { + public BaseInformation getLevelOne() { return mLevelOne; } @@ -433,8 +450,7 @@ class BaseData { case CODEC_AUDIO_LOCATION_FRONT_RIGHT: ret = "RIGHT"; break; - case CODEC_AUDIO_LOCATION_FRONT_LEFT - | CODEC_AUDIO_LOCATION_FRONT_RIGHT: + case CODEC_AUDIO_LOCATION_FRONT_LEFT | CODEC_AUDIO_LOCATION_FRONT_RIGHT: ret = "LR"; break; } diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java index 460555aae4c..c912a8d6081 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java @@ -94,9 +94,7 @@ import java.util.Optional; import java.util.PriorityQueue; import java.util.concurrent.ConcurrentHashMap; -/** - * Broacast Assistant Scan Service - */ +/** Broacast Assistant Scan Service */ public class BassClientService extends ProfileService { private static final String TAG = BassClientService.class.getSimpleName(); private static final int MAX_BASS_CLIENT_STATE_MACHINES = 10; @@ -183,8 +181,7 @@ public class BassClientService extends ProfileService { new BluetoothEventLogger(LOG_NB_EVENTS, TAG + " event log"); ; - @VisibleForTesting - ServiceFactory mServiceFactory = new ServiceFactory(); + @VisibleForTesting ServiceFactory mServiceFactory = new ServiceFactory(); private final Handler mHandler = new Handler(Looper.getMainLooper()) { @@ -297,8 +294,16 @@ public class BassClientService extends ProfileService { if (paResMap == null || (bId != BassConstants.INVALID_BROADCAST_ID && !paResMap.containsKey(bId))) { log("PAResmap: add >>>"); - PeriodicAdvertisementResult paRes = new PeriodicAdvertisementResult(device, - addressType, syncHandle, advSid, advInterval, bId, pbData, broadcastName); + PeriodicAdvertisementResult paRes = + new PeriodicAdvertisementResult( + device, + addressType, + syncHandle, + advSid, + advInterval, + bId, + pbData, + broadcastName); if (paRes != null) { paRes.print(); mPeriodicAdvertisementResultMap.putIfAbsent(device, new HashMap<>()); @@ -415,8 +420,11 @@ public class BassClientService extends ProfileService { return; } - log("removeActiveSyncedSource, scanDelegator: " + scanDelegator + ", syncHandle: " - + syncHandle); + log( + "removeActiveSyncedSource, scanDelegator: " + + scanDelegator + + ", syncHandle: " + + syncHandle); if (syncHandle == null) { // remove all sources for this scanDelegator mActiveSourceMap.remove(scanDelegator); @@ -429,8 +437,12 @@ public class BassClientService extends ProfileService { } } } - sEventLogger.logd(TAG, "Broadcast Source Unsynced: scanDelegator= " + scanDelegator - + ", syncHandle= " + syncHandle); + sEventLogger.logd( + TAG, + "Broadcast Source Unsynced: scanDelegator= " + + scanDelegator + + ", syncHandle= " + + syncHandle); } void addActiveSyncedSource(BluetoothDevice scanDelegator, Integer syncHandle) { @@ -444,16 +456,23 @@ public class BassClientService extends ProfileService { return; } - log("addActiveSyncedSource, scanDelegator: " + scanDelegator + ", syncHandle: " - + syncHandle); + log( + "addActiveSyncedSource, scanDelegator: " + + scanDelegator + + ", syncHandle: " + + syncHandle); if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) { mActiveSourceMap.putIfAbsent(scanDelegator, new ArrayList<>()); if (!mActiveSourceMap.get(scanDelegator).contains(syncHandle)) { mActiveSourceMap.get(scanDelegator).add(syncHandle); } } - sEventLogger.logd(TAG, "Broadcast Source Synced: scanDelegator= " + scanDelegator - + ", syncHandle= " + syncHandle); + sEventLogger.logd( + TAG, + "Broadcast Source Synced: scanDelegator= " + + scanDelegator + + ", syncHandle= " + + syncHandle); } List getActiveSyncedSources(BluetoothDevice scanDelegator) { @@ -469,11 +488,16 @@ public class BassClientService extends ProfileService { List currentSources = mActiveSourceMap.get(scanDelegator); if (currentSources != null) { - log("getActiveSyncedSources: scanDelegator: " + scanDelegator - + ", sources num: " + currentSources.size()); + log( + "getActiveSyncedSources: scanDelegator: " + + scanDelegator + + ", sources num: " + + currentSources.size()); } else { - log("getActiveSyncedSources: scanDelegator: " + scanDelegator - + ", currentSources is null"); + log( + "getActiveSyncedSources: scanDelegator: " + + scanDelegator + + ", currentSources is null"); } return currentSources; } @@ -523,10 +547,14 @@ public class BassClientService extends ProfileService { if (sService != null) { throw new IllegalStateException("start() called twice"); } - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when BassClientService starts"); - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when BassClientService starts"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when BassClientService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when BassClientService starts"); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mStateMachines.clear(); @@ -726,8 +754,9 @@ public class BassClientService extends ProfileService { continue; } - boolean isAnyPendingAddSourceOperationForDevice = operations.stream() - .anyMatch(e -> e.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)); + boolean isAnyPendingAddSourceOperationForDevice = + operations.stream() + .anyMatch(e -> e.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)); if (isAnyPendingAddSourceOperationForDevice) { return true; @@ -737,10 +766,15 @@ public class BassClientService extends ProfileService { return false; } - private void checkForPendingGroupOpRequest(BluetoothDevice sink, int reason, int reqMsg, - Object obj) { - log("checkForPendingGroupOpRequest device: " + sink + ", reason: " + reason - + ", reqMsg: " + reqMsg); + private void checkForPendingGroupOpRequest( + BluetoothDevice sink, int reason, int reqMsg, Object obj) { + log( + "checkForPendingGroupOpRequest device: " + + sink + + ", reason: " + + reason + + ", reqMsg: " + + reqMsg); List> operations = mPendingGroupOp.get(sink); if (operations == null) { @@ -756,22 +790,30 @@ public class BassClientService extends ProfileService { if (isSuccess(reason)) { BluetoothLeBroadcastReceiveState sourceState = (BluetoothLeBroadcastReceiveState) obj; - boolean removed = operations.removeIf(m -> - (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)) - && (sourceState.getBroadcastId() - == ((BluetoothLeBroadcastMetadata) m.second).getBroadcastId())); + boolean removed = + operations.removeIf( + m -> + (m.first.equals( + BassClientStateMachine + .ADD_BCAST_SOURCE)) + && (sourceState.getBroadcastId() + == ((BluetoothLeBroadcastMetadata) + m.second) + .getBroadcastId())); if (removed) { setSourceGroupManaged(sink, sourceState.getSourceId(), true); - } } else { BluetoothLeBroadcastMetadata metadata = (BluetoothLeBroadcastMetadata) obj; - operations.removeIf(m -> - (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)) - && (metadata.getBroadcastId() - == ((BluetoothLeBroadcastMetadata) m.second).getBroadcastId())); - - if (!isAnyPendingAddSourceOperation() && mIsAssistantActive + operations.removeIf( + m -> + (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)) + && (metadata.getBroadcastId() + == ((BluetoothLeBroadcastMetadata) m.second) + .getBroadcastId())); + + if (!isAnyPendingAddSourceOperation() + && mIsAssistantActive && mPausedBroadcastSinks.isEmpty()) { LeAudioService leAudioService = mServiceFactory.getLeAudioService(); mIsAssistantActive = false; @@ -786,9 +828,10 @@ public class BassClientService extends ProfileService { case BassClientStateMachine.REMOVE_BCAST_SOURCE: // Identify the operation by operation type and sourceId Integer sourceId = (Integer) obj; - operations.removeIf(m -> - m.first.equals(BassClientStateMachine.REMOVE_BCAST_SOURCE) - && (sourceId.equals((Integer) m.second))); + operations.removeIf( + m -> + m.first.equals(BassClientStateMachine.REMOVE_BCAST_SOURCE) + && (sourceId.equals((Integer) m.second))); setSourceGroupManaged(sink, sourceId, false); break; default: @@ -913,14 +956,15 @@ public class BassClientService extends ProfileService { if (metadata != null) { int broadcastId = metadata.getBroadcastId(); - for (BluetoothDevice device: getTargetDeviceList(sink, true)) { + for (BluetoothDevice device : getTargetDeviceList(sink, true)) { List sources = getOrCreateStateMachine(device).getAllSources(); // For each device, find the source ID having this broadcast ID - Optional receiver = sources.stream() - .filter(e -> e.getBroadcastId() == broadcastId) - .findAny(); + Optional receiver = + sources.stream() + .filter(e -> e.getBroadcastId() == broadcastId) + .findAny(); if (receiver.isPresent()) { map.put(device, receiver.get().getSourceId()); } else { @@ -928,11 +972,15 @@ public class BassClientService extends ProfileService { map.put(device, BassConstants.INVALID_SOURCE_ID); } } - return new Pair>(metadata, map); + return new Pair>( + metadata, map); } else { - Log.e(TAG, "Couldn't find broadcast metadata for device: " - + sink.getAnonymizedAddress() + ", and sourceId:" + sourceId); + Log.e( + TAG, + "Couldn't find broadcast metadata for device: " + + sink.getAnonymizedAddress() + + ", and sourceId:" + + sourceId); } } @@ -946,8 +994,8 @@ public class BassClientService extends ProfileService { CsipSetCoordinatorService csipClient = mServiceFactory.getCsipSetCoordinatorService(); if (csipClient != null) { // Check for coordinated set of devices in the context of CAP - List csipDevices = csipClient.getGroupDevicesOrdered(device, - BluetoothUuid.CAP); + List csipDevices = + csipClient.getGroupDevicesOrdered(device, BluetoothUuid.CAP); if (!csipDevices.isEmpty()) { return csipDevices; } else { @@ -974,8 +1022,12 @@ public class BassClientService extends ProfileService { && metaData.getSourceAdvertisingSid() == state.getSourceAdvertisingSid() && metaData.getBroadcastId() == state.getBroadcastId()) { retval = false; - Log.e(TAG, "isValidBroadcastSourceAddition: fail for " + device - + " metaData: " + metaData); + Log.e( + TAG, + "isValidBroadcastSourceAddition: fail for " + + device + + " metaData: " + + metaData); break; } } @@ -993,7 +1045,7 @@ public class BassClientService extends ProfileService { } boolean isRoomAvailable = false; String emptyBluetoothDevice = "00:00:00:00:00:00"; - for (BluetoothLeBroadcastReceiveState recvState: stateMachine.getAllSources()) { + for (BluetoothLeBroadcastReceiveState recvState : stateMachine.getAllSources()) { if (recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { isRoomAvailable = true; break; @@ -1050,8 +1102,10 @@ public class BassClientService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_BASS_CLIENT_STATE_MACHINES) { - Log.e(TAG, "Maximum number of Bassclient state machines reached: " - + MAX_BASS_CLIENT_STATE_MACHINES); + Log.e( + TAG, + "Maximum number of Bassclient state machines reached: " + + MAX_BASS_CLIENT_STATE_MACHINES); return null; } log("Creating a new state machine for " + device); @@ -1123,8 +1177,9 @@ public class BassClientService extends ProfileService { synchronized (mStateMachines) { BassClientStateMachine sm = mStateMachines.get(device); if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); + Log.w( + TAG, + "removeStateMachine: device " + device + " does not have a state machine"); return; } log("removeStateMachine: removing state machine for device: " + device); @@ -1167,8 +1222,11 @@ public class BassClientService extends ProfileService { synchronized (mStateMachines) { BassClientStateMachine stateMachine = getOrCreateStateMachine(device); if (stateMachine == null) { - Log.w(TAG, "informConnectedDeviceAboutScanOffloadStop: Can't get state " - + "machine for device: " + device); + Log.w( + TAG, + "informConnectedDeviceAboutScanOffloadStop: Can't get state " + + "machine for device: " + + device); continue; } stateMachine.sendMessage(BassClientStateMachine.STOP_SCAN_OFFLOAD); @@ -1224,16 +1282,21 @@ public class BassClientService extends ProfileService { mHandler.post(() -> connectionStateChanged(device, fromState, toState)); } - synchronized void connectionStateChanged(BluetoothDevice device, int fromState, - int toState) { + synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { if (!isAvailable()) { Log.w(TAG, "connectionStateChanged: service is not available"); return; } if ((device == null) || (fromState == toState)) { - Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device - + " fromState=" + fromState + " toState=" + toState); + Log.e( + TAG, + "connectionStateChanged: unexpected invocation. device=" + + device + + " fromState=" + + fromState + + " toState=" + + toState); return; } @@ -1389,6 +1452,7 @@ public class BassClientService extends ProfileService { /** * Get a list of all LE Audio Broadcast Sinks with the specified connection states. + * * @param states states array representing the connection states * @return a list of devices that match the provided connection states */ @@ -1404,8 +1468,7 @@ public class BassClientService extends ProfileService { synchronized (mStateMachines) { for (BluetoothDevice device : bondedDevices) { final ParcelUuid[] featureUuids = device.getUuids(); - if (!Utils.arrayContains( - featureUuids, BluetoothUuid.BASS)) { + if (!Utils.arrayContains(featureUuids, BluetoothUuid.BASS)) { continue; } int connectionState = BluetoothProfile.STATE_DISCONNECTED; @@ -1426,6 +1489,7 @@ public class BassClientService extends ProfileService { /** * Get a list of all LE Audio Broadcast Sinks connected with the LE Audio Broadcast Assistant. + * * @return list of connected devices */ public List getConnectedDevices() { @@ -1444,10 +1508,9 @@ public class BassClientService extends ProfileService { /** * Set the connectionPolicy of the Broadcast Audio Scan Service profile. * - *

The connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be one of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -1456,8 +1519,8 @@ public class BassClientService extends ProfileService { public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); boolean setSuccessfully = - mDatabaseManager.setProfileConnectionPolicy(device, - BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, connectionPolicy); + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, connectionPolicy); if (setSuccessfully && connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { connect(device); } else if (setSuccessfully @@ -1470,17 +1533,16 @@ public class BassClientService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device paired bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + return mDatabaseManager.getProfileConnectionPolicy( + device, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); } /** @@ -1619,29 +1681,35 @@ public class BassClientService extends ProfileService { if (mPeriodicAdvertisementResultMap != null) { clearNotifiedFlags(); } - ScanSettings settings = new ScanSettings.Builder().setCallbackType( - ScanSettings.CALLBACK_TYPE_ALL_MATCHES) - .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) - .setLegacy(false) - .build(); + ScanSettings settings = + new ScanSettings.Builder() + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) + .setLegacy(false) + .build(); if (filters == null) { filters = new ArrayList(); } if (!BassUtils.containUuid(filters, BassConstants.BAAS_UUID)) { - byte[] serviceData = {0x00, 0x00 ,0x00}; // Broadcast_ID + byte[] serviceData = {0x00, 0x00, 0x00}; // Broadcast_ID byte[] serviceDataMask = {0x00, 0x00, 0x00}; - filters.add(new ScanFilter.Builder() - .setServiceData(BassConstants.BAAS_UUID, - serviceData, serviceDataMask).build()); + filters.add( + new ScanFilter.Builder() + .setServiceData( + BassConstants.BAAS_UUID, serviceData, serviceDataMask) + .build()); } for (BluetoothDevice device : getConnectedDevices()) { synchronized (mStateMachines) { BassClientStateMachine stateMachine = getOrCreateStateMachine(device); if (stateMachine == null) { - Log.w(TAG, "startSearchingForSources: Can't get state machine for " - + "device: " + device); + Log.w( + TAG, + "startSearchingForSources: Can't get state machine for " + + "device: " + + device); continue; } stateMachine.sendMessage(BassClientStateMachine.START_SCAN_OFFLOAD); @@ -1654,9 +1722,7 @@ public class BassClientService extends ProfileService { } } - /** - * Stops an ongoing search for nearby Broadcast Sources - */ + /** Stops an ongoing search for nearby Broadcast Sources */ public void stopSearchingForSources() { log("stopSearchingForSources"); if (mBluetoothAdapter == null) { @@ -1718,6 +1784,7 @@ public class BassClientService extends ProfileService { /** * Return true if a search has been started by this application + * * @return true if a search has been started by this application */ public boolean isSearchInProgress() { @@ -2241,8 +2308,8 @@ public class BassClientService extends ProfileService { Log.e(TAG, "Can't get state machine for device: " + sink); return; } - Message message = stateMachine.obtainMessage( - BassClientStateMachine.SELECT_BCAST_SOURCE); + Message message = + stateMachine.obtainMessage(BassClientStateMachine.SELECT_BCAST_SOURCE); message.obj = result; message.arg1 = autoTrigger ? BassConstants.AUTO : BassConstants.USER; stateMachine.sendMessage(message); @@ -2258,9 +2325,7 @@ public class BassClientService extends ProfileService { * coordinated set members, False otherwise */ public void addSource( - BluetoothDevice sink, - BluetoothLeBroadcastMetadata sourceMetadata, - boolean isGroupOp) { + BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata, boolean isGroupOp) { log( "addSource: " + ("device: " + sink) @@ -2333,14 +2398,14 @@ public class BassClientService extends ProfileService { BassClientStateMachine stateMachine = getOrCreateStateMachine(device); if (stateMachine == null) { log("addSource: Error bad parameter: no state machine for " + device); - mCallbacks.notifySourceAddFailed(device, sourceMetadata, - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + mCallbacks.notifySourceAddFailed( + device, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); continue; } if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) { log("addSource: device is not connected"); - mCallbacks.notifySourceAddFailed(device, sourceMetadata, - BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); + mCallbacks.notifySourceAddFailed( + device, sourceMetadata, BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); continue; } if (stateMachine.hasPendingSourceOperation()) { @@ -2395,16 +2460,20 @@ public class BassClientService extends ProfileService { } if (!isValidBroadcastSourceAddition(device, sourceMetadata)) { log("addSource: not a valid broadcast source addition"); - mCallbacks.notifySourceAddFailed(device, sourceMetadata, + mCallbacks.notifySourceAddFailed( + device, + sourceMetadata, BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_DUPLICATE_ADDITION); continue; } if ((code != null) && (code.length != 0)) { if ((code.length > 16) || (code.length < 4)) { - log("Invalid broadcast code length: " + code.length - + ", should be between 4 and 16 octets"); - mCallbacks.notifySourceAddFailed(device, sourceMetadata, - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + log( + "Invalid broadcast code length: " + + code.length + + ", should be between 4 and 16 octets"); + mCallbacks.notifySourceAddFailed( + device, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); continue; } } @@ -2413,8 +2482,8 @@ public class BassClientService extends ProfileService { mBroadcastMetadataMap.put(device, sourceMetadata); if (isGroupOp) { - enqueueSourceGroupOp(device, BassClientStateMachine.ADD_BCAST_SOURCE, - sourceMetadata); + enqueueSourceGroupOp( + device, BassClientStateMachine.ADD_BCAST_SOURCE, sourceMetadata); } sEventLogger.logd( @@ -2463,8 +2532,8 @@ public class BassClientService extends ProfileService { if (updatedMetadata == null) { log("modifySource: Error bad parameters: updatedMetadata cannot be null"); for (BluetoothDevice device : devices.keySet()) { - mCallbacks.notifySourceModifyFailed(device, sourceId, - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + mCallbacks.notifySourceModifyFailed( + device, sourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); } return; } @@ -2520,8 +2589,7 @@ public class BassClientService extends ProfileService { /** * Removes the Broadcast Source from a Broadcast Sink * - * @param sink representing the Broadcast Sink from which a Broadcast - * Source should be removed + * @param sink representing the Broadcast Sink from which a Broadcast Source should be removed * @param sourceId source ID as delivered in onSourceAdded */ public void removeSource(BluetoothDevice sink, int sourceId) { @@ -2540,20 +2608,22 @@ public class BassClientService extends ProfileService { if (stateMachine == null) { log("removeSource: Error bad parameters: device = " + device); - mCallbacks.notifySourceRemoveFailed(device, sourceId, - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + mCallbacks.notifySourceRemoveFailed( + device, sourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); continue; } if (deviceSourceId == BassConstants.INVALID_SOURCE_ID) { log("removeSource: no such sourceId for device: " + device); - mCallbacks.notifySourceRemoveFailed(device, sourceId, + mCallbacks.notifySourceRemoveFailed( + device, + sourceId, BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_INVALID_SOURCE_ID); continue; } if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) { log("removeSource: device is not connected"); - mCallbacks.notifySourceRemoveFailed(device, sourceId, - BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); + mCallbacks.notifySourceRemoveFailed( + device, sourceId, BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); continue; } @@ -2569,8 +2639,8 @@ public class BassClientService extends ProfileService { + (", broadcastName: " + metaData.getBroadcastName())); log("Force source to lost PA sync"); - Message message = stateMachine.obtainMessage( - BassClientStateMachine.UPDATE_BCAST_SOURCE); + Message message = + stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE); message.arg1 = sourceId; message.arg2 = BassConstants.PA_SYNC_DO_NOT_SYNC; /* Pending remove set. Remove source once not synchronized to PA */ @@ -2581,8 +2651,7 @@ public class BassClientService extends ProfileService { } sEventLogger.logd( - TAG, - "Remove Broadcast Source: device: " + device + ", sourceId: " + sourceId); + TAG, "Remove Broadcast Source: device: " + device + ", sourceId: " + sourceId); Message message = stateMachine.obtainMessage(BassClientStateMachine.REMOVE_BCAST_SOURCE); @@ -2593,7 +2662,9 @@ public class BassClientService extends ProfileService { for (Map.Entry deviceSourceIdPair : devices.entrySet()) { BluetoothDevice device = deviceSourceIdPair.getKey(); Integer deviceSourceId = deviceSourceIdPair.getValue(); - enqueueSourceGroupOp(device, BassClientStateMachine.REMOVE_BCAST_SOURCE, + enqueueSourceGroupOp( + device, + BassClientStateMachine.REMOVE_BCAST_SOURCE, Integer.valueOf(deviceSourceId)); } } @@ -2614,7 +2685,7 @@ public class BassClientService extends ProfileService { } List recvStates = new ArrayList(); - for (BluetoothLeBroadcastReceiveState rs: stateMachine.getAllSources()) { + for (BluetoothLeBroadcastReceiveState rs : stateMachine.getAllSources()) { String emptyBluetoothDevice = "00:00:00:00:00:00"; if (!rs.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { recvStates.add(rs); @@ -2773,7 +2844,6 @@ public class BassClientService extends ProfileService { if (leAudioService != null) { leAudioService.activeBroadcastAssistantNotification(true); } - } return false; @@ -3108,9 +3178,7 @@ public class BassClientService extends ProfileService { } } - /** - * Callback handler - */ + /** Callback handler */ static class Callbacks extends Handler { private static final int MSG_SEARCH_STARTED = 1; private static final int MSG_SEARCH_STARTED_FAILED = 2; @@ -3126,8 +3194,8 @@ public class BassClientService extends ProfileService { private static final int MSG_RECEIVESTATE_CHANGED = 12; private static final int MSG_SOURCE_LOST = 13; - private final RemoteCallbackList - mCallbacks = new RemoteCallbackList<>(); + private final RemoteCallbackList mCallbacks = + new RemoteCallbackList<>(); Callbacks(Looper looper) { super(looper); @@ -3155,14 +3223,17 @@ public class BassClientService extends ProfileService { case MSG_SOURCE_ADDED_FAILED: ObjParams param = (ObjParams) msg.obj; sink = (BluetoothDevice) param.mObj1; - sService.checkForPendingGroupOpRequest(sink, reason, - BassClientStateMachine.ADD_BCAST_SOURCE, param.mObj2); + sService.checkForPendingGroupOpRequest( + sink, reason, BassClientStateMachine.ADD_BCAST_SOURCE, param.mObj2); break; case MSG_SOURCE_REMOVED: case MSG_SOURCE_REMOVED_FAILED: sink = (BluetoothDevice) msg.obj; - sService.checkForPendingGroupOpRequest(sink, reason, - BassClientStateMachine.REMOVE_BCAST_SOURCE, Integer.valueOf(msg.arg2)); + sService.checkForPendingGroupOpRequest( + sink, + reason, + BassClientStateMachine.REMOVE_BCAST_SOURCE, + Integer.valueOf(msg.arg2)); break; default: break; @@ -3188,14 +3259,15 @@ public class BassClientService extends ProfileService { private class ObjParams { Object mObj1; Object mObj2; + ObjParams(Object o1, Object o2) { mObj1 = o1; mObj2 = o2; } } - private void invokeCallback(IBluetoothLeBroadcastAssistantCallback callback, - Message msg) throws RemoteException { + private void invokeCallback(IBluetoothLeBroadcastAssistantCallback callback, Message msg) + throws RemoteException { final int reason = msg.arg1; final int sourceId = msg.arg2; ObjParams param; @@ -3296,8 +3368,8 @@ public class BassClientService extends ProfileService { obtainMessage(MSG_SOURCE_FOUND, 0, 0, source).sendToTarget(); } - void notifySourceAdded(BluetoothDevice sink, BluetoothLeBroadcastReceiveState recvState, - int reason) { + void notifySourceAdded( + BluetoothDevice sink, BluetoothLeBroadcastReceiveState recvState, int reason) { sService.localNotifySourceAdded(sink, recvState); sEventLogger.logd( @@ -3314,8 +3386,8 @@ public class BassClientService extends ProfileService { obtainMessage(MSG_SOURCE_ADDED, reason, recvState.getSourceId(), param).sendToTarget(); } - void notifySourceAddFailed(BluetoothDevice sink, BluetoothLeBroadcastMetadata source, - int reason) { + void notifySourceAddFailed( + BluetoothDevice sink, BluetoothLeBroadcastMetadata source, int reason) { sEventLogger.loge( TAG, "notifySourceAddFailed: sink: " @@ -3379,8 +3451,8 @@ public class BassClientService extends ProfileService { obtainMessage(MSG_SOURCE_REMOVED_FAILED, reason, sourceId, sink).sendToTarget(); } - void notifyReceiveStateChanged(BluetoothDevice sink, int sourceId, - BluetoothLeBroadcastReceiveState state) { + void notifyReceiveStateChanged( + BluetoothDevice sink, int sourceId, BluetoothLeBroadcastReceiveState state) { ObjParams param = new ObjParams(sink, state); sService.localNotifyReceiveStateChanged(sink); @@ -3632,7 +3704,8 @@ public class BassClientService extends ProfileService { @Override public void addSource( - BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata, + BluetoothDevice sink, + BluetoothLeBroadcastMetadata sourceMetadata, boolean isGroupOp) { try { BassClientService service = getService(); diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java index 546102bc742..a93cb568937 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java @@ -78,10 +78,8 @@ import java.util.stream.IntStream; @VisibleForTesting public class BassClientStateMachine extends StateMachine { private static final String TAG = "BassClientStateMachine"; - @VisibleForTesting - static final byte[] REMOTE_SCAN_STOP = {00}; - @VisibleForTesting - static final byte[] REMOTE_SCAN_START = {01}; + @VisibleForTesting static final byte[] REMOTE_SCAN_STOP = {00}; + @VisibleForTesting static final byte[] REMOTE_SCAN_START = {01}; private static final byte OPCODE_ADD_SOURCE = 0x02; private static final byte OPCODE_UPDATE_SOURCE = 0x03; private static final byte OPCODE_SET_BCAST_PIN = 0x04; @@ -108,8 +106,7 @@ public class BassClientStateMachine extends StateMachine { static final int CANCEL_PENDING_SOURCE_OPERATION = 18; // NOTE: the value is not "final" - it is modified in the unit tests - @VisibleForTesting - private int mConnectTimeoutMs; + @VisibleForTesting private int mConnectTimeoutMs; // Type of argument for set broadcast code operation static final int ARGTYPE_METADATA = 1; @@ -122,7 +119,7 @@ public class BassClientStateMachine extends StateMachine { /*key is combination of sourceId, Address and advSid for this hashmap*/ private final Map mBluetoothLeBroadcastReceiveStates = - new HashMap(); + new HashMap(); private final Map mCurrentMetadata = new HashMap(); private final Disconnected mDisconnected = new Disconnected(); private final Connected mConnected = new Connected(); @@ -134,46 +131,33 @@ public class BassClientStateMachine extends StateMachine { @VisibleForTesting final List mBroadcastCharacteristics = new ArrayList(); - @VisibleForTesting - BluetoothDevice mDevice; + + @VisibleForTesting BluetoothDevice mDevice; private boolean mIsAllowedList = false; private int mLastConnectionState = -1; - @VisibleForTesting - boolean mMTUChangeRequested = false; - @VisibleForTesting - boolean mDiscoveryInitiated = false; - @VisibleForTesting - BassClientService mService; + @VisibleForTesting boolean mMTUChangeRequested = false; + @VisibleForTesting boolean mDiscoveryInitiated = false; + @VisibleForTesting BassClientService mService; AdapterService mAdapterService; - @VisibleForTesting - BluetoothGattCharacteristic mBroadcastScanControlPoint; + @VisibleForTesting BluetoothGattCharacteristic mBroadcastScanControlPoint; private final Map mFirstTimeBisDiscoveryMap; private int mPASyncRetryCounter = 0; - @VisibleForTesting - int mNumOfBroadcastReceiverStates = 0; - @VisibleForTesting - int mPendingOperation = -1; - @VisibleForTesting - byte mPendingSourceId = -1; - @VisibleForTesting - BluetoothLeBroadcastMetadata mPendingMetadata = null; + @VisibleForTesting int mNumOfBroadcastReceiverStates = 0; + @VisibleForTesting int mPendingOperation = -1; + @VisibleForTesting byte mPendingSourceId = -1; + @VisibleForTesting BluetoothLeBroadcastMetadata mPendingMetadata = null; private BluetoothLeBroadcastMetadata mSetBroadcastPINMetadata = null; - @VisibleForTesting - boolean mSetBroadcastCodePending = false; + @VisibleForTesting boolean mSetBroadcastCodePending = false; private final Map mPendingRemove = new HashMap(); - @VisibleForTesting - boolean mAutoTriggered = false; + @VisibleForTesting boolean mAutoTriggered = false; private boolean mDefNoPAS = false; private boolean mForceSB = false; - @VisibleForTesting - BluetoothLeBroadcastMetadata mPendingSourceToAdd = null; + @VisibleForTesting BluetoothLeBroadcastMetadata mPendingSourceToAdd = null; private int mBroadcastSourceIdLength = 3; - @VisibleForTesting - byte mNextSourceId = 0; + @VisibleForTesting byte mNextSourceId = 0; private boolean mAllowReconnect = false; - @VisibleForTesting - BluetoothGattTestableWrapper mBluetoothGatt = null; + @VisibleForTesting BluetoothGattTestableWrapper mBluetoothGatt = null; BluetoothGattCallback mGattCallback = null; @VisibleForTesting PeriodicAdvertisingCallback mLocalPeriodicAdvCallback = new PACallback(); int mMaxSingleAttributeWriteValueLen = 0; @@ -197,12 +181,19 @@ public class BassClientStateMachine extends StateMachine { setInitialState(mDisconnected); mFirstTimeBisDiscoveryMap = new HashMap(); long token = Binder.clearCallingIdentity(); - mIsAllowedList = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, - "persist.vendor.service.bt.wl", true); - mDefNoPAS = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, - "persist.vendor.service.bt.defNoPAS", false); - mForceSB = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, - "persist.vendor.service.bt.forceSB", false); + mIsAllowedList = + DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_BLUETOOTH, "persist.vendor.service.bt.wl", true); + mDefNoPAS = + DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_BLUETOOTH, + "persist.vendor.service.bt.defNoPAS", + false); + mForceSB = + DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_BLUETOOTH, + "persist.vendor.service.bt.forceSB", + false); Binder.restoreCallingIdentity(token); } @@ -282,8 +273,8 @@ public class BassClientStateMachine extends StateMachine { return mCurrentMetadata.getOrDefault(sourceId, null); } - private void setCurrentBroadcastMetadata(Integer sourceId, - BluetoothLeBroadcastMetadata metadata) { + private void setCurrentBroadcastMetadata( + Integer sourceId, BluetoothLeBroadcastMetadata metadata) { if (metadata != null) { mCurrentMetadata.put(sourceId, metadata); } else { @@ -311,9 +302,12 @@ public class BassClientStateMachine extends StateMachine { BluetoothDevice device = currentSources.get(i).getSourceDevice(); if (device != null && device.equals(srcDevice)) { state = currentSources.get(i); - Log.e(TAG, + Log.e( + TAG, "getBroadcastReceiveStateForSourceDevice: returns for: " - + srcDevice + "&srcInfo" + state); + + srcDevice + + "&srcInfo" + + state); return state; } } @@ -388,8 +382,11 @@ public class BassClientStateMachine extends StateMachine { Map bmsAdvDataMap = record.getServiceData(); if (bmsAdvDataMap != null) { for (Map.Entry entry : bmsAdvDataMap.entrySet()) { - log("ParcelUUid = " + entry.getKey() + ", Value = " - + Arrays.toString(entry.getValue())); + log( + "ParcelUUid = " + + entry.getKey() + + ", Value = " + + Arrays.toString(entry.getValue())); } } byte[] advData = record.getServiceData(BassConstants.BASIC_AUDIO_UUID); @@ -459,8 +456,7 @@ public class BassClientStateMachine extends StateMachine { broadcastId = BassUtils.parseBroadcastId(bId); } if (listOfUuids.containsKey(BassConstants.PUBLIC_BROADCAST_UUID)) { - byte[] pbAnnouncement = - listOfUuids.get(BassConstants.PUBLIC_BROADCAST_UUID); + byte[] pbAnnouncement = listOfUuids.get(BassConstants.PUBLIC_BROADCAST_UUID); pbData = PublicBroadcastData.parsePublicBroadcastData(pbAnnouncement); } } @@ -599,15 +595,13 @@ public class BassClientStateMachine extends StateMachine { "Should never be executed with" + " leaudioBroadcastExtractPeriodicScannerFromStateMachine flag"); } - BluetoothLeBroadcastMetadata.Builder metaData = - new BluetoothLeBroadcastMetadata.Builder(); + BluetoothLeBroadcastMetadata.Builder metaData = new BluetoothLeBroadcastMetadata.Builder(); int index = 0; for (BaseData.BaseInformation baseLevel2 : baseData.getLevelTwo()) { BluetoothLeBroadcastSubgroup.Builder subGroup = new BluetoothLeBroadcastSubgroup.Builder(); - for (int j = 0; j < baseLevel2.numSubGroups; j ++) { - BaseData.BaseInformation baseLevel3 = - baseData.getLevelThree().get(index++); + for (int j = 0; j < baseLevel2.numSubGroups; j++) { + BaseData.BaseInformation baseLevel3 = baseData.getLevelThree().get(index++); BluetoothLeBroadcastChannel.Builder channel = new BluetoothLeBroadcastChannel.Builder(); channel.setChannelIndex(baseLevel3.index); @@ -624,11 +618,12 @@ public class BassClientStateMachine extends StateMachine { subGroup.addChannel(channel.build()); } byte[] arrayCodecId = baseLevel2.codecId; - long codeId = ((long) (arrayCodecId[4] & 0xff)) << 32 - | (arrayCodecId[3] & 0xff) << 24 - | (arrayCodecId[2] & 0xff) << 16 - | (arrayCodecId[1] & 0xff) << 8 - | (arrayCodecId[0] & 0xff); + long codeId = + ((long) (arrayCodecId[4] & 0xff)) << 32 + | (arrayCodecId[3] & 0xff) << 24 + | (arrayCodecId[2] & 0xff) << 16 + | (arrayCodecId[1] & 0xff) << 8 + | (arrayCodecId[0] & 0xff); subGroup.setCodecId(codeId); try { subGroup.setCodecSpecificConfig( @@ -697,8 +692,7 @@ public class BassClientStateMachine extends StateMachine { return metaData.build(); } - private void broadcastReceiverState( - BluetoothLeBroadcastReceiveState state, int sourceId) { + private void broadcastReceiverState(BluetoothLeBroadcastReceiveState state, int sourceId) { log("broadcastReceiverState: " + mDevice); mService.getCallbacks().notifyReceiveStateChanged(mDevice, sourceId, state); } @@ -726,14 +720,20 @@ public class BassClientStateMachine extends StateMachine { if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) { serviceData = 0x000000FF & recvState.getSourceId(); serviceData = serviceData << 8; - //advA matches EXT_ADV_ADDRESS - //also matches source address (as we would have written) - serviceData = serviceData - & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS); - serviceData = serviceData - & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS); - log("Initiate PAST for: " + mDevice + ", syncHandle: " + syncHandle - + "serviceData" + serviceData); + // advA matches EXT_ADV_ADDRESS + // also matches source address (as we would have written) + serviceData = + serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS); + serviceData = + serviceData + & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS); + log( + "Initiate PAST for: " + + mDevice + + ", syncHandle: " + + syncHandle + + "serviceData" + + serviceData); BluetoothMethodProxy.getInstance() .periodicAdvertisingManagerTransferSync( BassClientPeriodicAdvertisingManager @@ -750,11 +750,15 @@ public class BassClientStateMachine extends StateMachine { serviceData = 0x000000FF & recvState.getSourceId(); serviceData = serviceData << 8; // Address we set in the Source Address can differ from the address in the air - serviceData = serviceData - | BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS; - log("Initiate local broadcast PAST for: " + mDevice - + ", advSID/Handle: " + advHandle - + ", serviceData: " + serviceData); + serviceData = + serviceData | BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS; + log( + "Initiate local broadcast PAST for: " + + mDevice + + ", advSID/Handle: " + + advHandle + + ", serviceData: " + + serviceData); BluetoothMethodProxy.getInstance() .periodicAdvertisingManagerTransferSetInfo( BassClientPeriodicAdvertisingManager @@ -775,12 +779,11 @@ public class BassClientStateMachine extends StateMachine { // non colocated case, Broadcast PIN should have been updated from lyaer // If there is pending one process it Now if (recvState.getBigEncryptionState() - == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED + == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED && mSetBroadcastCodePending) { log("Update the Broadcast now"); if (mSetBroadcastPINMetadata != null) { - setCurrentBroadcastMetadata(recvState.getSourceId(), - mSetBroadcastPINMetadata); + setCurrentBroadcastMetadata(recvState.getSourceId(), mSetBroadcastPINMetadata); } Message m = obtainMessage(BassClientStateMachine.SET_BCAST_CODE); m.obj = recvState; @@ -791,8 +794,7 @@ public class BassClientStateMachine extends StateMachine { } } - private BluetoothLeBroadcastReceiveState parseBroadcastReceiverState( - byte[] receiverState) { + private BluetoothLeBroadcastReceiveState parseBroadcastReceiverState(byte[] receiverState) { byte sourceId = 0; if (receiverState.length > 0) { sourceId = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ID_IDX]; @@ -864,16 +866,20 @@ public class BassClientStateMachine extends StateMachine { BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE); badBroadcastCodeLen = BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE; } - byte numSubGroups = receiverState[BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX - + badBroadcastCodeLen]; - int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX - + badBroadcastCodeLen + 1; + byte numSubGroups = + receiverState[ + BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX + badBroadcastCodeLen]; + int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX + badBroadcastCodeLen + 1; ArrayList metadataList = new ArrayList(); ArrayList bisSyncState = new ArrayList(); for (int i = 0; i < numSubGroups; i++) { byte[] bisSyncIndex = new byte[BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE]; - System.arraycopy(receiverState, offset, bisSyncIndex, 0, + System.arraycopy( + receiverState, + offset, + bisSyncIndex, + 0, BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE); offset += BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE; bisSyncState.add((long) Utils.byteArrayToInt(bisSyncIndex)); @@ -904,26 +910,27 @@ public class BassClientStateMachine extends StateMachine { sourceAddress, 0, BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE); - byte sourceAddressType = receiverState[BassConstants - .BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX]; + byte sourceAddressType = + receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX]; BassUtils.reverse(sourceAddress); String address = Utils.getAddressStringFromByte(sourceAddress); BluetoothDevice device = BluetoothAdapter.getDefaultAdapter() .getRemoteLeDevice(address, sourceAddressType); byte sourceAdvSid = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADV_SID_IDX]; - recvState = new BluetoothLeBroadcastReceiveState( - sourceId, - (int) sourceAddressType, - device, - sourceAdvSid, - broadcastId, - (int) paSyncState, - (int) bigEncryptionStatus, - badBroadcastCode, - numSubGroups, - bisSyncState, - metadataList); + recvState = + new BluetoothLeBroadcastReceiveState( + sourceId, + (int) sourceAddressType, + device, + sourceAdvSid, + broadcastId, + (int) paSyncState, + (int) bigEncryptionStatus, + badBroadcastCode, + numSubGroups, + bisSyncState, + metadataList); } return recvState; } @@ -931,8 +938,7 @@ public class BassClientStateMachine extends StateMachine { private void processBroadcastReceiverState( byte[] receiverState, BluetoothGattCharacteristic characteristic) { log("processBroadcastReceiverState: characteristic:" + characteristic); - BluetoothLeBroadcastReceiveState recvState = parseBroadcastReceiverState( - receiverState); + BluetoothLeBroadcastReceiveState recvState = parseBroadcastReceiverState(receiverState); if (recvState == null) { log("processBroadcastReceiverState: Null recvState"); return; @@ -1004,8 +1010,11 @@ public class BassClientStateMachine extends StateMachine { mPendingMetadata = null; } removeMessages(CANCEL_PENDING_SOURCE_OPERATION); - mService.getCallbacks().notifySourceModified(mDevice, - recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + mService.getCallbacks() + .notifySourceModified( + mDevice, + recvState.getSourceId(), + BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); @@ -1034,8 +1043,9 @@ public class BassClientStateMachine extends StateMachine { if (mService.okToConnect(mDevice)) { log("Bassclient Connected to: " + mDevice); if (mBluetoothGatt != null) { - log("Attempting to start service discovery:" - + mBluetoothGatt.discoverServices()); + log( + "Attempting to start service discovery:" + + mBluetoothGatt.discoverServices()); mDiscoveryInitiated = true; } } else if (mBluetoothGatt != null) { @@ -1068,8 +1078,12 @@ public class BassClientStateMachine extends StateMachine { mBluetoothGatt.requestMtu(BassConstants.BASS_MAX_BYTES); mMTUChangeRequested = true; } else { - Log.w(TAG, "onServicesDiscovered received: " - + status + "mBluetoothGatt" + mBluetoothGatt); + Log.w( + TAG, + "onServicesDiscovered received: " + + status + + "mBluetoothGatt" + + mBluetoothGatt); } } else { log("remote initiated callback"); @@ -1078,23 +1092,24 @@ public class BassClientStateMachine extends StateMachine { @Override public void onCharacteristicRead( - BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic, - int status) { - if (status == BluetoothGatt.GATT_SUCCESS && characteristic.getUuid() - .equals(BassConstants.BASS_BCAST_RECEIVER_STATE)) { + BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if (status == BluetoothGatt.GATT_SUCCESS + && characteristic.getUuid().equals(BassConstants.BASS_BCAST_RECEIVER_STATE)) { log("onCharacteristicRead: BASS_BCAST_RECEIVER_STATE: status" + status); if (characteristic.getValue() == null) { Log.e(TAG, "Remote receiver state is NULL"); return; } - logByteArray("Received ", characteristic.getValue(), 0, + logByteArray( + "Received ", + characteristic.getValue(), + 0, characteristic.getValue().length); processBroadcastReceiverState(characteristic.getValue(), characteristic); } // switch to receiving notifications after initial characteristic read - BluetoothGattDescriptor desc = characteristic - .getDescriptor(BassConstants.CLIENT_CHARACTERISTIC_CONFIG); + BluetoothGattDescriptor desc = + characteristic.getDescriptor(BassConstants.CLIENT_CHARACTERISTIC_CONFIG); if (mBluetoothGatt != null && desc != null) { log("Setting the value for Desc"); mBluetoothGatt.setCharacteristicNotification(characteristic, true); @@ -1124,8 +1139,7 @@ public class BassClientStateMachine extends StateMachine { acquireAllBassChars(); mMTUChangeRequested = false; } else { - log("onMtuChanged is remote initiated trigger, mBluetoothGatt:" - + mBluetoothGatt); + log("onMtuChanged is remote initiated trigger, mBluetoothGatt:" + mBluetoothGatt); } if (status == BluetoothGatt.GATT_SUCCESS) { @@ -1147,8 +1161,8 @@ public class BassClientStateMachine extends StateMachine { } @Override - public void onCharacteristicWrite(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic, int status) { + public void onCharacteristicWrite( + BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { Message m = obtainMessage(GATT_TXN_PROCESSED); m.arg1 = status; sendMessage(m); @@ -1170,12 +1184,19 @@ public class BassClientStateMachine extends StateMachine { "Should never be executed with" + " leaudioBroadcastExtractPeriodicScannerFromStateMachine flag"); } - log("onSyncEstablished syncHandle: " + syncHandle - + ", device: " + device - + ", advertisingSid: " + advertisingSid - + ", skip: " + skip - + ", timeout: " + timeout - + ", status: " + status); + log( + "onSyncEstablished syncHandle: " + + syncHandle + + ", device: " + + device + + ", advertisingSid: " + + advertisingSid + + ", skip: " + + skip + + ", timeout: " + + timeout + + ", status: " + + status); if (status == BluetoothGatt.GATT_SUCCESS) { // updates syncHandle, advSid // set other fields as invalid or null @@ -1190,8 +1211,7 @@ public class BassClientStateMachine extends StateMachine { null); removeMessages(PSYNC_ACTIVE_TIMEOUT); // Refresh sync timeout if another source synced - sendMessageDelayed( - PSYNC_ACTIVE_TIMEOUT, BassConstants.PSYNC_ACTIVE_TIMEOUT_MS); + sendMessageDelayed(PSYNC_ACTIVE_TIMEOUT, BassConstants.PSYNC_ACTIVE_TIMEOUT_MS); mService.addActiveSyncedSource(mDevice, syncHandle); // update valid sync handle in mPeriodicAdvCallbacksMap @@ -1299,8 +1319,7 @@ public class BassClientStateMachine extends StateMachine { @Override public void onSyncTransferred(BluetoothDevice device, int status) { - log("onSyncTransferred: device=" + device + - " ,status =" + status); + log("onSyncTransferred: device=" + device + " ,status =" + status); } } @@ -1315,11 +1334,16 @@ public class BassClientStateMachine extends StateMachine { mGattCallback = new GattCallback(); } - BluetoothGatt gatt = mDevice.connectGatt(mService, autoConnect, - mGattCallback, BluetoothDevice.TRANSPORT_LE, - (BluetoothDevice.PHY_LE_1M_MASK - | BluetoothDevice.PHY_LE_2M_MASK - | BluetoothDevice.PHY_LE_CODED_MASK), null); + BluetoothGatt gatt = + mDevice.connectGatt( + mService, + autoConnect, + mGattCallback, + BluetoothDevice.TRANSPORT_LE, + (BluetoothDevice.PHY_LE_1M_MASK + | BluetoothDevice.PHY_LE_2M_MASK + | BluetoothDevice.PHY_LE_CODED_MASK), + null); if (gatt != null) { mBluetoothGatt = new BluetoothGattTestableWrapper(gatt); @@ -1328,9 +1352,7 @@ public class BassClientStateMachine extends StateMachine { return mBluetoothGatt != null; } - /** - * getAllSources - */ + /** getAllSources */ public List getAllSources() { List list = new ArrayList(mBluetoothLeBroadcastReceiveStates.values()); return list; @@ -1358,8 +1380,10 @@ public class BassClientStateMachine extends StateMachine { if (((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) || ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0)) { - Log.w(TAG, "Broadcast Audio Scan Control Point characteristic has invalid " - + "properties!"); + Log.w( + TAG, + "Broadcast Audio Scan Control Point characteristic has invalid " + + "properties!"); } else { mBroadcastScanControlPoint = allChars.get(i); log("Index of ScanCtrlPoint:" + i); @@ -1395,8 +1419,11 @@ public class BassClientStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - log("Enter Disconnected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Enter Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); clearCharsCache(); mNextSourceId = 0; removeDeferredMessages(DISCONNECT); @@ -1416,15 +1443,21 @@ public class BassClientStateMachine extends StateMachine { @Override public void exit() { - log("Exit Disconnected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected process message(" + mDevice - + "): " + messageWhatToString(message.what)); + log( + "Disconnected process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: log("Connecting to " + mDevice); @@ -1478,8 +1511,11 @@ public class BassClientStateMachine extends StateMachine { class Connecting extends State { @Override public void enter() { - log("Enter Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Enter Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, mDevice, mConnectTimeoutMs); broadcastConnectionState( mDevice, mLastConnectionState, BluetoothProfile.STATE_CONNECTING); @@ -1487,16 +1523,22 @@ public class BassClientStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: log("Already Connecting to " + mDevice); @@ -1542,8 +1584,7 @@ public class BassClientStateMachine extends StateMachine { } } - private static int getBisSyncFromChannelPreference( - List channels) { + private static int getBisSyncFromChannelPreference(List channels) { int bisSync = 0; for (BluetoothLeBroadcastChannel channel : channels) { if (channel.isSelected()) { @@ -1622,8 +1663,8 @@ public class BassClientStateMachine extends StateMachine { return res; } - private byte[] convertBroadcastMetadataToUpdateSourceByteArray(int sourceId, - BluetoothLeBroadcastMetadata metaData, int paSync) { + private byte[] convertBroadcastMetadataToUpdateSourceByteArray( + int sourceId, BluetoothLeBroadcastMetadata metaData, int paSync) { BluetoothLeBroadcastReceiveState existingState = getBroadcastReceiveStateForSourceId(sourceId); if (existingState == null) { @@ -1690,13 +1731,13 @@ public class BassClientStateMachine extends StateMachine { res[0] = OPCODE_SET_BCAST_PIN; // Source_ID res[1] = (byte) recvState.getSourceId(); - log("convertRecvStateToSetBroadcastCodeByteArray: Source device : " - + recvState.getSourceDevice()); + log( + "convertRecvStateToSetBroadcastCodeByteArray: Source device : " + + recvState.getSourceDevice()); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(recvState.getSourceId()); if (metaData == null) { - Log.e(TAG, "Fail to find broadcast source, sourceId = " - + recvState.getSourceId()); + Log.e(TAG, "Fail to find broadcast source, sourceId = " + recvState.getSourceId()); return null; } // Broadcast Code @@ -1732,8 +1773,10 @@ public class BassClientStateMachine extends StateMachine { log("Source state is null"); continue; } - if (sourceId == state.getSourceId() && state.getBigEncryptionState() - == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED) { + if (sourceId == state.getSourceId() + && state.getBigEncryptionState() + == BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_CODE_REQUIRED) { retval = true; break; } @@ -1746,19 +1789,25 @@ public class BassClientStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - log("Enter Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Enter Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(CONNECT); if (mLastConnectionState != BluetoothProfile.STATE_CONNECTED) { - broadcastConnectionState(mDevice, mLastConnectionState, - BluetoothProfile.STATE_CONNECTED); + broadcastConnectionState( + mDevice, mLastConnectionState, BluetoothProfile.STATE_CONNECTED); } } @Override public void exit() { - log("Exit Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @@ -1950,8 +1999,9 @@ public class BassClientStateMachine extends StateMachine { BassConstants.SOURCE_OPERATION_TIMEOUT_MS); } else { Log.e(TAG, "ADD_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal"); - mService.getCallbacks().notifySourceAddFailed(mDevice, - metaData, BluetoothStatusCodes.ERROR_UNKNOWN); + mService.getCallbacks() + .notifySourceAddFailed( + mDevice, metaData, BluetoothStatusCodes.ERROR_UNKNOWN); } break; case UPDATE_BCAST_SOURCE: @@ -1959,8 +2009,9 @@ public class BassClientStateMachine extends StateMachine { int sourceId = message.arg1; int paSync = message.arg2; log("Updating Broadcast source: " + metaData); - byte[] updateSourceInfo = convertBroadcastMetadataToUpdateSourceByteArray( - sourceId, metaData, paSync); + byte[] updateSourceInfo = + convertBroadcastMetadataToUpdateSourceByteArray( + sourceId, metaData, paSync); if (updateSourceInfo == null) { Log.e(TAG, "update source: source Info is NULL"); break; @@ -1987,8 +2038,9 @@ public class BassClientStateMachine extends StateMachine { BassConstants.SOURCE_OPERATION_TIMEOUT_MS); } else { Log.e(TAG, "UPDATE_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal"); - mService.getCallbacks().notifySourceModifyFailed( - mDevice, sourceId, BluetoothStatusCodes.ERROR_UNKNOWN); + mService.getCallbacks() + .notifySourceModifyFailed( + mDevice, sourceId, BluetoothStatusCodes.ERROR_UNKNOWN); } break; case SET_BCAST_CODE: @@ -1996,13 +2048,11 @@ public class BassClientStateMachine extends StateMachine { mSetBroadcastCodePending = false; BluetoothLeBroadcastReceiveState recvState = null; if (argType == ARGTYPE_METADATA) { - mSetBroadcastPINMetadata = - (BluetoothLeBroadcastMetadata) message.obj; + mSetBroadcastPINMetadata = (BluetoothLeBroadcastMetadata) message.obj; mSetBroadcastCodePending = true; } else { recvState = (BluetoothLeBroadcastReceiveState) message.obj; - if (!isItRightTimeToUpdateBroadcastPin( - (byte) recvState.getSourceId())) { + if (!isItRightTimeToUpdateBroadcastPin((byte) recvState.getSourceId())) { mSetBroadcastCodePending = true; } } @@ -2048,8 +2098,9 @@ public class BassClientStateMachine extends StateMachine { BassConstants.GATT_TXN_TIMEOUT_MS); } else { Log.e(TAG, "REMOVE_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal"); - mService.getCallbacks().notifySourceRemoveFailed(mDevice, - sid, BluetoothStatusCodes.ERROR_UNKNOWN); + mService.getCallbacks() + .notifySourceRemoveFailed( + mDevice, sid, BluetoothStatusCodes.ERROR_UNKNOWN); if (mPendingSourceToSwitch != null) { // Switching source failed // Need to notify add source failure for service to cleanup @@ -2123,8 +2174,8 @@ public class BassClientStateMachine extends StateMachine { if (!mAutoTriggered || Flags.leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { if (!isSuccess(status)) { - mService.getCallbacks().notifySourceModifyFailed(mDevice, - mPendingSourceId, status); + mService.getCallbacks() + .notifySourceModifyFailed(mDevice, mPendingSourceId, status); mPendingMetadata = null; removeMessages(CANCEL_PENDING_SOURCE_OPERATION); } @@ -2134,8 +2185,8 @@ public class BassClientStateMachine extends StateMachine { break; case REMOVE_BCAST_SOURCE: if (!isSuccess(status)) { - mService.getCallbacks().notifySourceRemoveFailed(mDevice, - mPendingSourceId, status); + mService.getCallbacks() + .notifySourceRemoveFailed(mDevice, mPendingSourceId, status); if (mPendingSourceToSwitch != null) { // Switching source failed // Need to notify add source failure for service to cleanup @@ -2159,23 +2210,34 @@ public class BassClientStateMachine extends StateMachine { class ConnectedProcessing extends State { @Override public void enter() { - log("Enter ConnectedProcessing(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Enter ConnectedProcessing(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); } + @Override public void exit() { /* Pending Metadata will be used to bond with source ID in receiver state notify */ if (mPendingOperation == REMOVE_BCAST_SOURCE) { - mPendingMetadata = null; + mPendingMetadata = null; } - log("Exit ConnectedProcessing(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit ConnectedProcessing(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); } + @Override public boolean processMessage(Message message) { - log("ConnectedProcessing process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "ConnectedProcessing process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: Log.w(TAG, "CONNECT request is ignored" + mDevice); @@ -2221,20 +2283,15 @@ public class BassClientStateMachine extends StateMachine { log("GATT transaction processed for" + mDevice); if (status == BluetoothGatt.GATT_SUCCESS) { sendPendingCallbacks( - mPendingOperation, - BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + mPendingOperation, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } else { - sendPendingCallbacks( - mPendingOperation, - BluetoothStatusCodes.ERROR_UNKNOWN); + sendPendingCallbacks(mPendingOperation, BluetoothStatusCodes.ERROR_UNKNOWN); } transitionTo(mConnected); break; case GATT_TXN_TIMEOUT: log("GATT transaction timeout for" + mDevice); - sendPendingCallbacks( - mPendingOperation, - BluetoothStatusCodes.ERROR_UNKNOWN); + sendPendingCallbacks(mPendingOperation, BluetoothStatusCodes.ERROR_UNKNOWN); mPendingOperation = -1; mPendingSourceId = -1; if ((message.arg1 == UPDATE_BCAST_SOURCE) @@ -2252,9 +2309,10 @@ public class BassClientStateMachine extends StateMachine { case REACHED_MAX_SOURCE_LIMIT: case SWITCH_BCAST_SOURCE: case PSYNC_ACTIVE_TIMEOUT: - log("defer the message: " - + messageWhatToString(message.what) - + ", so that it will be processed later"); + log( + "defer the message: " + + messageWhatToString(message.what) + + ", so that it will be processed later"); deferMessage(message); break; case CANCEL_PENDING_SOURCE_OPERATION: @@ -2282,8 +2340,9 @@ public class BassClientStateMachine extends StateMachine { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, fromState); intent.putExtra(BluetoothProfile.EXTRA_STATE, toState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mService.sendBroadcast( intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); } @@ -2361,9 +2420,7 @@ public class BassClientStateMachine extends StateMachine { return Integer.toString(what); } - /** - * Dump info - */ + /** Dump info */ public void dump(StringBuilder sb) { ProfileService.println(sb, "mDevice: " + mDevice); ProfileService.println(sb, " StateMachine: " + this); @@ -2428,17 +2485,14 @@ public class BassClientStateMachine extends StateMachine { return mWrappedBluetoothGatt.discoverServices(); } - /** - * See {@link BluetoothGatt#readCharacteristic( - * BluetoothGattCharacteristic)}. - */ + /** See {@link BluetoothGatt#readCharacteristic( BluetoothGattCharacteristic)}. */ public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) { return mWrappedBluetoothGatt.readCharacteristic(characteristic); } /** - * See {@link BluetoothGatt#writeCharacteristic( - * BluetoothGattCharacteristic, byte[], int)} . + * See {@link BluetoothGatt#writeCharacteristic( BluetoothGattCharacteristic, byte[], int)} + * . */ public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) { return mWrappedBluetoothGatt.writeCharacteristic(characteristic); @@ -2449,10 +2503,7 @@ public class BassClientStateMachine extends StateMachine { return mWrappedBluetoothGatt.readDescriptor(descriptor); } - /** - * See {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, - * byte[])}. - */ + /** See {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, byte[])}. */ public boolean writeDescriptor(BluetoothGattDescriptor descriptor) { return mWrappedBluetoothGatt.writeDescriptor(descriptor); } @@ -2478,5 +2529,4 @@ public class BassClientStateMachine extends StateMachine { mWrappedBluetoothGatt.close(); } } - } diff --git a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java index c3399ae6360..981f4b62874 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java @@ -20,14 +20,11 @@ import android.os.ParcelUuid; import java.util.UUID; -/** - * Broadcast Audio Scan Service constants class - */ +/** Broadcast Audio Scan Service constants class */ public class BassConstants { public static final ParcelUuid BAAS_UUID = ParcelUuid.fromString("00001852-0000-1000-8000-00805F9B34FB"); - public static final UUID BASS_UUID = - UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB"); + public static final UUID BASS_UUID = UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB"); public static final UUID BASS_BCAST_AUDIO_SCAN_CTRL_POINT = UUID.fromString("00002BC7-0000-1000-8000-00805F9B34FB"); public static final UUID BASS_BCAST_RECEIVER_STATE = diff --git a/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java b/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java index 1a4a40a2e87..d65913d7229 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java @@ -26,9 +26,7 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.internal.annotations.VisibleForTesting; -/** - * Factory class for object initialization to help with unit testing - */ +/** Factory class for object initialization to help with unit testing */ public class BassObjectsFactory { private static final String TAG = BassObjectsFactory.class.getSimpleName(); private static BassObjectsFactory sInstance; diff --git a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java index 73dcbb92468..239bcf3d825 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java @@ -23,14 +23,12 @@ import android.util.Log; import java.util.Arrays; import java.util.List; -/** - * Bass Utility functions - */ +/** Bass Utility functions */ class BassUtils { private static final String TAG = "BassUtils"; static boolean containUuid(List filters, ParcelUuid uuid) { - for (ScanFilter filter: filters) { + for (ScanFilter filter : filters) { if (filter.getServiceUuid().equals(uuid)) { return true; } diff --git a/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java b/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java index 7a33db94d0d..31cf2776060 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java +++ b/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java @@ -23,9 +23,7 @@ import android.bluetooth.le.ScanSettings; import java.util.List; -/** - * Helper class to mock {@link BluetoothLeScanner} which is final. - */ +/** Helper class to mock {@link BluetoothLeScanner} which is final. */ public class BluetoothLeScannerWrapper { BluetoothLeScanner mBluetoothLeScanner; @@ -34,17 +32,13 @@ public class BluetoothLeScannerWrapper { mBluetoothLeScanner = scanner; } - /** - * Starts Bluetooth LE scanning - */ - public void startScan(List filters, ScanSettings settings, - final ScanCallback callback) { + /** Starts Bluetooth LE scanning */ + public void startScan( + List filters, ScanSettings settings, final ScanCallback callback) { mBluetoothLeScanner.startScan(filters, settings, callback); } - /** - * Stops Bluetooth LE scanning - */ + /** Stops Bluetooth LE scanning */ public void stopScan(ScanCallback callback) { mBluetoothLeScanner.stopScan(callback); } diff --git a/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java b/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java index 8f23446feaa..6a985f6ac0b 100644 --- a/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java +++ b/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java @@ -19,9 +19,7 @@ package com.android.bluetooth.bass_client; import android.bluetooth.BluetoothDevice; import android.util.Log; -/** - * Periodic Advertisement Result - */ +/** Periodic Advertisement Result */ public class PeriodicAdvertisementResult { private static final String TAG = PeriodicAdvertisementResult.class.getSimpleName(); @@ -35,14 +33,15 @@ public class PeriodicAdvertisementResult { private PublicBroadcastData mPbData; private String mBroadcastName; - PeriodicAdvertisementResult(BluetoothDevice device, - int addressType, - int syncHandle, - int advSid, - int paInterval, - int broadcastId, - PublicBroadcastData pbData, - String broadcastName) { + PeriodicAdvertisementResult( + BluetoothDevice device, + int addressType, + int syncHandle, + int advSid, + int paInterval, + int broadcastId, + PublicBroadcastData pbData, + String broadcastName) { mDevice = device; mAddressType = addressType; mAdvSid = advSid; @@ -54,23 +53,17 @@ public class PeriodicAdvertisementResult { mBroadcastName = broadcastName; } - /** - * Update Sync handle - */ + /** Update Sync handle */ public void updateSyncHandle(int syncHandle) { mSyncHandle = syncHandle; } - /** - * Get Sync handle - */ + /** Get Sync handle */ public int getSyncHandle() { return mSyncHandle; } - /** - * Get mIsNotified flag - */ + /** Get mIsNotified flag */ public boolean isNotified() { synchronized (this) { return mIsNotified; @@ -83,93 +76,67 @@ public class PeriodicAdvertisementResult { } } - /** - * Update Adv ID - */ + /** Update Adv ID */ public void updateAdvSid(int advSid) { mAdvSid = advSid; } - /** - * Get Adv ID - */ + /** Get Adv ID */ public int getAdvSid() { return mAdvSid; } - /** - * Update address type - */ + /** Update address type */ public void updateAddressType(int addressType) { mAddressType = addressType; } - /** - * Get address type - */ + /** Get address type */ public int getAddressType() { return mAddressType; } - /** - * Update Adv interval - */ + /** Update Adv interval */ public void updateAdvInterval(int advInterval) { mPAInterval = advInterval; } - /** - * Get Adv interval - */ + /** Get Adv interval */ public int getAdvInterval() { return mPAInterval; } - /** - * Update broadcast ID - */ + /** Update broadcast ID */ public void updateBroadcastId(int broadcastId) { mBroadcastId = broadcastId; } - /** - * Get broadcast ID - */ + /** Get broadcast ID */ public int getBroadcastId() { return mBroadcastId; } - /** - * Update public broadcast data - */ + /** Update public broadcast data */ public void updatePublicBroadcastData(PublicBroadcastData pbData) { mPbData = pbData; } - /** - * Get public broadcast data - */ + /** Get public broadcast data */ public PublicBroadcastData getPublicBroadcastData() { return mPbData; } - /** - * Update broadcast name - */ + /** Update broadcast name */ public void updateBroadcastName(String broadcastName) { mBroadcastName = broadcastName; } - /** - * Get broadcast name - */ + /** Get broadcast name */ public String getBroadcastName() { return mBroadcastName; } - /** - * print - */ + /** print */ public void print() { log("-- PeriodicAdvertisementResult --"); log("mDevice:" + mDevice); diff --git a/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java b/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java index bff99cb25e7..4601cafa6cc 100644 --- a/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java +++ b/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java @@ -21,9 +21,7 @@ import android.util.Log; import java.util.Arrays; -/** - * Helper class to parse the Public Broadcast Announcement data - */ +/** Helper class to parse the Public Broadcast Announcement data */ class PublicBroadcastData { private static final String TAG = "Bassclient.PublicBroadcastData"; private static final int FEATURES_ENCRYPTION_BIT = 0x01 << 0; diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java index 0b416d1b70c..266b115751f 100644 --- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java @@ -52,57 +52,44 @@ import java.util.Objects; import java.util.Set; /** - * The active device manager is responsible for keeping track of the - * connected A2DP/HFP/AVRCP/HearingAid/LE audio devices and select which device is - * active (for each profile). - * The active device manager selects a fallback device when the currently active device - * is disconnected, and it selects BT devices that are lastly activated one. + * The active device manager is responsible for keeping track of the connected + * A2DP/HFP/AVRCP/HearingAid/LE audio devices and select which device is active (for each profile). + * The active device manager selects a fallback device when the currently active device is + * disconnected, and it selects BT devices that are lastly activated one. * - * Current policy (subject to change): - * 1) If the maximum number of connected devices is one, the manager doesn't - * do anything. Each profile is responsible for automatically selecting - * the connected device as active. Only if the maximum number of connected - * devices is more than one, the rules below will apply. - * 2) The selected A2DP active device is the one used for AVRCP as well. - * 3) The HFP active device might be different from the A2DP active device. - * 4) The Active Device Manager always listens for the change of active devices. - * When it changed (e.g., triggered indirectly by user action on the UI), - * the new active device is marked as the current active device for that profile. - * 5) If there is a HearingAid active device, then A2DP, HFP and LE audio active devices - * must be set to null (i.e., A2DP, HFP and LE audio cannot have active devices). - * The reason is that A2DP, HFP or LE audio cannot be used together with HearingAid. - * 6) If there are no connected devices (e.g., during startup, or after all - * devices have been disconnected, the active device per profile - * (A2DP/HFP/HearingAid/LE audio) is selected as follows: - * 6.1) The last connected HearingAid device is selected as active. - * If there is an active A2DP, HFP or LE audio device, those must be set to null. - * 6.2) The last connected A2DP, HFP or LE audio device is selected as active. - * However, if there is an active HearingAid device, then the - * A2DP, HFP, or LE audio active device is not set (must remain null). - * 7) If the currently active device (per profile) is disconnected, the - * Active Device Manager just marks that the profile has no active device, - * and the lastly activated BT device that is still connected would be selected. - * 8) If there is already an active device, however, if active device change notified - * with a null device, the corresponding profile is marked as having no active device. - * 9) If a wired audio device is connected, the audio output is switched - * by the Audio Framework itself to that device. We detect this here, - * and the active device for each profile (A2DP/HFP/HearingAid/LE audio) is set - * to null to reflect the output device state change. However, if the - * wired audio device is disconnected, we don't do anything explicit - * and apply the default behavior instead: - * 9.1) If the wired headset is still the selected output device (i.e. the - * active device is set to null), the Phone itself will become the output - * device (i.e., the active device will remain null). If music was - * playing, it will stop. - * 9.2) If one of the Bluetooth devices is the selected active device - * (e.g., by the user in the UI), disconnecting the wired audio device - * will have no impact. E.g., music will continue streaming over the - * active Bluetooth device. + *

Current policy (subject to change): 1) If the maximum number of connected devices is one, the + * manager doesn't do anything. Each profile is responsible for automatically selecting the + * connected device as active. Only if the maximum number of connected devices is more than one, the + * rules below will apply. 2) The selected A2DP active device is the one used for AVRCP as well. 3) + * The HFP active device might be different from the A2DP active device. 4) The Active Device + * Manager always listens for the change of active devices. When it changed (e.g., triggered + * indirectly by user action on the UI), the new active device is marked as the current active + * device for that profile. 5) If there is a HearingAid active device, then A2DP, HFP and LE audio + * active devices must be set to null (i.e., A2DP, HFP and LE audio cannot have active devices). The + * reason is that A2DP, HFP or LE audio cannot be used together with HearingAid. 6) If there are no + * connected devices (e.g., during startup, or after all devices have been disconnected, the active + * device per profile (A2DP/HFP/HearingAid/LE audio) is selected as follows: 6.1) The last connected + * HearingAid device is selected as active. If there is an active A2DP, HFP or LE audio device, + * those must be set to null. 6.2) The last connected A2DP, HFP or LE audio device is selected as + * active. However, if there is an active HearingAid device, then the A2DP, HFP, or LE audio active + * device is not set (must remain null). 7) If the currently active device (per profile) is + * disconnected, the Active Device Manager just marks that the profile has no active device, and the + * lastly activated BT device that is still connected would be selected. 8) If there is already an + * active device, however, if active device change notified with a null device, the corresponding + * profile is marked as having no active device. 9) If a wired audio device is connected, the audio + * output is switched by the Audio Framework itself to that device. We detect this here, and the + * active device for each profile (A2DP/HFP/HearingAid/LE audio) is set to null to reflect the + * output device state change. However, if the wired audio device is disconnected, we don't do + * anything explicit and apply the default behavior instead: 9.1) If the wired headset is still the + * selected output device (i.e. the active device is set to null), the Phone itself will become the + * output device (i.e., the active device will remain null). If music was playing, it will stop. + * 9.2) If one of the Bluetooth devices is the selected active device (e.g., by the user in the UI), + * disconnecting the wired audio device will have no impact. E.g., music will continue streaming + * over the active Bluetooth device. */ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallback { private static final String TAG = ActiveDeviceManager.class.getSimpleName(); - @VisibleForTesting - static final int A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS = 5_000; + @VisibleForTesting static final int A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS = 5_000; private final AdapterService mAdapterService; private DatabaseManager mDbManager; @@ -113,28 +100,40 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback; private final Object mLock = new Object(); + @GuardedBy("mLock") private final List mA2dpConnectedDevices = new ArrayList<>(); + @GuardedBy("mLock") private final List mHfpConnectedDevices = new ArrayList<>(); + @GuardedBy("mLock") private final List mHearingAidConnectedDevices = new ArrayList<>(); + @GuardedBy("mLock") private final List mLeAudioConnectedDevices = new ArrayList<>(); + @GuardedBy("mLock") private final List mLeHearingAidConnectedDevices = new ArrayList<>(); + @GuardedBy("mLock") private List mPendingLeHearingAidActiveDevice = new ArrayList<>(); + @GuardedBy("mLock") private BluetoothDevice mA2dpActiveDevice = null; + @GuardedBy("mLock") private BluetoothDevice mHfpActiveDevice = null; + @GuardedBy("mLock") private final Set mHearingAidActiveDevices = new ArraySet<>(); + @GuardedBy("mLock") private BluetoothDevice mLeAudioActiveDevice = null; + @GuardedBy("mLock") private BluetoothDevice mLeHearingAidActiveDevice = null; + @GuardedBy("mLock") private BluetoothDevice mPendingActiveDevice = null; @@ -226,13 +225,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } /** - * Handles the active device logic for when A2DP is connected. Does the following: - * 1. Check if a hearing aid device is active. We will always prefer hearing aid devices, so if - * one is active, we will not make this A2DP device active. - * 2. If there is no hearing aid device active, we will make this A2DP device active. - * 3. We will make this device active for HFP if it's already connected to HFP - * 4. If dual mode is disabled, we clear the LE Audio active device to ensure mutual exclusion - * between classic and LE audio. + * Handles the active device logic for when A2DP is connected. Does the following: 1. Check if a + * hearing aid device is active. We will always prefer hearing aid devices, so if one is active, + * we will not make this A2DP device active. 2. If there is no hearing aid device active, we + * will make this A2DP device active. 3. We will make this device active for HFP if it's already + * connected to HFP 4. If dual mode is disabled, we clear the LE Audio active device to ensure + * mutual exclusion between classic and LE audio. * * @param device is the device that was connected to A2DP */ @@ -275,8 +273,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac setLeAudioActiveDevice(null, true); } } else { - Log.d(TAG, "A2DP activation is suspended until HFP connected: " - + device); + Log.d(TAG, "A2DP activation is suspended until HFP connected: " + device); if (mPendingActiveDevice != null) { mHandler.removeCallbacksAndMessages(mPendingActiveDevice); } @@ -295,13 +292,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } /** - * Handles the active device logic for when HFP is connected. Does the following: - * 1. Check if a hearing aid device is active. We will always prefer hearing aid devices, so if - * one is active, we will not make this HFP device active. - * 2. If there is no hearing aid device active, we will make this HFP device active. - * 3. We will make this device active for A2DP if it's already connected to A2DP - * 4. If dual mode is disabled, we clear the LE Audio active device to ensure mutual exclusion - * between classic and LE audio. + * Handles the active device logic for when HFP is connected. Does the following: 1. Check if a + * hearing aid device is active. We will always prefer hearing aid devices, so if one is active, + * we will not make this HFP device active. 2. If there is no hearing aid device active, we will + * make this HFP device active. 3. We will make this device active for A2DP if it's already + * connected to A2DP 4. If dual mode is disabled, we clear the LE Audio active device to ensure + * mutual exclusion between classic and LE audio. * * @param device is the device that was connected to A2DP */ @@ -354,8 +350,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac setLeAudioActiveDevice(null, true); } } else { - Log.d(TAG, "HFP activation is suspended until A2DP connected: " - + device); + Log.d(TAG, "HFP activation is suspended until A2DP connected: " + device); if (mPendingActiveDevice != null) { mHandler.removeCallbacksAndMessages(mPendingActiveDevice); } @@ -479,8 +474,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleA2dpDisconnected(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleA2dpDisconnected: " + device - + ", mA2dpActiveDevice=" + mA2dpActiveDevice); + Log.d( + TAG, + "handleA2dpDisconnected: " + + device + + ", mA2dpActiveDevice=" + + mA2dpActiveDevice); mA2dpConnectedDevices.remove(device); if (Objects.equals(mA2dpActiveDevice, device)) { if (!setFallbackDeviceActiveLocked()) { @@ -492,8 +491,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleHfpDisconnected(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleHfpDisconnected: " + device - + ", mHfpActiveDevice=" + mHfpActiveDevice); + Log.d( + TAG, + "handleHfpDisconnected: " + device + ", mHfpActiveDevice=" + mHfpActiveDevice); mHfpConnectedDevices.remove(device); if (Objects.equals(mHfpActiveDevice, device)) { if (mHfpConnectedDevices.isEmpty()) { @@ -506,8 +506,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleHearingAidDisconnected(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleHearingAidDisconnected: " + device - + ", mHearingAidActiveDevices=" + mHearingAidActiveDevices); + Log.d( + TAG, + "handleHearingAidDisconnected: " + + device + + ", mHearingAidActiveDevices=" + + mHearingAidActiveDevices); mHearingAidConnectedDevices.remove(device); if (mHearingAidActiveDevices.remove(device) && mHearingAidActiveDevices.isEmpty()) { if (!setFallbackDeviceActiveLocked()) { @@ -519,8 +523,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleLeAudioDisconnected(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleLeAudioDisconnected: " + device - + ", mLeAudioActiveDevice=" + mLeAudioActiveDevice); + Log.d( + TAG, + "handleLeAudioDisconnected: " + + device + + ", mLeAudioActiveDevice=" + + mLeAudioActiveDevice); final LeAudioService leAudioService = mFactory.getLeAudioService(); if (leAudioService == null || device == null) { @@ -543,8 +551,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleHapDisconnected(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleHapDisconnected: " + device - + ", mLeHearingAidActiveDevice=" + mLeHearingAidActiveDevice); + Log.d( + TAG, + "handleHapDisconnected: " + + device + + ", mLeHearingAidActiveDevice=" + + mLeHearingAidActiveDevice); mLeHearingAidConnectedDevices.remove(device); mPendingLeHearingAidActiveDevice.remove(device); if (Objects.equals(mLeHearingAidActiveDevice, device)) { @@ -555,18 +567,21 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac /** * Handles the active device logic for when the A2DP active device changes. Does the following: - * 1. Clear the active hearing aid. - * 2. If dual mode is enabled and all supported classic audio profiles are enabled, makes this - * device active for LE Audio. If not, clear the LE Audio active device. - * 3. Make HFP active for this device if it is already connected to HFP. - * 4. Stores the new A2DP active device. + * 1. Clear the active hearing aid. 2. If dual mode is enabled and all supported classic audio + * profiles are enabled, makes this device active for LE Audio. If not, clear the LE Audio + * active device. 3. Make HFP active for this device if it is already connected to HFP. 4. + * Stores the new A2DP active device. * * @param device is the device that was connected to A2DP */ private void handleA2dpActiveDeviceChanged(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleA2dpActiveDeviceChanged: " + device - + ", mA2dpActiveDevice=" + mA2dpActiveDevice); + Log.d( + TAG, + "handleA2dpActiveDeviceChanged: " + + device + + ", mA2dpActiveDevice=" + + mA2dpActiveDevice); if (!Objects.equals(mA2dpActiveDevice, device)) { if (device != null) { setHearingAidActiveDevice(null, true); @@ -619,18 +634,21 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac /** * Handles the active device logic for when the HFP active device changes. Does the following: - * 1. Clear the active hearing aid. - * 2. If dual mode is enabled and all supported classic audio profiles are enabled, makes this - * device active for LE Audio. If not, clear the LE Audio active device. - * 3. Make A2DP active for this device if it is already connected to A2DP. - * 4. Stores the new HFP active device. + * 1. Clear the active hearing aid. 2. If dual mode is enabled and all supported classic audio + * profiles are enabled, makes this device active for LE Audio. If not, clear the LE Audio + * active device. 3. Make A2DP active for this device if it is already connected to A2DP. 4. + * Stores the new HFP active device. * * @param device is the device that was connected to A2DP */ private void handleHfpActiveDeviceChanged(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleHfpActiveDeviceChanged: " + device - + ", mHfpActiveDevice=" + mHfpActiveDevice); + Log.d( + TAG, + "handleHfpActiveDeviceChanged: " + + device + + ", mHfpActiveDevice=" + + mHfpActiveDevice); if (!Objects.equals(mHfpActiveDevice, device)) { if (device != null) { setHearingAidActiveDevice(null, true); @@ -690,8 +708,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleHearingAidActiveDeviceChanged(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleHearingAidActiveDeviceChanged: " + device - + ", mHearingAidActiveDevices=" + mHearingAidActiveDevices); + Log.d( + TAG, + "handleHearingAidActiveDeviceChanged: " + + device + + ", mHearingAidActiveDevices=" + + mHearingAidActiveDevices); // Just assign locally the new value final HearingAidService hearingAidService = mFactory.getHearingAidService(); if (hearingAidService != null) { @@ -714,8 +736,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private void handleLeAudioActiveDeviceChanged(BluetoothDevice device) { synchronized (mLock) { - Log.d(TAG, "handleLeAudioActiveDeviceChanged: " + device - + ", mLeAudioActiveDevice=" + mLeAudioActiveDevice); + Log.d( + TAG, + "handleLeAudioActiveDeviceChanged: " + + device + + ", mLeAudioActiveDevice=" + + mLeAudioActiveDevice); if (device != null && !mLeAudioConnectedDevices.contains(device)) { mLeAudioConnectedDevices.add(device); } @@ -756,8 +782,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac Log.d(TAG, "onAudioDevicesAdded"); boolean hasAddedWiredDevice = false; for (AudioDeviceInfo deviceInfo : addedDevices) { - Log.d(TAG, "Audio device added: " + deviceInfo.getProductName() + " type: " - + deviceInfo.getType()); + Log.d( + TAG, + "Audio device added: " + + deviceInfo.getProductName() + + " type: " + + deviceInfo.getType()); if (isWiredAudioHeadset(deviceInfo)) { hasAddedWiredDevice = true; break; @@ -769,8 +799,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } @Override - public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) { - } + public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {} } ActiveDeviceManager(AdapterService service, ServiceFactory factory) { @@ -806,8 +835,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } /** - * Get the {@link Looper} for the handler thread. This is used in testing and helper - * objects + * Get the {@link Looper} for the handler thread. This is used in testing and helper objects * * @return {@link Looper} for the handler thread */ @@ -823,10 +851,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return setA2dpActiveDevice(device, false); } - private boolean setA2dpActiveDevice(@Nullable BluetoothDevice device, - boolean hasFallbackDevice) { - Log.d(TAG, "setA2dpActiveDevice(" + device + ")" - + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); + private boolean setA2dpActiveDevice( + @Nullable BluetoothDevice device, boolean hasFallbackDevice) { + Log.d( + TAG, + "setA2dpActiveDevice(" + + device + + ")" + + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); synchronized (mLock) { if (mPendingActiveDevice != null) { mHandler.removeCallbacksAndMessages(mPendingActiveDevice); @@ -869,8 +901,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return false; } BluetoothSinkAudioPolicy audioPolicy = headsetService.getHfpCallAudioPolicy(device); - if (audioPolicy != null && audioPolicy.getActiveDevicePolicyAfterConnection() - == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { + if (audioPolicy != null + && audioPolicy.getActiveDevicePolicyAfterConnection() + == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { return false; } if (!headsetService.setActiveDevice(device)) { @@ -885,10 +918,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return setHearingAidActiveDevice(device, false); } - private boolean setHearingAidActiveDevice(@Nullable BluetoothDevice device, - boolean hasFallbackDevice) { - Log.d(TAG, "setHearingAidActiveDevice(" + device + ")" - + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); + private boolean setHearingAidActiveDevice( + @Nullable BluetoothDevice device, boolean hasFallbackDevice) { + Log.d( + TAG, + "setHearingAidActiveDevice(" + + device + + ")" + + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); final HearingAidService hearingAidService = mFactory.getHearingAidService(); if (hearingAidService == null) { @@ -923,10 +960,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return setLeAudioActiveDevice(device, false); } - private boolean setLeAudioActiveDevice(@Nullable BluetoothDevice device, - boolean hasFallbackDevice) { - Log.d(TAG, "setLeAudioActiveDevice(" + device + ")" - + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); + private boolean setLeAudioActiveDevice( + @Nullable BluetoothDevice device, boolean hasFallbackDevice) { + Log.d( + TAG, + "setLeAudioActiveDevice(" + + device + + ")" + + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : "")); synchronized (mLock) { final LeAudioService leAudioService = mFactory.getLeAudioService(); if (leAudioService == null) { @@ -984,8 +1025,8 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac /** * TODO: This method can return true when a fallback device for an unrelated profile is found. - * Take disconnected profile as an argument, and find the exact fallback device. - * Also, split this method to smaller methods for better readability. + * Take disconnected profile as an argument, and find the exact fallback device. Also, split + * this method to smaller methods for better readability. * * @return true when the fallback device is activated, false otherwise */ @@ -1063,7 +1104,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac setHfpActiveDevice(null); } /* If dual mode is enabled, LEA will be made active once all supported - classic audio profiles are made active for the device. */ + classic audio profiles are made active for the device. */ if (!Utils.isDualModeAudioEnabled()) { setLeAudioActiveDevice(null, true); } @@ -1161,14 +1202,15 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac /** * Checks CoD and metadata to determine if the device is a watch + * * @param device the remote device * @return {@code true} if it's a watch, {@code false} otherwise */ private boolean isWatch(BluetoothDevice device) { // Check CoD BluetoothClass deviceClass = device.getBluetoothClass(); - if (deviceClass != null && deviceClass.getDeviceClass() - == BluetoothClass.Device.WEARABLE_WRIST_WATCH) { + if (deviceClass != null + && deviceClass.getDeviceClass() == BluetoothClass.Device.WEARABLE_WRIST_WATCH) { return true; } @@ -1201,8 +1243,8 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } /** - * Called when a wired audio device is connected. - * It might be called multiple times each time a wired audio device is connected. + * Called when a wired audio device is connected. It might be called multiple times each time a + * wired audio device is connected. */ @VisibleForTesting @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterApp.java b/android/app/src/com/android/bluetooth/btservice/AdapterApp.java index 08f69e161b7..6c245eb229d 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterApp.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterApp.java @@ -20,7 +20,7 @@ import android.util.Log; public class AdapterApp extends Application { private static final String TAG = "BluetoothAdapterApp"; - //For Debugging only + // For Debugging only private static int sRefCount = 0; public AdapterApp() { diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java index c4fce10d432..ed783b99300 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java @@ -119,10 +119,10 @@ class AdapterProperties { private AdapterService mService; private boolean mDiscovering; - private long mDiscoveryEndMs; //< Time (ms since epoch) that discovery ended or will end. + private long mDiscoveryEndMs; // < Time (ms since epoch) that discovery ended or will end. private RemoteDevices mRemoteDevices; private BluetoothAdapter mAdapter; - //TODO - all hw capabilities to be exposed as a class + // TODO - all hw capabilities to be exposed as a class private int mNumOfAdvertisementInstancesSupported; private boolean mRpaOffloadSupported; private int mNumOfOffloadedIrkSupported; @@ -152,66 +152,67 @@ class AdapterProperties { private boolean mReceiverRegistered; private Handler mHandler; - private BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) { - Log.w(TAG, "Received intent with null action"); - return; - } - switch (action) { - case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.HEADSET, intent); - break; - case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.A2DP, intent); - break; - case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.HEADSET_CLIENT, intent); - break; - case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.HEARING_AID, intent); - break; - case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.A2DP_SINK, intent); - break; - case BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.HID_DEVICE, intent); - break; - case BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.HID_HOST, intent); - break; - case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.AVRCP_CONTROLLER, intent); - break; - case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.PAN, intent); - break; - case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.MAP, intent); - break; - case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.MAP_CLIENT, intent); - break; - case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.SAP, intent); - break; - case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.PBAP_CLIENT, intent); - break; - case BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.PBAP, intent); - break; - case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED: - logConnectionStateChanges(BluetoothProfile.LE_AUDIO, intent); - break; - default: - Log.w(TAG, "Received unknown intent " + intent); - break; - } - } - }; + private BroadcastReceiver mReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) { + Log.w(TAG, "Received intent with null action"); + return; + } + switch (action) { + case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.HEADSET, intent); + break; + case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.A2DP, intent); + break; + case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.HEADSET_CLIENT, intent); + break; + case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.HEARING_AID, intent); + break; + case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.A2DP_SINK, intent); + break; + case BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.HID_DEVICE, intent); + break; + case BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.HID_HOST, intent); + break; + case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.AVRCP_CONTROLLER, intent); + break; + case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.PAN, intent); + break; + case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.MAP, intent); + break; + case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.MAP_CLIENT, intent); + break; + case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.SAP, intent); + break; + case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.PBAP_CLIENT, intent); + break; + case BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.PBAP, intent); + break; + case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED: + logConnectionStateChanges(BluetoothProfile.LE_AUDIO, intent); + break; + default: + Log.w(TAG, "Received unknown intent " + intent); + break; + } + } + }; // Lock for all getters and setters. // If finer grained locking is needer, more locks @@ -230,23 +231,35 @@ class AdapterProperties { mRemoteDevices = remoteDevices; // Get default max connected audio devices from config.xml - int configDefaultMaxConnectedAudioDevices = mService.getResources().getInteger( - com.android.bluetooth.R.integer.config_bluetooth_max_connected_audio_devices); + int configDefaultMaxConnectedAudioDevices = + mService.getResources() + .getInteger( + com.android.bluetooth.R.integer + .config_bluetooth_max_connected_audio_devices); // Override max connected audio devices if MAX_CONNECTED_AUDIO_DEVICES_PROPERTY is set int propertyOverlayedMaxConnectedAudioDevices = - SystemProperties.getInt(MAX_CONNECTED_AUDIO_DEVICES_PROPERTY, + SystemProperties.getInt( + MAX_CONNECTED_AUDIO_DEVICES_PROPERTY, configDefaultMaxConnectedAudioDevices); // Make sure the final value of max connected audio devices is within allowed range - mMaxConnectedAudioDevices = Math.min(Math.max(propertyOverlayedMaxConnectedAudioDevices, - MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOUND), MAX_CONNECTED_AUDIO_DEVICES_UPPER_BOUND); - Log.i(TAG, "init(), maxConnectedAudioDevices, default=" - + configDefaultMaxConnectedAudioDevices + ", propertyOverlayed=" - + propertyOverlayedMaxConnectedAudioDevices + ", finalValue=" - + mMaxConnectedAudioDevices); + mMaxConnectedAudioDevices = + Math.min( + Math.max( + propertyOverlayedMaxConnectedAudioDevices, + MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOUND), + MAX_CONNECTED_AUDIO_DEVICES_UPPER_BOUND); + Log.i( + TAG, + "init(), maxConnectedAudioDevices, default=" + + configDefaultMaxConnectedAudioDevices + + ", propertyOverlayed=" + + propertyOverlayedMaxConnectedAudioDevices + + ", finalValue=" + + mMaxConnectedAudioDevices); mA2dpOffloadEnabled = SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false) - && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); + && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); mHandler = new Handler(Looper.getMainLooper()); @@ -294,19 +307,24 @@ class AdapterProperties { private static void invalidateGetProfileConnectionStateCache() { BluetoothAdapter.invalidateGetProfileConnectionStateCache(); } + private static void invalidateIsOffloadedFilteringSupportedCache() { BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache(); } + private static void invalidateBluetoothGetConnectionStateCache() { BluetoothMap.invalidateBluetoothGetConnectionStateCache(); BluetoothSap.invalidateBluetoothGetConnectionStateCache(); } + private static void invalidateGetConnectionStateCache() { BluetoothAdapter.invalidateGetAdapterConnectionStateCache(); } + private static void invalidateGetBondStateCache() { BluetoothDevice.invalidateBluetoothGetBondStateCache(); } + private static void invalidateBluetoothCaches() { invalidateGetProfileConnectionStateCache(); invalidateIsOffloadedFilteringSupportedCache(); @@ -329,6 +347,7 @@ class AdapterProperties { /** * Set the local adapter property - name + * * @param name the name to set */ boolean setName(String name) { @@ -352,11 +371,9 @@ class AdapterProperties { /** * Set the local adapter property - scanMode * - * @param scanMode the ScanMode to set, valid values are: { - * BluetoothAdapter.SCAN_MODE_NONE, + * @param scanMode the ScanMode to set, valid values are: { BluetoothAdapter.SCAN_MODE_NONE, * BluetoothAdapter.SCAN_MODE_CONNECTABLE, - * BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, - * } + * BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, } */ boolean setScanMode(int scanMode) { addScanChangeLog(scanMode); @@ -532,7 +549,6 @@ class AdapterProperties { return mTotNumOfTrackableAdv; } - /** * @return the isOffloadedTransportDiscoveryDataScanSupported */ @@ -560,16 +576,14 @@ class AdapterProperties { int getDynamicBufferSupport() { if (!mA2dpOffloadEnabled) { // TODO: Enable Dynamic Audio Buffer for A2DP software encoding when ready. - mIsDynamicAudioBufferSizeSupported = - BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE; + mIsDynamicAudioBufferSizeSupported = BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE; } else { if ((mDynamicAudioBufferSizeSupportedCodecsGroup1 != 0) || (mDynamicAudioBufferSizeSupportedCodecsGroup2 != 0)) { mIsDynamicAudioBufferSizeSupported = - BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD; + BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD; } else { - mIsDynamicAudioBufferSizeSupported = - BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE; + mIsDynamicAudioBufferSizeSupported = BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE; } } return mIsDynamicAudioBufferSizeSupported; @@ -741,8 +755,8 @@ class AdapterProperties { int metricId = mService.getMetricId(device); byte[] remoteDeviceInfoBytes = MetricsLogger.getInstance().getRemoteDeviceInfoProto(device); if (state == BluetoothProfile.STATE_CONNECTING) { - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED, - metricId, device.getName()); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED, metricId, device.getName()); BluetoothStatsLog.write( BluetoothStatsLog.REMOTE_DEVICE_INFORMATION_WITH_METRIC_ID, metricId, @@ -750,9 +764,15 @@ class AdapterProperties { MetricsLogger.getInstance() .logAllowlistedDeviceNameHash(metricId, device.getName(), true); } - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, state, - 0 /* deprecated */, profile, mService.obfuscateAddress(device), - metricId, 0, -1); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, + state, + 0 /* deprecated */, + profile, + mService.obfuscateAddress(device), + metricId, + 0, + -1); } @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) @@ -763,13 +783,27 @@ class AdapterProperties { @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) { - Log.d(TAG, "PROFILE_CONNECTION_STATE_CHANGE: profile=" - + BluetoothProfile.getProfileName(profile) + ", device=" + device + ", " - + prevState + " -> " + state); + Log.d( + TAG, + "PROFILE_CONNECTION_STATE_CHANGE: profile=" + + BluetoothProfile.getProfileName(profile) + + ", device=" + + device + + ", " + + prevState + + " -> " + + state); if (!isNormalStateTransition(prevState, state)) { - Log.w(TAG, "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" - + BluetoothProfile.getProfileName(profile) - + ", device=" + device + ", " + prevState + " -> " + state); + Log.w( + TAG, + "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + + BluetoothProfile.getProfileName(profile) + + ", device=" + + device + + ", " + + prevState + + " -> " + + state); } BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, @@ -785,8 +819,11 @@ class AdapterProperties { // with the invalid state converted to -1 in the intent. // Better to log an error and not send an intent with // invalid contents or set mAdapterConnectionState to -1. - errorLog("sendConnectionStateChange: invalid state transition " + prevState + " -> " - + state); + errorLog( + "sendConnectionStateChange: invalid state transition " + + prevState + + " -> " + + state); return; } @@ -803,12 +840,25 @@ class AdapterProperties { intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, newAdapterState); intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, prevAdapterState); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - Log.d(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: " + device + ": " + prevAdapterState - + " -> " + newAdapterState); + Log.d( + TAG, + "ADAPTER_CONNECTION_STATE_CHANGE: " + + device + + ": " + + prevAdapterState + + " -> " + + newAdapterState); if (!isNormalStateTransition(prevState, state)) { - Log.w(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile=" - + BluetoothProfile.getProfileName(profile) - + ", device=" + device + ", " + prevState + " -> " + state); + Log.w( + TAG, + "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + + BluetoothProfile.getProfileName(profile) + + ", device=" + + device + + ", " + + prevState + + " -> " + + state); } mService.sendBroadcastAsUser( intent, @@ -849,8 +899,8 @@ class AdapterProperties { return nextState == BluetoothProfile.STATE_DISCONNECTING; case BluetoothProfile.STATE_DISCONNECTING: case BluetoothProfile.STATE_CONNECTING: - return (nextState == BluetoothProfile.STATE_DISCONNECTED) || (nextState - == BluetoothProfile.STATE_CONNECTED); + return (nextState == BluetoothProfile.STATE_DISCONNECTED) + || (nextState == BluetoothProfile.STATE_CONNECTED); default: return false; } @@ -937,8 +987,8 @@ class AdapterProperties { if (newState == currHashState) { numDev++; - } else if (newState == BluetoothProfile.STATE_CONNECTED || ( - newState == BluetoothProfile.STATE_CONNECTING + } else if (newState == BluetoothProfile.STATE_CONNECTED + || (newState == BluetoothProfile.STATE_CONNECTING && currHashState != BluetoothProfile.STATE_CONNECTED)) { numDev = 1; } else if (numDev == 1 && oldState == currHashState) { @@ -1026,8 +1076,9 @@ class AdapterProperties { byte[] addrByte = new byte[BD_ADDR_LEN]; for (int j = 0; j < number; j++) { System.arraycopy(val, j * BD_ADDR_LEN, addrByte, 0, BD_ADDR_LEN); - onBondStateChanged(mAdapter.getRemoteDevice( - Utils.getAddressStringFromByte(addrByte)), + onBondStateChanged( + mAdapter.getRemoteDevice( + Utils.getAddressStringFromByte(addrByte)), BluetoothDevice.BOND_BONDED); } break; @@ -1079,35 +1130,53 @@ class AdapterProperties { mIsLePeriodicAdvertisingSyncTransferRecipientSupported = ((0xFF & ((int) val[27])) != 0); mIsOffloadedTransportDiscoveryDataScanSupported = ((0x01 & ((int) val[28])) != 0); - Log.d(TAG, "BT_PROPERTY_LOCAL_LE_FEATURES: update from BT controller" - + " mNumOfAdvertisementInstancesSupported = " - + mNumOfAdvertisementInstancesSupported + " mRpaOffloadSupported = " - + mRpaOffloadSupported + " mNumOfOffloadedIrkSupported = " - + mNumOfOffloadedIrkSupported + " mNumOfOffloadedScanFilterSupported = " - + mNumOfOffloadedScanFilterSupported + " mOffloadedScanResultStorageBytes= " - + mOffloadedScanResultStorageBytes + " mIsActivityAndEnergyReporting = " - + mIsActivityAndEnergyReporting + " mVersSupported = " + mVersSupported - + " mTotNumOfTrackableAdv = " + mTotNumOfTrackableAdv - + " mIsExtendedScanSupported = " + mIsExtendedScanSupported - + " mIsDebugLogSupported = " + mIsDebugLogSupported + " mIsLe2MPhySupported = " - + mIsLe2MPhySupported + " mIsLeCodedPhySupported = " + mIsLeCodedPhySupported - + " mIsLeExtendedAdvertisingSupported = " + mIsLeExtendedAdvertisingSupported - + " mIsLePeriodicAdvertisingSupported = " + mIsLePeriodicAdvertisingSupported - + " mLeMaximumAdvertisingDataLength = " + mLeMaximumAdvertisingDataLength - + " mDynamicAudioBufferSizeSupportedCodecsGroup1 = " - + mDynamicAudioBufferSizeSupportedCodecsGroup1 - + " mDynamicAudioBufferSizeSupportedCodecsGroup2 = " - + mDynamicAudioBufferSizeSupportedCodecsGroup2 - + " mIsLePeriodicAdvertisingSyncTransferSenderSupported = " - + mIsLePeriodicAdvertisingSyncTransferSenderSupported - + " mIsLeConnectedIsochronousStreamCentralSupported = " - + mIsLeConnectedIsochronousStreamCentralSupported - + " mIsLeIsochronousBroadcasterSupported = " - + mIsLeIsochronousBroadcasterSupported - + " mIsLePeriodicAdvertisingSyncTransferRecipientSupported = " - + mIsLePeriodicAdvertisingSyncTransferRecipientSupported - + " mIsOffloadedTransportDiscoveryDataScanSupported = " - + mIsOffloadedTransportDiscoveryDataScanSupported); + Log.d( + TAG, + "BT_PROPERTY_LOCAL_LE_FEATURES: update from BT controller" + + " mNumOfAdvertisementInstancesSupported = " + + mNumOfAdvertisementInstancesSupported + + " mRpaOffloadSupported = " + + mRpaOffloadSupported + + " mNumOfOffloadedIrkSupported = " + + mNumOfOffloadedIrkSupported + + " mNumOfOffloadedScanFilterSupported = " + + mNumOfOffloadedScanFilterSupported + + " mOffloadedScanResultStorageBytes= " + + mOffloadedScanResultStorageBytes + + " mIsActivityAndEnergyReporting = " + + mIsActivityAndEnergyReporting + + " mVersSupported = " + + mVersSupported + + " mTotNumOfTrackableAdv = " + + mTotNumOfTrackableAdv + + " mIsExtendedScanSupported = " + + mIsExtendedScanSupported + + " mIsDebugLogSupported = " + + mIsDebugLogSupported + + " mIsLe2MPhySupported = " + + mIsLe2MPhySupported + + " mIsLeCodedPhySupported = " + + mIsLeCodedPhySupported + + " mIsLeExtendedAdvertisingSupported = " + + mIsLeExtendedAdvertisingSupported + + " mIsLePeriodicAdvertisingSupported = " + + mIsLePeriodicAdvertisingSupported + + " mLeMaximumAdvertisingDataLength = " + + mLeMaximumAdvertisingDataLength + + " mDynamicAudioBufferSizeSupportedCodecsGroup1 = " + + mDynamicAudioBufferSizeSupportedCodecsGroup1 + + " mDynamicAudioBufferSizeSupportedCodecsGroup2 = " + + mDynamicAudioBufferSizeSupportedCodecsGroup2 + + " mIsLePeriodicAdvertisingSyncTransferSenderSupported = " + + mIsLePeriodicAdvertisingSyncTransferSenderSupported + + " mIsLeConnectedIsochronousStreamCentralSupported = " + + mIsLeConnectedIsochronousStreamCentralSupported + + " mIsLeIsochronousBroadcasterSupported = " + + mIsLeIsochronousBroadcasterSupported + + " mIsLePeriodicAdvertisingSyncTransferRecipientSupported = " + + mIsLePeriodicAdvertisingSyncTransferRecipientSupported + + " mIsOffloadedTransportDiscoveryDataScanSupported = " + + mIsOffloadedTransportDiscoveryDataScanSupported); invalidateIsOffloadedFilteringSupportedCache(); } @@ -1125,12 +1194,12 @@ class AdapterProperties { List bufferConstraintList = new ArrayList(); for (int i = 0; i < BufferConstraints.BUFFER_CODEC_MAX_NUM; i++) { - int defaultBufferTime = ((0xFF & ((int) val[i * 6 + 1])) << 8) - + (0xFF & ((int) val[i * 6])); - int maximumBufferTime = ((0xFF & ((int) val[i * 6 + 3])) << 8) - + (0xFF & ((int) val[i * 6 + 2])); - int minimumBufferTime = ((0xFF & ((int) val[i * 6 + 5])) << 8) - + (0xFF & ((int) val[i * 6 + 4])); + int defaultBufferTime = + ((0xFF & ((int) val[i * 6 + 1])) << 8) + (0xFF & ((int) val[i * 6])); + int maximumBufferTime = + ((0xFF & ((int) val[i * 6 + 3])) << 8) + (0xFF & ((int) val[i * 6 + 2])); + int minimumBufferTime = + ((0xFF & ((int) val[i * 6 + 5])) << 8) + (0xFF & ((int) val[i * 6 + 4])); bufferConstraintList.add( new BufferConstraint(defaultBufferTime, maximumBufferTime, minimumBufferTime)); } @@ -1139,8 +1208,11 @@ class AdapterProperties { } void onBluetoothReady() { - debugLog("onBluetoothReady, state=" + BluetoothAdapter.nameForState(getState()) - + ", ScanMode=" + mScanMode); + debugLog( + "onBluetoothReady, state=" + + BluetoothAdapter.nameForState(getState()) + + ", ScanMode=" + + mScanMode); synchronized (mObject) { // Reset adapter and profile connection states @@ -1251,7 +1323,6 @@ class AdapterProperties { for (String log : mScanModeChanges) { writer.println(" " + log); } - } private String dumpDeviceType(int deviceType) { diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterState.java b/android/app/src/com/android/bluetooth/btservice/AdapterState.java index 2e03054a05d..cd2182c1a7d 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterState.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterState.java @@ -27,35 +27,17 @@ import com.android.internal.util.State; import com.android.internal.util.StateMachine; /** - * This state machine handles Bluetooth Adapter State. - * Stable States: - * {@link OffState}: Initial State - * {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on - * {@link OnState} : Bluetooth is on (All supported profiles) + * This state machine handles Bluetooth Adapter State. Stable States: {@link OffState}: Initial + * State {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on {@link OnState} : + * Bluetooth is on (All supported profiles) * - * Transition States: - * {@link TurningBleOnState} : OffState to BleOnState - * {@link TurningBleOffState} : BleOnState to OffState - * {@link TurningOnState} : BleOnState to OnState - * {@link TurningOffState} : OnState to BleOnState - * - * +------ Off <-----+ - * | | - * v | - * TurningBleOn TO---> TurningBleOff - * | ^ ^ - * | | | - * +-----> ----+ | - * BleOn | - * +------ <---+ O - * v | T - * TurningOn TO----> TurningOff - * | ^ - * | | - * +-----> On ------+ + *

Transition States: {@link TurningBleOnState} : OffState to BleOnState {@link + * TurningBleOffState} : BleOnState to OffState {@link TurningOnState} : BleOnState to OnState + * {@link TurningOffState} : OnState to BleOnState * + *

+------ Off <-----+ | | v | TurningBleOn TO---> TurningBleOff | ^ ^ | | | +-----> ----+ | + * BleOn | +------ <---+ O v | T TurningOn TO----> TurningOff | ^ | | +-----> On ------+ */ - final class AdapterState extends StateMachine { private static final String TAG = AdapterState.class.getSimpleName(); @@ -72,19 +54,17 @@ final class AdapterState extends StateMachine { static final int BLE_STOP_TIMEOUT = 11; static final int BLE_START_TIMEOUT = 12; - static final String BLE_START_TIMEOUT_DELAY_PROPERTY = - "ro.bluetooth.ble_start_timeout_delay"; - static final String BLE_STOP_TIMEOUT_DELAY_PROPERTY = - "ro.bluetooth.ble_stop_timeout_delay"; + static final String BLE_START_TIMEOUT_DELAY_PROPERTY = "ro.bluetooth.ble_start_timeout_delay"; + static final String BLE_STOP_TIMEOUT_DELAY_PROPERTY = "ro.bluetooth.ble_stop_timeout_delay"; static final int BLE_START_TIMEOUT_DELAY = - 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); static final int BLE_STOP_TIMEOUT_DELAY = - 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); static final int BREDR_START_TIMEOUT_DELAY = - 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); static final int BREDR_STOP_TIMEOUT_DELAY = - 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); private AdapterService mAdapterService; private TurningOnState mTurningOnState = new TurningOnState(); @@ -113,19 +93,32 @@ final class AdapterState extends StateMachine { private String messageString(int message) { switch (message) { - case BLE_TURN_ON: return "BLE_TURN_ON"; - case USER_TURN_ON: return "USER_TURN_ON"; - case BREDR_STARTED: return "BREDR_STARTED"; - case BLE_STARTED: return "BLE_STARTED"; - case USER_TURN_OFF: return "USER_TURN_OFF"; - case BLE_TURN_OFF: return "BLE_TURN_OFF"; - case BLE_STOPPED: return "BLE_STOPPED"; - case BREDR_STOPPED: return "BREDR_STOPPED"; - case BLE_START_TIMEOUT: return "BLE_START_TIMEOUT"; - case BLE_STOP_TIMEOUT: return "BLE_STOP_TIMEOUT"; - case BREDR_START_TIMEOUT: return "BREDR_START_TIMEOUT"; - case BREDR_STOP_TIMEOUT: return "BREDR_STOP_TIMEOUT"; - default: return "Unknown message (" + message + ")"; + case BLE_TURN_ON: + return "BLE_TURN_ON"; + case USER_TURN_ON: + return "USER_TURN_ON"; + case BREDR_STARTED: + return "BREDR_STARTED"; + case BLE_STARTED: + return "BLE_STARTED"; + case USER_TURN_OFF: + return "USER_TURN_OFF"; + case BLE_TURN_OFF: + return "BLE_TURN_OFF"; + case BLE_STOPPED: + return "BLE_STOPPED"; + case BREDR_STOPPED: + return "BREDR_STOPPED"; + case BLE_START_TIMEOUT: + return "BLE_START_TIMEOUT"; + case BLE_STOP_TIMEOUT: + return "BLE_STOP_TIMEOUT"; + case BREDR_START_TIMEOUT: + return "BREDR_START_TIMEOUT"; + case BREDR_STOP_TIMEOUT: + return "BREDR_STOP_TIMEOUT"; + default: + return "Unknown message (" + message + ")"; } } @@ -263,8 +256,9 @@ final class AdapterState extends StateMachine { @Override public void enter() { super.enter(); - final int timeoutDelay = SystemProperties.getInt( - BLE_START_TIMEOUT_DELAY_PROPERTY, BLE_START_TIMEOUT_DELAY); + final int timeoutDelay = + SystemProperties.getInt( + BLE_START_TIMEOUT_DELAY_PROPERTY, BLE_START_TIMEOUT_DELAY); Log.d(TAG, "Start Timeout Delay: " + timeoutDelay); sendMessageDelayed(BLE_START_TIMEOUT, timeoutDelay); mAdapterService.bringUpBle(); @@ -386,8 +380,9 @@ final class AdapterState extends StateMachine { @Override public void enter() { super.enter(); - final int timeoutDelay = SystemProperties.getInt( - BLE_STOP_TIMEOUT_DELAY_PROPERTY, BLE_STOP_TIMEOUT_DELAY); + final int timeoutDelay = + SystemProperties.getInt( + BLE_STOP_TIMEOUT_DELAY_PROPERTY, BLE_STOP_TIMEOUT_DELAY); Log.d(TAG, "Stop Timeout Delay: " + timeoutDelay); sendMessageDelayed(BLE_STOP_TIMEOUT, timeoutDelay); mAdapterService.bringDownBle(); diff --git a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java index 8b1dc2e8b5f..8f2ca9c3592 100644 --- a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java +++ b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java @@ -564,25 +564,26 @@ public class AudioRoutingManager extends ActiveDeviceManager { + ", " + device + ")"); - boolean activated = switch (profile) { - case BluetoothProfile.A2DP -> { - A2dpService service = mFactory.getA2dpService(); - yield service == null ? false : service.setActiveDevice(device); - } - case BluetoothProfile.HEADSET -> { - HeadsetService service = mFactory.getHeadsetService(); - yield service == null ? false : service.setActiveDevice(device); - } - case BluetoothProfile.LE_AUDIO -> { - LeAudioService service = mFactory.getLeAudioService(); - yield service == null ? false : service.setActiveDevice(device); - } - case BluetoothProfile.HEARING_AID -> { - HearingAidService service = mFactory.getHearingAidService(); - yield service == null ? false : service.setActiveDevice(device); - } - default -> false; - }; + boolean activated = + switch (profile) { + case BluetoothProfile.A2DP -> { + A2dpService service = mFactory.getA2dpService(); + yield service == null ? false : service.setActiveDevice(device); + } + case BluetoothProfile.HEADSET -> { + HeadsetService service = mFactory.getHeadsetService(); + yield service == null ? false : service.setActiveDevice(device); + } + case BluetoothProfile.LE_AUDIO -> { + LeAudioService service = mFactory.getLeAudioService(); + yield service == null ? false : service.setActiveDevice(device); + } + case BluetoothProfile.HEARING_AID -> { + HearingAidService service = mFactory.getHearingAidService(); + yield service == null ? false : service.setActiveDevice(device); + } + default -> false; + }; if (activated) { List activeDevices = mActiveDevices.get(profile); if (activeDevices == null) { @@ -756,19 +757,22 @@ public class AudioRoutingManager extends ActiveDeviceManager { public boolean canActivateNow(int profile) { if (!connectedProfiles.contains(profile)) return false; return switch (profile) { - case BluetoothProfile.HEADSET -> !supportedProfiles.contains( - BluetoothProfile.A2DP) - || connectedProfiles.contains(BluetoothProfile.A2DP); - case BluetoothProfile.A2DP -> !supportedProfiles.contains( - BluetoothProfile.HEADSET) - || connectedProfiles.contains(BluetoothProfile.HEADSET); - case BluetoothProfile.LE_AUDIO -> !Utils.isDualModeAudioEnabled() - // Check all supported A2DP and HFP are connected if dual mode enabled - || ((connectedProfiles.contains(BluetoothProfile.A2DP) - || !supportedProfiles.contains(BluetoothProfile.A2DP)) - && (connectedProfiles.contains(BluetoothProfile.HEADSET) - || !supportedProfiles.contains( - BluetoothProfile.HEADSET))); + case BluetoothProfile.HEADSET -> + !supportedProfiles.contains(BluetoothProfile.A2DP) + || connectedProfiles.contains(BluetoothProfile.A2DP); + case BluetoothProfile.A2DP -> + !supportedProfiles.contains(BluetoothProfile.HEADSET) + || connectedProfiles.contains(BluetoothProfile.HEADSET); + case BluetoothProfile.LE_AUDIO -> + !Utils.isDualModeAudioEnabled() + // Check all supported A2DP and HFP are connected if dual mode + // enabled + || ((connectedProfiles.contains(BluetoothProfile.A2DP) + || !supportedProfiles.contains( + BluetoothProfile.A2DP)) + && (connectedProfiles.contains(BluetoothProfile.HEADSET) + || !supportedProfiles.contains( + BluetoothProfile.HEADSET))); default -> true; }; } diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java b/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java index 4376097c22d..aeb297dcb07 100644 --- a/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java +++ b/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java @@ -24,9 +24,9 @@ import com.android.internal.annotations.VisibleForTesting; /** * A proxy class that facilitates testing of the ScanManager. * - * This is necessary due to the "final" attribute of the BluetoothAdapter class. In order to - * test the correct functioning of the ScanManager class, the final class must be put - * into a container that can be mocked correctly. + *

This is necessary due to the "final" attribute of the BluetoothAdapter class. In order to test + * the correct functioning of the ScanManager class, the final class must be put into a container + * that can be mocked correctly. */ public class BluetoothAdapterProxy { private static final String TAG = BluetoothAdapterProxy.class.getSimpleName(); diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java index 3fa40e4b182..279d625c8c8 100644 --- a/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java +++ b/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java @@ -70,9 +70,7 @@ public class BluetoothQualityReportNativeInterface { cleanupNative(); } - /** - * Callback from the native stack back into the Java framework. - */ + /** Callback from the native stack back into the Java framework. */ private void bqrDeliver( byte[] remoteAddr, int lmpVer, int lmpSubVer, int manufacturerId, byte[] bqrRawData) { BluetoothClass remoteBtClass = null; @@ -91,8 +89,12 @@ public class BluetoothQualityReportNativeInterface { remoteName = device.getName(); remoteBtClass = device.getBluetoothClass(); } else { - Log.e(TAG, "bqrDeliver failed: " - + (remoteAddress == null ? "remoteAddress is null" : "adapter is null")); + Log.e( + TAG, + "bqrDeliver failed: " + + (remoteAddress == null + ? "remoteAddress is null" + : "adapter is null")); return; } diff --git a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java index 355a3ad5a9b..10f3b195358 100644 --- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java +++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java @@ -58,13 +58,10 @@ import java.util.Optional; import java.util.Set; /** - * This state machine handles Bluetooth Adapter State. - * States: - * {@link StableState} : No device is in bonding / unbonding state. - * {@link PendingCommandState} : Some device is in bonding / unbonding state. - * TODO(BT) This class can be removed and this logic moved to the stack. + * This state machine handles Bluetooth Adapter State. States: {@link StableState} : No device is in + * bonding / unbonding state. {@link PendingCommandState} : Some device is in bonding / unbonding + * state. TODO(BT) This class can be removed and this logic moved to the stack. */ - final class BondStateMachine extends StateMachine { private static final String TAG = "BluetoothBondStateMachine"; @@ -99,8 +96,8 @@ final class BondStateMachine extends StateMachine { @VisibleForTesting Set mPendingBondedDevices = new HashSet<>(); - private BondStateMachine(AdapterService service, AdapterProperties prop, - RemoteDevices remoteDevices) { + private BondStateMachine( + AdapterService service, AdapterProperties prop, RemoteDevices remoteDevices) { super("BondStateMachine:"); addState(mStableState); addState(mPendingCommandState); @@ -111,8 +108,8 @@ final class BondStateMachine extends StateMachine { setInitialState(mStableState); } - public static BondStateMachine make(AdapterService service, AdapterProperties prop, - RemoteDevices remoteDevices) { + public static BondStateMachine make( + AdapterService service, AdapterProperties prop, RemoteDevices remoteDevices) { Log.d(TAG, "make"); BondStateMachine bsm = new BondStateMachine(service, prop, remoteDevices); bsm.start(); @@ -146,7 +143,6 @@ final class BondStateMachine extends StateMachine { BluetoothDevice dev = (BluetoothDevice) msg.obj; switch (msg.what) { - case CREATE_BOND: /* BOND_BONDED event is send after keys are exchanged, but BTIF layer would still use bonding control blocks until service discovery is finished. If @@ -183,10 +179,14 @@ final class BondStateMachine extends StateMachine { } } - OobData p192Data = (msg.getData() != null) - ? msg.getData().getParcelable(OOBDATAP192) : null; - OobData p256Data = (msg.getData() != null) - ? msg.getData().getParcelable(OOBDATAP256) : null; + OobData p192Data = + (msg.getData() != null) + ? msg.getData().getParcelable(OOBDATAP192) + : null; + OobData p256Data = + (msg.getData() != null) + ? msg.getData().getParcelable(OOBDATAP256) + : null; createBond(dev, msg.arg1, p192Data, p256Data, true); break; case REMOVE_BOND: @@ -194,16 +194,18 @@ final class BondStateMachine extends StateMachine { break; case BONDING_STATE_CHANGE: int newState = msg.arg1; - /* if incoming pairing, transition to pending state */ + /* if incoming pairing, transition to pending state */ if (newState == BluetoothDevice.BOND_BONDING) { deferMessage(msg); transitionTo(mPendingCommandState); } else if (newState == BluetoothDevice.BOND_NONE) { - /* if the link key was deleted by the stack */ + /* if the link key was deleted by the stack */ sendIntent(dev, newState, 0, false); } else { - Log.e(TAG, "In stable state, received invalid newState: " - + state2str(newState)); + Log.e( + TAG, + "In stable state, received invalid newState: " + + state2str(newState)); } break; case BONDED_INTENT_DELAY: @@ -240,18 +242,24 @@ final class BondStateMachine extends StateMachine { DeviceProperties devProp = mRemoteDevices.getDeviceProperties(dev); boolean result = false; if ((mDevices.contains(dev) || mPendingBondedDevices.contains(dev)) - && msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE - && msg.what != SSP_REQUEST && msg.what != PIN_REQUEST) { + && msg.what != CANCEL_BOND + && msg.what != BONDING_STATE_CHANGE + && msg.what != SSP_REQUEST + && msg.what != PIN_REQUEST) { deferMessage(msg); return true; } switch (msg.what) { case CREATE_BOND: - OobData p192Data = (msg.getData() != null) - ? msg.getData().getParcelable(OOBDATAP192) : null; - OobData p256Data = (msg.getData() != null) - ? msg.getData().getParcelable(OOBDATAP256) : null; + OobData p192Data = + (msg.getData() != null) + ? msg.getData().getParcelable(OOBDATAP192) + : null; + OobData p256Data = + (msg.getData() != null) + ? msg.getData().getParcelable(OOBDATAP256) + : null; result = createBond(dev, msg.arg1, p192Data, p256Data, false); break; case REMOVE_BOND: @@ -278,12 +286,12 @@ final class BondStateMachine extends StateMachine { transitionTo(mStableState); } if (newState == BluetoothDevice.BOND_NONE) { - mAdapterService.setPhonebookAccessPermission(dev, - BluetoothDevice.ACCESS_UNKNOWN); - mAdapterService.setMessageAccessPermission(dev, - BluetoothDevice.ACCESS_UNKNOWN); - mAdapterService.setSimAccessPermission(dev, - BluetoothDevice.ACCESS_UNKNOWN); + mAdapterService.setPhonebookAccessPermission( + dev, BluetoothDevice.ACCESS_UNKNOWN); + mAdapterService.setMessageAccessPermission( + dev, BluetoothDevice.ACCESS_UNKNOWN); + mAdapterService.setSimAccessPermission( + dev, BluetoothDevice.ACCESS_UNKNOWN); // Set the profile Priorities to undefined clearProfilePriority(dev); } @@ -323,7 +331,7 @@ final class BondStateMachine extends StateMachine { // passkey and displaying it to the user. If the keyboard doesn't follow // the spec recommendation, check if the keyboard has a fixed PIN zero // and pair. - //TODO: Maintain list of devices that have fixed pin + // TODO: Maintain list of devices that have fixed pin // Generate a variable 6-digit PIN in range of 100000-999999 // This is not truly random but good enough. int pin = 100000 + (int) Math.floor((Math.random() * (999999 - 100000))); @@ -396,12 +404,17 @@ final class BondStateMachine extends StateMachine { return false; } - @RequiresPermission(allOf = { + @RequiresPermission( + allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.INTERACT_ACROSS_USERS, - }) - private boolean createBond(BluetoothDevice dev, int transport, OobData remoteP192Data, - OobData remoteP256Data, boolean transition) { + }) + private boolean createBond( + BluetoothDevice dev, + int transport, + OobData remoteP192Data, + OobData remoteP256Data, + boolean transition) { if (dev.getBondState() == BluetoothDevice.BOND_NONE) { infoLog("Bond address is:" + dev + ", transport is: " + transport); byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); @@ -409,28 +422,41 @@ final class BondStateMachine extends StateMachine { boolean result; // If we have some data if (remoteP192Data != null || remoteP256Data != null) { - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(dev), transport, dev.getType(), - BluetoothDevice.BOND_BONDING, - BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING_OOB, - BluetoothProtoEnums.UNBOND_REASON_UNKNOWN, mAdapterService.getMetricId(dev)); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(dev), + transport, + dev.getType(), + BluetoothDevice.BOND_BONDING, + BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING_OOB, + BluetoothProtoEnums.UNBOND_REASON_UNKNOWN, + mAdapterService.getMetricId(dev)); result = mAdapterService .getNative() .createBondOutOfBand( addr, transport, remoteP192Data, remoteP256Data); } else { - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(dev), transport, dev.getType(), - BluetoothDevice.BOND_BONDING, - BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING, - BluetoothProtoEnums.UNBOND_REASON_UNKNOWN, mAdapterService.getMetricId(dev)); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(dev), + transport, + dev.getType(), + BluetoothDevice.BOND_BONDING, + BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING, + BluetoothProtoEnums.UNBOND_REASON_UNKNOWN, + mAdapterService.getMetricId(dev)); result = mAdapterService.getNative().createBond(addr, addrType, transport); } - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED, - mAdapterService.getMetricId(dev), dev.getName()); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(dev), transport, dev.getType(), + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED, + mAdapterService.getMetricId(dev), + dev.getName()); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(dev), + transport, + dev.getType(), BluetoothDevice.BOND_BONDING, remoteP192Data == null && remoteP256Data == null ? BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN @@ -438,12 +464,19 @@ final class BondStateMachine extends StateMachine { BluetoothProtoEnums.UNBOND_REASON_UNKNOWN); if (!result) { - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(dev), transport, dev.getType(), - BluetoothDevice.BOND_NONE, BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN, + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(dev), + transport, + dev.getType(), + BluetoothDevice.BOND_NONE, + BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN, BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS); // Using UNBOND_REASON_REMOVED for legacy reason - sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED, + sendIntent( + dev, + BluetoothDevice.BOND_NONE, + BluetoothDevice.UNBOND_REASON_REMOVED, false); return false; } else if (transition) { @@ -474,12 +507,13 @@ final class BondStateMachine extends StateMachine { } @VisibleForTesting - @RequiresPermission(allOf = { + @RequiresPermission( + allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.INTERACT_ACROSS_USERS, - }) - void sendIntent(BluetoothDevice device, int newState, int reason, - boolean isTriggerFromDelayMessage) { + }) + void sendIntent( + BluetoothDevice device, int newState, int reason, boolean isTriggerFromDelayMessage) { DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device); int oldState = BluetoothDevice.BOND_NONE; if (newState != BluetoothDevice.BOND_NONE @@ -494,12 +528,17 @@ final class BondStateMachine extends StateMachine { if (devProp != null) { oldState = devProp.getBondState(); } - if (isTriggerFromDelayMessage && (oldState != BluetoothDevice.BOND_BONDED - || newState != BluetoothDevice.BOND_BONDED - || !mPendingBondedDevices.contains(device))) { - infoLog("Invalid state when doing delay send bonded intent, oldState: " + oldState - + ", newState: " + newState + ", in PendingBondedDevices list? " - + mPendingBondedDevices.contains(device)); + if (isTriggerFromDelayMessage + && (oldState != BluetoothDevice.BOND_BONDED + || newState != BluetoothDevice.BOND_BONDED + || !mPendingBondedDevices.contains(device))) { + infoLog( + "Invalid state when doing delay send bonded intent, oldState: " + + oldState + + ", newState: " + + newState + + ", in PendingBondedDevices list? " + + mPendingBondedDevices.contains(device)); return; } if (mPendingBondedDevices.contains(device)) { @@ -517,19 +556,28 @@ final class BondStateMachine extends StateMachine { if (oldState == newState) { return; } - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(device), 0, device.getType(), - newState, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_BOND_STATE_INTENT_SENT, reason, + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(device), + 0, + device.getType(), + newState, + BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_BOND_STATE_INTENT_SENT, + reason, mAdapterService.getMetricId(device)); BluetoothClass deviceClass = device.getBluetoothClass(); int classOfDevice = deviceClass == null ? 0 : deviceClass.getClassOfDevice(); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED, - mAdapterService.obfuscateAddress(device), classOfDevice, + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED, + mAdapterService.obfuscateAddress(device), + classOfDevice, mAdapterService.getMetricId(device)); mAdapterProperties.onBondStateChanged(device, newState); - if (!isTriggerFromDelayMessage && newState == BluetoothDevice.BOND_BONDED - && devProp != null && devProp.getUuids() == null) { + if (!isTriggerFromDelayMessage + && newState == BluetoothDevice.BOND_BONDED + && devProp != null + && devProp.getUuids() == null) { infoLog(device + " is bonded, wait for SDP complete to broadcast bonded intent"); if (!mPendingBondedDevices.contains(device)) { mPendingBondedDevices.add(device); @@ -559,8 +607,13 @@ final class BondStateMachine extends StateMachine { UserHandle.ALL, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); - infoLog("Bond State Change Intent:" + device + " " + state2str(oldState) + " => " - + state2str(newState)); + infoLog( + "Bond State Change Intent:" + + device + + " " + + state2str(oldState) + + " => " + + state2str(newState)); } void bondStateChangeCallback(int status, byte[] address, int newState, int hciReason) { @@ -573,8 +626,15 @@ final class BondStateMachine extends StateMachine { device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address)); } - infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device + " newState: " - + newState + " hciReason: " + hciReason); + infoLog( + "bondStateChangeCallback: Status: " + + status + + " Address: " + + device + + " newState: " + + newState + + " hciReason: " + + hciReason); Message msg = obtainMessage(BONDING_STATE_CHANGE); msg.obj = device; @@ -597,13 +657,16 @@ final class BondStateMachine extends StateMachine { if (bdDevice == null) { mRemoteDevices.addDeviceProperties(address); } - infoLog("sspRequestCallback: " + Utils.getRedactedAddressStringFromByte(address) - + " pairingVariant " + pairingVariant - + " passkey: " + (Build.isDebuggable() ? passkey : "******")); + infoLog( + "sspRequestCallback: " + + Utils.getRedactedAddressStringFromByte(address) + + " pairingVariant " + + pairingVariant + + " passkey: " + + (Build.isDebuggable() ? passkey : "******")); int variant; boolean displayPasskey = false; switch (pairingVariant) { - case AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION: variant = BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION; displayPasskey = true; @@ -633,10 +696,14 @@ final class BondStateMachine extends StateMachine { device = Objects.requireNonNull(mRemoteDevices.getDevice(address)); } - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(device), 0, device.getType(), + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(device), + 0, + device.getType(), BluetoothDevice.BOND_BONDING, - BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REQUESTED, 0); + BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REQUESTED, + 0); Message msg = obtainMessage(SSP_REQUEST); msg.obj = device; @@ -652,7 +719,7 @@ final class BondStateMachine extends StateMachine { @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) void pinRequestCallback(byte[] address, byte[] name, int cod, boolean min16Digits) { - //TODO(BT): Get wakelock and update name and cod + // TODO(BT): Get wakelock and update name and cod BluetoothDevice bdDevice = mRemoteDevices.getDevice(address); if (bdDevice == null) { @@ -660,13 +727,22 @@ final class BondStateMachine extends StateMachine { bdDevice = Objects.requireNonNull(mRemoteDevices.getDevice(address)); } - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, - mAdapterService.obfuscateAddress(bdDevice), 0, bdDevice.getType(), + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, + mAdapterService.obfuscateAddress(bdDevice), + 0, + bdDevice.getType(), BluetoothDevice.BOND_BONDING, - BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REQUESTED, 0); + BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REQUESTED, + 0); - infoLog("pinRequestCallback: " + bdDevice - + " name:" + Utils.getName(bdDevice) + " cod:" + new BluetoothClass(cod)); + infoLog( + "pinRequestCallback: " + + bdDevice + + " name:" + + Utils.getName(bdDevice) + + " cod:" + + new BluetoothClass(cod)); Message msg = obtainMessage(PIN_REQUEST); msg.obj = bdDevice; @@ -691,10 +767,11 @@ final class BondStateMachine extends StateMachine { removeMessages(what); } - @RequiresPermission(allOf = { - android.Manifest.permission.BLUETOOTH_PRIVILEGED, - android.Manifest.permission.MODIFY_PHONE_STATE, - }) + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + android.Manifest.permission.MODIFY_PHONE_STATE, + }) private void clearProfilePriority(BluetoothDevice device) { HidHostService hidService = HidHostService.getHidHostService(); A2dpService a2dpService = A2dpService.getA2dpService(); @@ -718,15 +795,15 @@ final class BondStateMachine extends StateMachine { headsetService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } if (headsetClientService != null) { - headsetClientService.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + headsetClientService.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } if (a2dpSinkService != null) { a2dpSinkService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } if (pbapClientService != null) { - pbapClientService.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + pbapClientService.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } if (leAudioService != null) { leAudioService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); diff --git a/android/app/src/com/android/bluetooth/btservice/CompanionManager.java b/android/app/src/com/android/bluetooth/btservice/CompanionManager.java index 16a6c556dc0..bd56a7dcc22 100644 --- a/android/app/src/com/android/bluetooth/btservice/CompanionManager.java +++ b/android/app/src/com/android/bluetooth/btservice/CompanionManager.java @@ -32,16 +32,14 @@ import java.util.HashSet; import java.util.Set; /** - A CompanionManager to specify parameters between companion devices and regular devices. - - 1. A paired device is recognized as a companion device if its METADATA_SOFTWARE_VERSION is - set to BluetoothDevice.COMPANION_TYPE_PRIMARY or BluetoothDevice.COMPANION_TYPE_SECONDARY. - 2. Only can have one companion device at a time. - 3. Remove bond does not remove the companion device record. - 4. Factory reset Bluetooth removes the companion device. - 5. Companion device has individual GATT connection parameters. -*/ - + * A CompanionManager to specify parameters between companion devices and regular devices. + * + *

1. A paired device is recognized as a companion device if its METADATA_SOFTWARE_VERSION is set + * to BluetoothDevice.COMPANION_TYPE_PRIMARY or BluetoothDevice.COMPANION_TYPE_SECONDARY. 2. Only + * can have one companion device at a time. 3. Remove bond does not remove the companion device + * record. 4. Factory reset Bluetooth removes the companion device. 5. Companion device has + * individual GATT connection parameters. + */ public class CompanionManager { private static final String TAG = "BluetoothCompanionManager"; @@ -59,13 +57,13 @@ public class CompanionManager { private final int[] mGattConnLowDefault; private final int[] mGattConnDckDefault; - @VisibleForTesting static final int COMPANION_TYPE_NONE = 0; - @VisibleForTesting static final int COMPANION_TYPE_PRIMARY = 1; + @VisibleForTesting static final int COMPANION_TYPE_NONE = 0; + @VisibleForTesting static final int COMPANION_TYPE_PRIMARY = 1; @VisibleForTesting static final int COMPANION_TYPE_SECONDARY = 2; public static final int GATT_CONN_INTERVAL_MIN = 0; public static final int GATT_CONN_INTERVAL_MAX = 1; - public static final int GATT_CONN_LATENCY = 2; + public static final int GATT_CONN_LATENCY = 2; @VisibleForTesting static final String COMPANION_INFO = "bluetooth_companion_info"; @VisibleForTesting static final String COMPANION_DEVICE_KEY = "companion_device"; @@ -95,72 +93,113 @@ public class CompanionManager { public CompanionManager(AdapterService service, ServiceFactory factory) { mAdapterService = service; - mGattConnHighDefault = new int[] { - getGattConfig(PROPERTY_HIGH_MIN_INTERVAL, - R.integer.gatt_high_priority_min_interval), - getGattConfig(PROPERTY_HIGH_MAX_INTERVAL, - R.integer.gatt_high_priority_max_interval), - getGattConfig(PROPERTY_HIGH_LATENCY, - R.integer.gatt_high_priority_latency)}; - mGattConnBalanceDefault = new int[] { - getGattConfig(PROPERTY_BALANCED_MIN_INTERVAL, - R.integer.gatt_balanced_priority_min_interval), - getGattConfig(PROPERTY_BALANCED_MAX_INTERVAL, - R.integer.gatt_balanced_priority_max_interval), - getGattConfig(PROPERTY_BALANCED_LATENCY, - R.integer.gatt_balanced_priority_latency)}; - mGattConnLowDefault = new int[] { - getGattConfig(PROPERTY_LOW_MIN_INTERVAL, R.integer.gatt_low_power_min_interval), - getGattConfig(PROPERTY_LOW_MAX_INTERVAL, R.integer.gatt_low_power_max_interval), - getGattConfig(PROPERTY_LOW_LATENCY, R.integer.gatt_low_power_latency)}; - mGattConnDckDefault = new int[] { - getGattConfig(PROPERTY_DCK_MIN_INTERVAL, R.integer.gatt_dck_priority_min_interval), - getGattConfig(PROPERTY_DCK_MAX_INTERVAL, R.integer.gatt_dck_priority_max_interval), - getGattConfig(PROPERTY_DCK_LATENCY, R.integer.gatt_dck_priority_latency)}; - - mGattConnHighPrimary = new int[] { - getGattConfig(PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_high_priority_min_interval_primary), - getGattConfig(PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_high_priority_max_interval_primary), - getGattConfig(PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_high_priority_latency_primary)}; - mGattConnBalancePrimary = new int[] { - getGattConfig(PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_balanced_priority_min_interval_primary), - getGattConfig(PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_balanced_priority_max_interval_primary), - getGattConfig(PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_balanced_priority_latency_primary)}; - mGattConnLowPrimary = new int[] { - getGattConfig(PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_low_power_min_interval_primary), - getGattConfig(PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_low_power_max_interval_primary), - getGattConfig(PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_PRIMARY, - R.integer.gatt_low_power_latency_primary)}; - - mGattConnHighSecondary = new int[] { - getGattConfig(PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_high_priority_min_interval_secondary), - getGattConfig(PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_high_priority_max_interval_secondary), - getGattConfig(PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_high_priority_latency_secondary)}; - mGattConnBalanceSecondary = new int[] { - getGattConfig(PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_balanced_priority_min_interval_secondary), - getGattConfig(PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_balanced_priority_max_interval_secondary), - getGattConfig(PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_balanced_priority_latency_secondary)}; - mGattConnLowSecondary = new int[] { - getGattConfig(PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_low_power_min_interval_secondary), - getGattConfig(PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_low_power_max_interval_secondary), - getGattConfig(PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_SECONDARY, - R.integer.gatt_low_power_latency_secondary)}; + mGattConnHighDefault = + new int[] { + getGattConfig( + PROPERTY_HIGH_MIN_INTERVAL, R.integer.gatt_high_priority_min_interval), + getGattConfig( + PROPERTY_HIGH_MAX_INTERVAL, R.integer.gatt_high_priority_max_interval), + getGattConfig(PROPERTY_HIGH_LATENCY, R.integer.gatt_high_priority_latency) + }; + mGattConnBalanceDefault = + new int[] { + getGattConfig( + PROPERTY_BALANCED_MIN_INTERVAL, + R.integer.gatt_balanced_priority_min_interval), + getGattConfig( + PROPERTY_BALANCED_MAX_INTERVAL, + R.integer.gatt_balanced_priority_max_interval), + getGattConfig( + PROPERTY_BALANCED_LATENCY, R.integer.gatt_balanced_priority_latency) + }; + mGattConnLowDefault = + new int[] { + getGattConfig(PROPERTY_LOW_MIN_INTERVAL, R.integer.gatt_low_power_min_interval), + getGattConfig(PROPERTY_LOW_MAX_INTERVAL, R.integer.gatt_low_power_max_interval), + getGattConfig(PROPERTY_LOW_LATENCY, R.integer.gatt_low_power_latency) + }; + mGattConnDckDefault = + new int[] { + getGattConfig( + PROPERTY_DCK_MIN_INTERVAL, R.integer.gatt_dck_priority_min_interval), + getGattConfig( + PROPERTY_DCK_MAX_INTERVAL, R.integer.gatt_dck_priority_max_interval), + getGattConfig(PROPERTY_DCK_LATENCY, R.integer.gatt_dck_priority_latency) + }; + + mGattConnHighPrimary = + new int[] { + getGattConfig( + PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_high_priority_min_interval_primary), + getGattConfig( + PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_high_priority_max_interval_primary), + getGattConfig( + PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_high_priority_latency_primary) + }; + mGattConnBalancePrimary = + new int[] { + getGattConfig( + PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_balanced_priority_min_interval_primary), + getGattConfig( + PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_balanced_priority_max_interval_primary), + getGattConfig( + PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_balanced_priority_latency_primary) + }; + mGattConnLowPrimary = + new int[] { + getGattConfig( + PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_low_power_min_interval_primary), + getGattConfig( + PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_low_power_max_interval_primary), + getGattConfig( + PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_PRIMARY, + R.integer.gatt_low_power_latency_primary) + }; + + mGattConnHighSecondary = + new int[] { + getGattConfig( + PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_high_priority_min_interval_secondary), + getGattConfig( + PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_high_priority_max_interval_secondary), + getGattConfig( + PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_high_priority_latency_secondary) + }; + mGattConnBalanceSecondary = + new int[] { + getGattConfig( + PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_balanced_priority_min_interval_secondary), + getGattConfig( + PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_balanced_priority_max_interval_secondary), + getGattConfig( + PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_balanced_priority_latency_secondary) + }; + mGattConnLowSecondary = + new int[] { + getGattConfig( + PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_low_power_min_interval_secondary), + getGattConfig( + PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_low_power_max_interval_secondary), + getGattConfig( + PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_SECONDARY, + R.integer.gatt_low_power_latency_secondary) + }; } private int getGattConfig(String property, int resId) { @@ -173,8 +212,8 @@ public class CompanionManager { try { mCompanionDevice = mAdapter.getRemoteDevice(address); - mCompanionType = getCompanionPreferences().getInt( - COMPANION_TYPE_KEY, COMPANION_TYPE_NONE); + mCompanionType = + getCompanionPreferences().getInt(COMPANION_TYPE_KEY, COMPANION_TYPE_NONE); } catch (IllegalArgumentException e) { mCompanionDevice = null; mCompanionType = COMPANION_TYPE_NONE; @@ -184,8 +223,9 @@ public class CompanionManager { if (mCompanionDevice == null) { // We don't have any companion phone registered, try look from the bonded devices for (BluetoothDevice device : mAdapter.getBondedDevices()) { - byte[] metadata = mAdapterService.getMetadata(device, - BluetoothDevice.METADATA_SOFTWARE_VERSION); + byte[] metadata = + mAdapterService.getMetadata( + device, BluetoothDevice.METADATA_SOFTWARE_VERSION); if (metadata == null) { continue; } @@ -208,11 +248,14 @@ public class CompanionManager { @Override public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) { String valueStr = new String(value); - Log.d(TAG, String.format("Metadata updated in Device %s: %d = %s.", device, - key, value == null ? null : valueStr)); + Log.d( + TAG, + String.format( + "Metadata updated in Device %s: %d = %s.", + device, key, value == null ? null : valueStr)); if (key == BluetoothDevice.METADATA_SOFTWARE_VERSION && (valueStr.equals(BluetoothDevice.COMPANION_TYPE_PRIMARY) - || valueStr.equals(BluetoothDevice.COMPANION_TYPE_SECONDARY))) { + || valueStr.equals(BluetoothDevice.COMPANION_TYPE_SECONDARY))) { setCompanionDevice(device, valueStr); } } @@ -222,16 +265,17 @@ public class CompanionManager { synchronized (mMetadataListeningDevices) { Log.i(TAG, "setCompanionDevice: " + companionDevice + ", type=" + type); mCompanionDevice = companionDevice; - mCompanionType = type.equals(BluetoothDevice.COMPANION_TYPE_PRIMARY) - ? COMPANION_TYPE_PRIMARY : COMPANION_TYPE_SECONDARY; + mCompanionType = + type.equals(BluetoothDevice.COMPANION_TYPE_PRIMARY) + ? COMPANION_TYPE_PRIMARY + : COMPANION_TYPE_SECONDARY; // unregister all metadata listeners for (BluetoothDevice device : mMetadataListeningDevices) { try { mAdapter.removeOnMetadataChangedListener(device, mMetadataListener); } catch (IllegalArgumentException e) { - Log.e(TAG, "failed to unregister metadata listener for " - + device + " " + e); + Log.e(TAG, "failed to unregister metadata listener for " + device + " " + e); } } mMetadataListeningDevices.clear(); @@ -279,8 +323,7 @@ public class CompanionManager { mAdapter.addOnMetadataChangedListener( device, mAdapterService.getMainExecutor(), mMetadataListener); } catch (IllegalArgumentException e) { - Log.e(TAG, "failed to register metadata listener for " - + device + " " + e); + Log.e(TAG, "failed to register metadata listener for " + device + " " + e); } mMetadataListeningDevices.add(device); } @@ -294,14 +337,12 @@ public class CompanionManager { try { mAdapter.removeOnMetadataChangedListener(device, mMetadataListener); } catch (IllegalArgumentException e) { - Log.e(TAG, "failed to unregister metadata listener for " - + device + " " + e); + Log.e(TAG, "failed to unregister metadata listener for " + device + " " + e); } mMetadataListeningDevices.remove(device); } } - /** * Method to get the stored companion device * @@ -336,9 +377,7 @@ public class CompanionManager { return device.equals(mCompanionDevice); } - /** - * Method to reset the stored companion info - */ + /** Method to reset the stored companion info */ public void factoryReset() { synchronized (mMetadataListeningDevices) { mCompanionDevice = null; @@ -355,11 +394,11 @@ public class CompanionManager { * Gets the GATT connection parameters of the device * * @param address the address of the Bluetooth device - * @param type type of the parameter, can be GATT_CONN_INTERVAL_MIN, GATT_CONN_INTERVAL_MAX - * or GATT_CONN_LATENCY + * @param type type of the parameter, can be GATT_CONN_INTERVAL_MIN, GATT_CONN_INTERVAL_MAX or + * GATT_CONN_LATENCY * @param priority the priority of the connection, can be - * BluetoothGatt.CONNECTION_PRIORITY_HIGH, BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER or - * BluetoothGatt.CONNECTION_PRIORITY_BALANCED + * BluetoothGatt.CONNECTION_PRIORITY_HIGH, BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER or + * BluetoothGatt.CONNECTION_PRIORITY_BALANCED * @return the connection parameter in integer */ public int getGattConnParameters(String address, int type, int priority) { diff --git a/android/app/src/com/android/bluetooth/btservice/DataMigration.java b/android/app/src/com/android/bluetooth/btservice/DataMigration.java index 7586658d377..3d4f9640607 100644 --- a/android/app/src/com/android/bluetooth/btservice/DataMigration.java +++ b/android/app/src/com/android/bluetooth/btservice/DataMigration.java @@ -32,21 +32,17 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.List; final class DataMigration { - private DataMigration(){} + private DataMigration() {} + private static final String TAG = "DataMigration"; - @VisibleForTesting - static final String AUTHORITY = "bluetooth_legacy.provider"; + @VisibleForTesting static final String AUTHORITY = "bluetooth_legacy.provider"; - @VisibleForTesting - static final String START_MIGRATION_CALL = "start_legacy_migration"; - @VisibleForTesting - static final String FINISH_MIGRATION_CALL = "finish_legacy_migration"; + @VisibleForTesting static final String START_MIGRATION_CALL = "start_legacy_migration"; + @VisibleForTesting static final String FINISH_MIGRATION_CALL = "finish_legacy_migration"; - @VisibleForTesting - static final String BLUETOOTH_DATABASE = "bluetooth_db"; - @VisibleForTesting - static final String OPP_DATABASE = "btopp.db"; + @VisibleForTesting static final String BLUETOOTH_DATABASE = "bluetooth_db"; + @VisibleForTesting static final String OPP_DATABASE = "btopp.db"; // AvrcpVolumeManager.VOLUME_MAP private static final String VOLUME_MAP_PREFERENCE_FILE = "bluetooth_volume_map"; @@ -78,26 +74,18 @@ final class DataMigration { }; // Main key use for storing all the key in the associate bundle - @VisibleForTesting - static final String KEY_LIST = "key_list"; + @VisibleForTesting static final String KEY_LIST = "key_list"; - @VisibleForTesting - static final String BLUETOOTH_CONFIG = "bluetooth_config"; + @VisibleForTesting static final String BLUETOOTH_CONFIG = "bluetooth_config"; static final String MIGRATION_DONE_PROPERTY = "migration_done"; - @VisibleForTesting - static final String MIGRATION_ATTEMPT_PROPERTY = "migration_attempt"; + @VisibleForTesting static final String MIGRATION_ATTEMPT_PROPERTY = "migration_attempt"; - @VisibleForTesting - public static final int MIGRATION_STATUS_TO_BE_DONE = 0; - @VisibleForTesting - public static final int MIGRATION_STATUS_COMPLETED = 1; - @VisibleForTesting - public static final int MIGRATION_STATUS_MISSING_APK = 2; - @VisibleForTesting - public static final int MIGRATION_STATUS_MAX_ATTEMPT = 3; + @VisibleForTesting public static final int MIGRATION_STATUS_TO_BE_DONE = 0; + @VisibleForTesting public static final int MIGRATION_STATUS_COMPLETED = 1; + @VisibleForTesting public static final int MIGRATION_STATUS_MISSING_APK = 2; + @VisibleForTesting public static final int MIGRATION_STATUS_MAX_ATTEMPT = 3; - @VisibleForTesting - static final int MAX_ATTEMPT = 3; + @VisibleForTesting static final int MAX_ATTEMPT = 3; static int run(Context ctx) { if (migrationStatus(ctx) == MIGRATION_STATUS_COMPLETED) { @@ -115,7 +103,7 @@ final class DataMigration { return MIGRATION_STATUS_MAX_ATTEMPT; } - for (String pref: sharedPreferencesKeys) { + for (String pref : sharedPreferencesKeys) { sharedPreferencesMigration(pref, ctx); } // Migration for DefaultSharedPreferences used in PbapUtils. Contains Long @@ -133,9 +121,13 @@ final class DataMigration { static boolean bluetoothDatabaseMigration(Context ctx) { final String logHeader = BLUETOOTH_DATABASE + ": "; ContentResolver resolver = ctx.getContentResolver(); - Cursor cursor = resolver.query( - Uri.parse("content://" + AUTHORITY + "/" + BLUETOOTH_DATABASE), - null, null, null, null); + Cursor cursor = + resolver.query( + Uri.parse("content://" + AUTHORITY + "/" + BLUETOOTH_DATABASE), + null, + null, + null, + null); if (cursor == null) { Log.d(TAG, logHeader + "Nothing to migrate"); return true; @@ -155,9 +147,13 @@ final class DataMigration { static boolean oppDatabaseMigration(Context ctx) { final String logHeader = OPP_DATABASE + ": "; ContentResolver resolver = ctx.getContentResolver(); - Cursor cursor = resolver.query( - Uri.parse("content://" + AUTHORITY + "/" + OPP_DATABASE), - null, null, null, null); + Cursor cursor = + resolver.query( + Uri.parse("content://" + AUTHORITY + "/" + OPP_DATABASE), + null, + null, + null, + null); if (cursor == null) { Log.d(TAG, logHeader + "Nothing to migrate"); return true; @@ -173,8 +169,8 @@ final class DataMigration { return status; } - private static boolean writeObjectToEditor(SharedPreferences.Editor editor, Bundle b, - String itemKey) { + private static boolean writeObjectToEditor( + SharedPreferences.Editor editor, Bundle b, String itemKey) { Object value = b.get(itemKey); if (value == null) { Log.e(TAG, itemKey + ": No value associated with this itemKey"); @@ -189,8 +185,12 @@ final class DataMigration { } else if (value instanceof String) { editor.putString(itemKey, (String) value); } else { - Log.e(TAG, itemKey + ": Failed to migrate: " - + value.getClass().getSimpleName() + ": Data type not handled"); + Log.e( + TAG, + itemKey + + ": Failed to migrate: " + + value.getClass().getSimpleName() + + ": Data type not handled"); return false; } return true; @@ -241,9 +241,7 @@ final class DataMigration { static boolean incrementeMigrationAttempt(Context ctx) { SharedPreferences pref = ctx.getSharedPreferences(BLUETOOTH_CONFIG, Context.MODE_PRIVATE); int currentAttempt = Math.min(pref.getInt(MIGRATION_ATTEMPT_PROPERTY, 0), MAX_ATTEMPT); - pref.edit() - .putInt(MIGRATION_ATTEMPT_PROPERTY, currentAttempt + 1) - .apply(); + pref.edit().putInt(MIGRATION_ATTEMPT_PROPERTY, currentAttempt + 1).apply(); return currentAttempt < MAX_ATTEMPT; } @@ -261,8 +259,8 @@ final class DataMigration { @VisibleForTesting static void markMigrationStatus(Context ctx, int status) { ctx.getSharedPreferences(BLUETOOTH_CONFIG, Context.MODE_PRIVATE) - .edit() - .putInt(MIGRATION_DONE_PROPERTY, status) - .apply(); + .edit() + .putInt(MIGRATION_DONE_PROPERTY, status) + .apply(); } } diff --git a/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java b/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java index 02b2c4bef8c..4e22c1ce4b4 100644 --- a/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java +++ b/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java @@ -19,9 +19,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -/** - * Class to generate a default Device Bloomfilter - */ +/** Class to generate a default Device Bloomfilter */ public class DeviceBloomfilterGenerator { public static final String BLOOM_FILTER_DEFAULT = @@ -373,8 +371,10 @@ public class DeviceBloomfilterGenerator { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) - + Character.digit(s.charAt(i + 1), 16)); + data[i / 2] = + (byte) + ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); } return data; } diff --git a/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java b/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java index 72bf389feb3..e2b72953228 100644 --- a/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java +++ b/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java @@ -24,7 +24,9 @@ final class DiscoveringPackage { private @Nullable String mPermission; private boolean mHasDisavowedLocation; - DiscoveringPackage(@NonNull String packageName, @Nullable String permission, + DiscoveringPackage( + @NonNull String packageName, + @Nullable String permission, boolean hasDisavowedLocation) { mPackageName = packageName; mPermission = permission; diff --git a/android/app/src/com/android/bluetooth/btservice/InteropUtil.java b/android/app/src/com/android/bluetooth/btservice/InteropUtil.java index 32e2476249d..93ab3ac4f2a 100644 --- a/android/app/src/com/android/bluetooth/btservice/InteropUtil.java +++ b/android/app/src/com/android/bluetooth/btservice/InteropUtil.java @@ -20,18 +20,17 @@ package com.android.bluetooth.btservice; import android.util.Log; /** - * APIs of interoperability workaround utilities. - * These APIs will call stack layer's interop APIs of interop.cc to do matching - * or entry adding/removing. + * APIs of interoperability workaround utilities. These APIs will call stack layer's interop APIs of + * interop.cc to do matching or entry adding/removing. */ public class InteropUtil { private static final String TAG = "InteropUtil"; /** - * Add interop feature from device/include/interop.h to below InteropFeature if - * this feature needs to be matched at java layer. Feature's name will be passed to - * stack layer to do matching, so make sure that the added feature's name is exactly - * same as that in device/include/interop.h. + * Add interop feature from device/include/interop.h to below InteropFeature if this feature + * needs to be matched at java layer. Feature's name will be passed to stack layer to do + * matching, so make sure that the added feature's name is exactly same as that in + * device/include/interop.h. */ public enum InteropFeature { INTEROP_NOT_UPDATE_AVRCP_PAUSED_TO_REMOTE, @@ -45,8 +44,8 @@ public class InteropUtil { } /** - * Check if a given address matches a known interoperability workaround - * identified by the interop feature. + * Check if a given address matches a known interoperability workaround identified by the + * interop feature. * * @param feature a given interop feature defined in {@link InteropFeature}. * @param address a given address to be matched. @@ -55,8 +54,11 @@ public class InteropUtil { public static boolean interopMatchAddr(InteropFeature feature, String address) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopMatchAddr: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopMatchAddr: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return false; } @@ -71,8 +73,8 @@ public class InteropUtil { } /** - * Check if a given name matches a known interoperability workaround - * identified by the interop feature. + * Check if a given name matches a known interoperability workaround identified by the interop + * feature. * * @param feature a given interop feature defined in {@link InteropFeature}. * @param name a given name to be matched. @@ -81,8 +83,11 @@ public class InteropUtil { public static boolean interopMatchName(InteropFeature feature, String name) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopMatchName: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopMatchName: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return false; } @@ -98,8 +103,8 @@ public class InteropUtil { /** * Check if a given address or remote device name matches a known interoperability workaround - * identified by the interop feature. remote device name will be fetched internally based on - * the given address at stack layer. + * identified by the interop feature. remote device name will be fetched internally based on the + * given address at stack layer. * * @param feature a given interop feature defined in {@link InteropFeature}. * @param address a given address to be matched. @@ -108,8 +113,11 @@ public class InteropUtil { public static boolean interopMatchAddrOrName(InteropFeature feature, String address) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopMatchAddrOrName: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopMatchAddrOrName: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return false; } @@ -124,25 +132,33 @@ public class InteropUtil { } /** - * Add a dynamic address interop database entry identified by the interop feature - * for a device matching the first length bytes of addr. + * Add a dynamic address interop database entry identified by the interop feature for a device + * matching the first length bytes of addr. * * @param feature a given interop feature defined in {@link InteropFeature}. * @param address a given address to be added. - * @param length the number of bytes of address to be stored, - * length must be in [1,6], and usually it is 3. + * @param length the number of bytes of address to be stored, length must be in [1,6], and + * usually it is 3. */ - public static void interopDatabaseAddAddr(InteropFeature feature, - String address, int length) { + public static void interopDatabaseAddAddr(InteropFeature feature, String address, int length) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopDatabaseAddAddr: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopDatabaseAddAddr: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return; } - Log.d(TAG, "interopDatabaseAddAddr: feature=" + feature.name() - + ", address=" + address + ", length=" + length); + Log.d( + TAG, + "interopDatabaseAddAddr: feature=" + + feature.name() + + ", address=" + + address + + ", length=" + + length); if (address == null || (length <= 0 || length > 6)) { return; } @@ -151,8 +167,8 @@ public class InteropUtil { } /** - * Remove a dynamic address interop database entry identified by the interop feature - * for a device matching the addr. + * Remove a dynamic address interop database entry identified by the interop feature for a + * device matching the addr. * * @param feature a given interop feature defined in {@link InteropFeature}. * @param address a given address to be removed. @@ -160,8 +176,11 @@ public class InteropUtil { public static void interopDatabaseRemoveAddr(InteropFeature feature, String address) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopDatabaseRemoveAddr: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopDatabaseRemoveAddr: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return; } @@ -182,8 +201,11 @@ public class InteropUtil { public static void interopDatabaseAddName(InteropFeature feature, String name) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopDatabaseAddName: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopDatabaseAddName: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return; } @@ -204,8 +226,11 @@ public class InteropUtil { public static void interopDatabaseRemoveName(InteropFeature feature, String name) { AdapterService adapterService = AdapterService.getAdapterService(); if (adapterService == null) { - Log.d(TAG, "interopDatabaseRemoveName: feature=" + feature.name() - + ", adapterService is null or vendor intf is not enabled"); + Log.d( + TAG, + "interopDatabaseRemoveName: feature=" + + feature.name() + + ", adapterService is null or vendor intf is not enabled"); return; } diff --git a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java index f8904bd6d43..2822345ed4c 100644 --- a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +++ b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java @@ -76,10 +76,15 @@ class JniCallbacks { mRemoteDevices.leAddressAssociateCallback(mainAddress, secondaryAddress); } - void aclStateChangeCallback(int status, byte[] address, int newState, - int transportLinkType, int hciReason, int handle) { - mRemoteDevices.aclStateChangeCallback(status, address, newState, - transportLinkType, hciReason, handle); + void aclStateChangeCallback( + int status, + byte[] address, + int newState, + int transportLinkType, + int hciReason, + int handle) { + mRemoteDevices.aclStateChangeCallback( + status, address, newState, transportLinkType, hciReason, handle); } void keyMissingCallback(byte[] address) { @@ -111,8 +116,13 @@ class JniCallbacks { int packets_not_receive_count, int negative_acknowledgement_count) { mAdapterService.linkQualityReportCallback( - timestamp, report_id, rssi, snr, retransmission_count, - packets_not_receive_count, negative_acknowledgement_count); + timestamp, + report_id, + rssi, + snr, + retransmission_count, + packets_not_receive_count, + negative_acknowledgement_count); } void switchBufferSizeCallback(boolean is_low_latency_buffer_size) { diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java index 737abd3a56a..7b490e2bbb2 100644 --- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java @@ -72,8 +72,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { // Message types for the handler (internal messages generated by intents or timeouts) private static final int MESSAGE_CONNECT_OTHER_PROFILES = 3; - @VisibleForTesting static final String AUTO_CONNECT_PROFILES_PROPERTY = - "bluetooth.auto_connect_profiles.enabled"; + @VisibleForTesting + static final String AUTO_CONNECT_PROFILES_PROPERTY = "bluetooth.auto_connect_profiles.enabled"; private static final String LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY = "ro.bluetooth.leaudio.le_audio_connection_by_default"; @@ -144,18 +144,19 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MESSAGE_CONNECT_OTHER_PROFILES: { - // Called when we try connect some profiles in processConnectOtherProfiles but - // we send a delayed message to try connecting the remaining profiles - BluetoothDevice device = (BluetoothDevice) msg.obj; - processConnectOtherProfiles(device); - mConnectOtherProfilesDeviceSet.remove(device); - break; - } + case MESSAGE_CONNECT_OTHER_PROFILES: + { + // Called when we try connect some profiles in processConnectOtherProfiles + // but + // we send a delayed message to try connecting the remaining profiles + BluetoothDevice device = (BluetoothDevice) msg.obj; + processConnectOtherProfiles(device); + mConnectOtherProfilesDeviceSet.remove(device); + break; + } } } } - ; // Policy API functions for lifecycle management (protected) @@ -174,8 +175,10 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { PhonePolicy(AdapterService service, ServiceFactory factory) { mAdapterService = service; - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when PhonePolicy starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when PhonePolicy starts"); mFactory = factory; mHandler = new PhonePolicyHandler(service.getMainLooper()); mAutoConnectProfilesSupported = @@ -293,9 +296,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { HearingAidService hearingAidService = mFactory.getHearingAidService(); LeAudioService leAudioService = mFactory.getLeAudioService(); CsipSetCoordinatorService csipSetCoordinatorService = - mFactory.getCsipSetCoordinatorService(); - VolumeControlService volumeControlService = - mFactory.getVolumeControlService(); + mFactory.getCsipSetCoordinatorService(); + VolumeControlService volumeControlService = mFactory.getVolumeControlService(); HapClientService hapClientService = mFactory.getHapClientService(); BassClientService bcService = mFactory.getBassClientService(); BatteryService batteryService = mFactory.getBatteryService(); @@ -341,8 +343,12 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { if (mAutoConnectProfilesSupported) { hidService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { - mAdapterService.getDatabase().setProfileConnectionPolicy(device, - BluetoothProfile.HID_HOST, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + mAdapterService + .getDatabase() + .setProfileConnectionPolicy( + device, + BluetoothProfile.HID_HOST, + BluetoothProfile.CONNECTION_POLICY_ALLOWED); } MetricsLogger.getInstance() .count( @@ -359,17 +365,24 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { && (headsetService.getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_UNKNOWN))) { if (!isDualModeAudioEnabled() && isLeAudioProfileAllowed) { - debugLog("clear hfp profile priority for the le audio dual mode device " - + device); - mAdapterService.getDatabase().setProfileConnectionPolicy(device, - BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + debugLog("clear hfp profile priority for the le audio dual mode device " + device); + mAdapterService + .getDatabase() + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } else { if (mAutoConnectProfilesSupported) { headsetService.setConnectionPolicy( device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { - mAdapterService.getDatabase().setProfileConnectionPolicy(device, - BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + mAdapterService + .getDatabase() + .setProfileConnectionPolicy( + device, + BluetoothProfile.HEADSET, + BluetoothProfile.CONNECTION_POLICY_ALLOWED); } } } @@ -381,12 +394,16 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) { if (!isDualModeAudioEnabled() && isLeAudioProfileAllowed) { debugLog("clear a2dp profile priority for the le audio dual mode device " + device); - mAdapterService.getDatabase().setProfileConnectionPolicy(device, - BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + mAdapterService + .getDatabase() + .setProfileConnectionPolicy( + device, + BluetoothProfile.A2DP, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } else { if (mAutoConnectProfilesSupported) { - a2dpService.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + a2dpService.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { mAdapterService .getDatabase() @@ -532,9 +549,12 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { hapClientService.setConnectionPolicy( device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { - mAdapterService.getDatabase().setProfileConnectionPolicy(device, - BluetoothProfile.HAP_CLIENT, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + mAdapterService + .getDatabase() + .setProfileConnectionPolicy( + device, + BluetoothProfile.HAP_CLIENT, + BluetoothProfile.CONNECTION_POLICY_ALLOWED); } } else { mAdapterService @@ -582,8 +602,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) { debugLog("setting battery profile priority for device " + device); if (mAutoConnectProfilesSupported) { - batteryService.setConnectionPolicy(device, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + batteryService.setConnectionPolicy( + device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } else { mAdapterService .getDatabase() @@ -655,8 +675,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - private void processProfileStateChanged(BluetoothDevice device, int profileId, int nextState, - int prevState) { + private void processProfileStateChanged( + BluetoothDevice device, int profileId, int nextState, int prevState) { debugLog( "processProfileStateChanged, device=" + device @@ -705,9 +725,13 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { * @param device is the device we just made the active device */ private void processActiveDeviceChanged(BluetoothDevice device, int profileId) { - debugLog("processActiveDeviceChanged, device=" + device + ", profile=" - + BluetoothProfile.getProfileName(profileId) + " isDualModeAudioEnabled=" - + isDualModeAudioEnabled()); + debugLog( + "processActiveDeviceChanged, device=" + + device + + ", profile=" + + BluetoothProfile.getProfileName(profileId) + + " isDualModeAudioEnabled=" + + isDualModeAudioEnabled()); if (device == null) { return; @@ -771,7 +795,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { PanService panService = mFactory.getPanService(); LeAudioService leAudioService = mFactory.getLeAudioService(); CsipSetCoordinatorService csipSetCooridnatorService = - mFactory.getCsipSetCoordinatorService(); + mFactory.getCsipSetCoordinatorService(); if (hsService != null) { List hsConnDevList = hsService.getConnectedDevices(); @@ -805,8 +829,9 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { mHeadsetRetrySet.remove(device); mA2dpRetrySet.remove(device); if (allProfilesEmpty) { - debugLog("handleAllProfilesDisconnected: all profiles disconnected for all" - + " devices"); + debugLog( + "handleAllProfilesDisconnected: all profiles disconnected for all" + + " devices"); // reset retry status so that in the next round we can start retrying connections resetStates(); } @@ -886,8 +911,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { debugLog("autoConnectA2dp: connecting A2DP with " + device); a2dpService.connect(device); } else { - debugLog("autoConnectA2dp: skipped auto-connect A2DP with device " + device - + " connectionPolicy " + a2dpConnectionPolicy); + debugLog( + "autoConnectA2dp: skipped auto-connect A2DP with device " + + device + + " connectionPolicy " + + a2dpConnectionPolicy); } } @@ -903,8 +931,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { debugLog("autoConnectHeadset: Connecting HFP with " + device); hsService.connect(device); } else { - debugLog("autoConnectHeadset: skipped auto-connect HFP with device " + device - + " connectionPolicy " + headsetConnectionPolicy); + debugLog( + "autoConnectHeadset: skipped auto-connect HFP with device " + + device + + " connectionPolicy " + + headsetConnectionPolicy); } } @@ -920,8 +951,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { debugLog("autoConnectHidHost: Connecting HID with " + device); hidHostService.connect(device); } else { - debugLog("autoConnectHidHost: skipped auto-connect HID with device " + device - + " connectionPolicy " + hidHostConnectionPolicy); + debugLog( + "autoConnectHidHost: skipped auto-connect HID with device " + + device + + " connectionPolicy " + + hidHostConnectionPolicy); } } @@ -944,10 +978,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { // profiles which are not already connected or in the process of connecting to attempt to // connect to the device that initiated the connection. In the event that this function is // invoked and there are no current bluetooth connections no new profiles will be connected. - @RequiresPermission(allOf = { - android.Manifest.permission.BLUETOOTH_PRIVILEGED, - android.Manifest.permission.MODIFY_PHONE_STATE, - }) + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + android.Manifest.permission.MODIFY_PHONE_STATE, + }) private void processConnectOtherProfiles(BluetoothDevice device) { debugLog("processConnectOtherProfiles, device=" + device); if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { @@ -972,28 +1007,29 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { PanService panService = mFactory.getPanService(); LeAudioService leAudioService = mFactory.getLeAudioService(); CsipSetCoordinatorService csipSetCooridnatorService = - mFactory.getCsipSetCoordinatorService(); - VolumeControlService volumeControlService = - mFactory.getVolumeControlService(); + mFactory.getCsipSetCoordinatorService(); + VolumeControlService volumeControlService = mFactory.getVolumeControlService(); BatteryService batteryService = mFactory.getBatteryService(); HidHostService hidHostService = mFactory.getHidHostService(); BassClientService bcService = mFactory.getBassClientService(); if (hsService != null) { - if (!mHeadsetRetrySet.contains(device) && (hsService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (!mHeadsetRetrySet.contains(device) + && (hsService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (hsService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to Headset with device " + device); mHeadsetRetrySet.add(device); hsService.connect(device); } } if (a2dpService != null) { - if (!mA2dpRetrySet.contains(device) && (a2dpService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (!mA2dpRetrySet.contains(device) + && (a2dpService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (a2dpService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to A2DP with device " + device); mA2dpRetrySet.add(device); a2dpService.connect(device); @@ -1003,10 +1039,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { List panConnDevList = panService.getConnectedDevices(); // TODO: the panConnDevList.isEmpty() check below should be removed once // Multi-PAN is supported. - if (panConnDevList.isEmpty() && (panService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (panConnDevList.isEmpty() + && (panService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (panService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to PAN with device " + device); panService.connect(device); } @@ -1024,49 +1061,53 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { } if (csipSetCooridnatorService != null) { List csipConnDevList = csipSetCooridnatorService.getConnectedDevices(); - if (!csipConnDevList.contains(device) && (csipSetCooridnatorService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (!csipConnDevList.contains(device) + && (csipSetCooridnatorService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (csipSetCooridnatorService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to CSIP with device " + device); csipSetCooridnatorService.connect(device); } } if (volumeControlService != null) { List vcConnDevList = volumeControlService.getConnectedDevices(); - if (!vcConnDevList.contains(device) && (volumeControlService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (!vcConnDevList.contains(device) + && (volumeControlService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (volumeControlService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to VCP with device " + device); volumeControlService.connect(device); } } if (batteryService != null) { List connectedDevices = batteryService.getConnectedDevices(); - if (!connectedDevices.contains(device) && (batteryService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (!connectedDevices.contains(device) + && (batteryService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (batteryService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to BAS with device " + device); batteryService.connect(device); } } if (hidHostService != null) { if ((hidHostService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (hidHostService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to HID with device " + device); hidHostService.connect(device); } } if (bcService != null) { List connectedDevices = bcService.getConnectedDevices(); - if (!connectedDevices.contains(device) && (bcService.getConnectionPolicy(device) - == BluetoothProfile.CONNECTION_POLICY_ALLOWED) + if (!connectedDevices.contains(device) + && (bcService.getConnectionPolicy(device) + == BluetoothProfile.CONNECTION_POLICY_ALLOWED) && (bcService.getConnectionState(device) - == BluetoothProfile.STATE_DISCONNECTED)) { + == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to BASS with device " + device); bcService.connect(device); } diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java index e2e470401e4..dc1646e4bd2 100644 --- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java +++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java @@ -16,7 +16,6 @@ package com.android.bluetooth.btservice; - import static java.util.Objects.requireNonNull; import android.annotation.RequiresPermission; @@ -33,8 +32,7 @@ import com.android.bluetooth.BluetoothMetricsProto; /** Base class for a background service that runs a Bluetooth profile */ public abstract class ProfileService extends ContextWrapper { - public static final String BLUETOOTH_PERM = - android.Manifest.permission.BLUETOOTH; + public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; public static final String BLUETOOTH_PRIVILEGED = android.Manifest.permission.BLUETOOTH_PRIVILEGED; @@ -99,10 +97,10 @@ public abstract class ProfileService extends ContextWrapper { } /** - * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) - * using a string class name assumed to be in the Bluetooth package. + * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) using + * a string class name assumed to be in the Bluetooth package. * - * It's expected that profiles can have a set of components that they may use to provide + *

It's expected that profiles can have a set of components that they may use to provide * features or interact with other services/the user. Profiles are expected to enable those * components when they start, and disable them when they stop. * @@ -111,8 +109,7 @@ public abstract class ProfileService extends ContextWrapper { */ @RequiresPermission(android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE) protected void setComponentAvailable(String className, boolean enable) { - Log.d(mName, "setComponentAvailable(className=" + className + ", enable=" + enable - + ")"); + Log.d(mName, "setComponentAvailable(className=" + className + ", enable=" + enable + ")"); if (className == null) { return; } @@ -123,7 +120,7 @@ public abstract class ProfileService extends ContextWrapper { /** * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) * - * It's expected that profiles can have a set of components that they may use to provide + *

It's expected that profiles can have a set of components that they may use to provide * features or interact with other services/the user. Profiles are expected to enable those * components when they start, and disable them when they stop. * @@ -132,16 +129,17 @@ public abstract class ProfileService extends ContextWrapper { */ @RequiresPermission(android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE) protected void setComponentAvailable(ComponentName component, boolean enable) { - Log.d(mName, "setComponentAvailable(component=" + component + ", enable=" + enable - + ")"); + Log.d(mName, "setComponentAvailable(component=" + component + ", enable=" + enable + ")"); if (component == null) { return; } - getPackageManager().setComponentEnabledSetting( - component, - enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED - : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS); + getPackageManager() + .setComponentEnabledSetting( + component, + enable + ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS); } /** diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index 661b7404d41..8f7e769538e 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -82,17 +82,13 @@ public class RemoteDevices { private final ArrayDeque mDeviceQueue; /** - * Bluetooth HFP v1.8 specifies the Battery Charge indicator of AG can take values from - * {@code 0} to {@code 5}, but it does not specify how to map the values back to percentages. - * The following mapping is used: - * - Level 0: 0% - * - Level 1: midpoint of 1-25% - * - Level 2: midpoint of 26-50% - * - Level 3: midpoint of 51-75% - * - Level 4: midpoint of 76-99% - * - Level 5: 100% + * Bluetooth HFP v1.8 specifies the Battery Charge indicator of AG can take values from {@code + * 0} to {@code 5}, but it does not specify how to map the values back to percentages. The + * following mapping is used: - Level 0: 0% - Level 1: midpoint of 1-25% - Level 2: midpoint of + * 26-50% - Level 3: midpoint of 51-75% - Level 4: midpoint of 76-99% - Level 5: 100% */ private static final int HFP_BATTERY_CHARGE_INDICATOR_0 = 0; + private static final int HFP_BATTERY_CHARGE_INDICATOR_1 = 13; private static final int HFP_BATTERY_CHARGE_INDICATOR_2 = 38; private static final int HFP_BATTERY_CHARGE_INDICATOR_3 = 63; @@ -106,6 +102,7 @@ public class RemoteDevices { /** * Handler must be created from an explicit looper to avoid threading ambiguity + * * @param looper The looper that this handler should be executed on */ RemoteDevicesHandler(Looper looper) { @@ -119,14 +116,14 @@ public class RemoteDevices { BluetoothDevice device = (BluetoothDevice) msg.obj; if (device != null) { // SDP Sending delayed SDP UUID intent - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_SENDING_DELAYED_UUID, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.SDP_SENDING_DELAYED_UUID, 1); DeviceProperties prop = getDeviceProperties(device); sendUuidIntent(device, prop); } else { // SDP Not sending delayed SDP UUID intent b/c device is not there - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_NOT_SENDING_DELAYED_UUID, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.SDP_NOT_SENDING_DELAYED_UUID, 1); } break; } @@ -134,22 +131,23 @@ public class RemoteDevices { } /** - * Predicate that tests if the given {@link BluetoothDevice} is well-known - * to be used for physical location. + * Predicate that tests if the given {@link BluetoothDevice} is well-known to be used for + * physical location. */ - private final Predicate mLocationDenylistPredicate = (device) -> { - final MacAddress parsedAddress = MacAddress.fromString(device.getAddress()); - if (mAdapterService.getLocationDenylistMac().test(parsedAddress.toByteArray())) { - Log.v(TAG, "Skipping device matching denylist: " + device); - return true; - } - final String name = Utils.getName(device); - if (mAdapterService.getLocationDenylistName().test(name)) { - Log.v(TAG, "Skipping name matching denylist: " + name); - return true; - } - return false; - }; + private final Predicate mLocationDenylistPredicate = + (device) -> { + final MacAddress parsedAddress = MacAddress.fromString(device.getAddress()); + if (mAdapterService.getLocationDenylistMac().test(parsedAddress.toByteArray())) { + Log.v(TAG, "Skipping device matching denylist: " + device); + return true; + } + final String name = Utils.getName(device); + if (mAdapterService.getLocationDenylistName().test(name)) { + Log.v(TAG, "Skipping name matching denylist: " + name); + return true; + } + return false; + }; RemoteDevices(AdapterService service, Looper looper) { mAdapter = ((Context) service).getSystemService(BluetoothManager.class).getAdapter(); @@ -163,8 +161,8 @@ public class RemoteDevices { } /** - * Reset should be called when the state of this object needs to be cleared - * RemoteDevices is still usable after reset + * Reset should be called when the state of this object needs to be cleared RemoteDevices is + * still usable after reset */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) void reset() { @@ -605,7 +603,7 @@ public class RemoteDevices { /** * @return the mIsCoordinatedSetMember - */ + */ boolean isCoordinatedSetMember() { synchronized (mObject) { return mIsCoordinatedSetMember; @@ -614,7 +612,7 @@ public class RemoteDevices { /** * @param isCoordinatedSetMember the mIsCoordinatedSetMember to set - */ + */ void setIsCoordinatedSetMember(boolean isCoordinatedSetMember) { if ((mAdapterService.getSupportedProfilesBitMask() & (1 << BluetoothProfile.CSIP_SET_COORDINATOR)) @@ -669,9 +667,9 @@ public class RemoteDevices { mModelName = modelName; try { mAdapterService.setMetadata( - this.mDevice, - BluetoothDevice.METADATA_MODEL_NAME, - mModelName.getBytes("UTF-8")); + this.mDevice, + BluetoothDevice.METADATA_MODEL_NAME, + mModelName.getBytes("UTF-8")); } catch (UnsupportedEncodingException uee) { Log.e(TAG, "setModelName: UTF-8 not supported?!?"); // this should not happen } @@ -699,9 +697,8 @@ public class RemoteDevices { intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); // SDP Sent UUID Intent here - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_SENT_UUID, 1); - //Remove the outstanding UUID request + MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_SENT_UUID, 1); + // Remove the outstanding UUID request mSdpTracker.remove(device); } @@ -921,7 +918,8 @@ public class RemoteDevices { deviceProperties.setBluetoothClass(newBluetoothClass); intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, bdDevice); - intent.putExtra(BluetoothDevice.EXTRA_CLASS, + intent.putExtra( + BluetoothDevice.EXTRA_CLASS, new BluetoothClass(deviceProperties.getBluetoothClass())); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mAdapterService.sendBroadcast( @@ -939,27 +937,29 @@ public class RemoteDevices { if (areUuidsEqual(newUuids, deviceProperties.getUuids())) { // SDP Skip adding UUIDs to property cache if equal debugLog("Skip uuids update for " + bdDevice.getAddress()); - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_UUIDS_EQUAL_SKIP, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.SDP_UUIDS_EQUAL_SKIP, 1); break; } deviceProperties.setUuids(newUuids); if (mAdapterService.getState() == BluetoothAdapter.STATE_ON) { // SDP Adding UUIDs to property cache and sending intent - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_ADD_UUID_WITH_INTENT, 1); + MetricsLogger.getInstance() + .cacheCount( + BluetoothProtoEnums.SDP_ADD_UUID_WITH_INTENT, 1); mAdapterService.deviceUuidUpdated(bdDevice); sendUuidIntent(bdDevice, deviceProperties); } else if (mAdapterService.getState() == BluetoothAdapter.STATE_BLE_ON) { // SDP Adding UUIDs to property cache but with no intent - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_ADD_UUID_WITH_NO_INTENT, 1); + MetricsLogger.getInstance() + .cacheCount( + BluetoothProtoEnums.SDP_ADD_UUID_WITH_NO_INTENT, 1); mAdapterService.deviceUuidUpdated(bdDevice); } else { // SDP Silently dropping UUIDs and with no intent - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_DROP_UUID, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.SDP_DROP_UUID, 1); } break; case AbstractionLayer.BT_PROPERTY_TYPE_OF_DEVICE: @@ -990,9 +990,17 @@ public class RemoteDevices { BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_DEVICE_INFO_REPORTED, mAdapterService.obfuscateAddress(bdDevice), - BluetoothProtoEnums.DEVICE_INFO_INTERNAL, LOG_SOURCE_DIS, null, - modelName, null, null, mAdapterService.getMetricId(bdDevice), - bdDevice.getAddressType(), 0, 0, 0); + BluetoothProtoEnums.DEVICE_INFO_INTERNAL, + LOG_SOURCE_DIS, + null, + modelName, + null, + null, + mAdapterService.getMetricId(bdDevice), + bdDevice.getAddressType(), + 0, + 0, + 0); break; } } @@ -1019,11 +1027,12 @@ public class RemoteDevices { Intent intent = new Intent(BluetoothDevice.ACTION_FOUND); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.putExtra(BluetoothDevice.EXTRA_CLASS, - new BluetoothClass(deviceProp.getBluetoothClass())); + intent.putExtra( + BluetoothDevice.EXTRA_CLASS, new BluetoothClass(deviceProp.getBluetoothClass())); intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.getRssi()); intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProp.getName()); - intent.putExtra(BluetoothDevice.EXTRA_IS_COORDINATED_SET_MEMBER, + intent.putExtra( + BluetoothDevice.EXTRA_IS_COORDINATED_SET_MEMBER, deviceProp.isCoordinatedSetMember()); final List packages = mAdapterService.getDiscoveringPackages(); @@ -1038,13 +1047,13 @@ public class RemoteDevices { intent.setPackage(pkg.getPackageName()); if (pkg.getPermission() != null) { - mAdapterService.sendBroadcastMultiplePermissions(intent, - new String[] { BLUETOOTH_SCAN, pkg.getPermission() }, + mAdapterService.sendBroadcastMultiplePermissions( + intent, + new String[] {BLUETOOTH_SCAN, pkg.getPermission()}, Utils.getTempBroadcastOptions()); } else { - mAdapterService.sendBroadcastMultiplePermissions(intent, - new String[] { BLUETOOTH_SCAN }, - Utils.getTempBroadcastOptions()); + mAdapterService.sendBroadcastMultiplePermissions( + intent, new String[] {BLUETOOTH_SCAN}, Utils.getTempBroadcastOptions()); } } } @@ -1053,20 +1062,26 @@ public class RemoteDevices { void addressConsolidateCallback(byte[] mainAddress, byte[] secondaryAddress) { BluetoothDevice device = getDevice(mainAddress); if (device == null) { - errorLog("addressConsolidateCallback: device is NULL, address=" - + Utils.getRedactedAddressStringFromByte(mainAddress) - + ", secondaryAddress=" - + Utils.getRedactedAddressStringFromByte(secondaryAddress)); + errorLog( + "addressConsolidateCallback: device is NULL, address=" + + Utils.getRedactedAddressStringFromByte(mainAddress) + + ", secondaryAddress=" + + Utils.getRedactedAddressStringFromByte(secondaryAddress)); return; } - Log.d(TAG, "addressConsolidateCallback device: " + device + ", secondaryAddress:" - + Utils.getRedactedAddressStringFromByte(secondaryAddress)); + Log.d( + TAG, + "addressConsolidateCallback device: " + + device + + ", secondaryAddress:" + + Utils.getRedactedAddressStringFromByte(secondaryAddress)); DeviceProperties deviceProperties = getDeviceProperties(device); deviceProperties.setIsConsolidated(true); deviceProperties.setDeviceType(BluetoothDevice.DEVICE_TYPE_DUAL); deviceProperties.setIdentityAddress(Utils.getAddressStringFromByte(secondaryAddress)); - mDualDevicesMap.put(deviceProperties.getIdentityAddress(), Utils.getAddressStringFromByte(mainAddress)); + mDualDevicesMap.put( + deviceProperties.getIdentityAddress(), Utils.getAddressStringFromByte(mainAddress)); } /** @@ -1078,25 +1093,36 @@ public class RemoteDevices { void leAddressAssociateCallback(byte[] mainAddress, byte[] secondaryAddress) { BluetoothDevice device = getDevice(mainAddress); if (device == null) { - errorLog("leAddressAssociateCallback: device is NULL, address=" - + Utils.getRedactedAddressStringFromByte(mainAddress) - + ", secondaryAddress=" - + Utils.getRedactedAddressStringFromByte(secondaryAddress)); + errorLog( + "leAddressAssociateCallback: device is NULL, address=" + + Utils.getRedactedAddressStringFromByte(mainAddress) + + ", secondaryAddress=" + + Utils.getRedactedAddressStringFromByte(secondaryAddress)); return; } - Log.d(TAG, "leAddressAssociateCallback device: " + device + ", secondaryAddress:" - + Utils.getRedactedAddressStringFromByte(secondaryAddress)); + Log.d( + TAG, + "leAddressAssociateCallback device: " + + device + + ", secondaryAddress:" + + Utils.getRedactedAddressStringFromByte(secondaryAddress)); DeviceProperties deviceProperties = getDeviceProperties(device); deviceProperties.mIdentityAddress = Utils.getAddressStringFromByte(secondaryAddress); } - @RequiresPermission(allOf = { - android.Manifest.permission.BLUETOOTH_CONNECT, - android.Manifest.permission.BLUETOOTH_PRIVILEGED, - }) - void aclStateChangeCallback(int status, byte[] address, int newState, - int transportLinkType, int hciReason, int handle) { + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + void aclStateChangeCallback( + int status, + byte[] address, + int newState, + int transportLinkType, + int hciReason, + int handle) { if (status != AbstractionLayer.BT_STATUS_SUCCESS) { debugLog("aclStateChangeCallback status is " + status + ", skipping"); return; @@ -1105,9 +1131,11 @@ public class RemoteDevices { BluetoothDevice device = getDevice(address); if (device == null) { - warnLog("aclStateChangeCallback: device is NULL, address=" - + Utils.getRedactedAddressStringFromByte(address) - + ", newState=" + newState); + warnLog( + "aclStateChangeCallback: device is NULL, address=" + + Utils.getRedactedAddressStringFromByte(address) + + ", newState=" + + newState); addDeviceProperties(address); device = Objects.requireNonNull(getDevice(address)); } @@ -1131,20 +1159,26 @@ public class RemoteDevices { batteryService.connectIfPossible(device); } mAdapterService.updatePhonePolicyOnAclConnect(device); - SecurityLog.writeEvent(SecurityLog.TAG_BLUETOOTH_CONNECTION, - Utils.getLoggableAddress(device), /* success */ 1, /* reason */ ""); + SecurityLog.writeEvent( + SecurityLog.TAG_BLUETOOTH_CONNECTION, + Utils.getLoggableAddress(device), /* success */ + 1, /* reason */ + ""); debugLog( - "aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state) - + " Connected: " + device); + "aclStateChangeCallback: Adapter State: " + + BluetoothAdapter.nameForState(state) + + " Connected: " + + device); } else { deviceProperties.setConnectionHandle(BluetoothDevice.ERROR, transportLinkType); if (device.getBondState() == BluetoothDevice.BOND_BONDING) { // Send PAIRING_CANCEL intent to dismiss any dialog requesting bonding. intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.setPackage(SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - mAdapterService.getString(R.string.pairing_ui_package))); + intent.setPackage( + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, + mAdapterService.getString(R.string.pairing_ui_package))); mAdapterService.sendBroadcast( intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); @@ -1168,7 +1202,7 @@ public class RemoteDevices { && transportLinkType == BluetoothDevice.TRANSPORT_LE) { batteryService.disconnect(device); } - resetBatteryLevel(device, /*isBas=*/ true); + resetBatteryLevel(device, /* isBas= */ true); } if (mAdapterService.isAllProfilesUnknown(device)) { @@ -1177,19 +1211,26 @@ public class RemoteDevices { deviceProp.setBondingInitiatedLocally(false); } } - SecurityLog.writeEvent(SecurityLog.TAG_BLUETOOTH_DISCONNECTION, + SecurityLog.writeEvent( + SecurityLog.TAG_BLUETOOTH_DISCONNECTION, Utils.getLoggableAddress(device), BluetoothAdapter.BluetoothConnectionCallback.disconnectReasonToString( AdapterService.hciToAndroidDisconnectReason(hciReason))); debugLog( - "aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state) - + " Disconnected: " + device - + " transportLinkType: " + transportLinkType - + " hciReason: " + hciReason); + "aclStateChangeCallback: Adapter State: " + + BluetoothAdapter.nameForState(state) + + " Disconnected: " + + device + + " transportLinkType: " + + transportLinkType + + " hciReason: " + + hciReason); } - int connectionState = newState == AbstractionLayer.BT_ACL_STATE_CONNECTED - ? BluetoothAdapter.STATE_CONNECTED : BluetoothAdapter.STATE_DISCONNECTED; + int connectionState = + newState == AbstractionLayer.BT_ACL_STATE_CONNECTED + ? BluetoothAdapter.STATE_CONNECTED + : BluetoothAdapter.STATE_DISCONNECTED; int metricId = mAdapterService.getMetricId(device); BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_ACL_CONNECTION_STATE_CHANGED, @@ -1200,13 +1241,16 @@ public class RemoteDevices { BluetoothClass deviceClass = device.getBluetoothClass(); int classOfDevice = deviceClass == null ? 0 : deviceClass.getClassOfDevice(); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED, - mAdapterService.obfuscateAddress(device), classOfDevice, metricId); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED, + mAdapterService.obfuscateAddress(device), + classOfDevice, + metricId); if (intent != null) { intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device) - .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) - .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) + .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mAdapterService.sendBroadcast( intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); @@ -1218,8 +1262,8 @@ public class RemoteDevices { if (connectionState == BluetoothAdapter.STATE_CONNECTED) { callback.onDeviceConnected(device); } else { - callback.onDeviceDisconnected(device, - AdapterService.hciToAndroidDisconnectReason(hciReason)); + callback.onDeviceDisconnected( + device, AdapterService.hciToAndroidDisconnectReason(hciReason)); } } catch (RemoteException ex) { Log.e(TAG, "RemoteException in calling IBluetoothConnectionCallback"); @@ -1227,8 +1271,10 @@ public class RemoteDevices { } } } else { - Log.e(TAG, "aclStateChangeCallback intent is null. deviceBondState: " - + device.getBondState()); + Log.e( + TAG, + "aclStateChangeCallback intent is null. deviceBondState: " + + device.getBondState()); } } @@ -1300,18 +1346,19 @@ public class RemoteDevices { + device + " transport:" + transport); - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_CACHED, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_CACHED, 1); return; } // If no UUIDs are cached and the device is bonding, wait for SDP after the device is bonded DeviceProperties deviceProperties = getDeviceProperties(device); - if (deviceProperties != null && deviceProperties.isBonding() + if (deviceProperties != null + && deviceProperties.isBonding() && getDeviceProperties(device).getUuids() == null) { debugLog("Skip fetch UUIDs due to bonding peer:" + device + " transport:" + transport); - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_BONDED, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_BONDED, 1); return; } @@ -1331,8 +1378,7 @@ public class RemoteDevices { mAdapterService .getNative() .getRemoteServices(Utils.getBytesFromAddress(device.getAddress()), transport); - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.SDP_INVOKE_SDP_CYCLE, 1); + MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_INVOKE_SDP_CYCLE, 1); } } @@ -1355,7 +1401,7 @@ public class RemoteDevices { return; } if (toState == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) { - resetBatteryLevel(device, /*isBas=*/ false); + resetBatteryLevel(device, /* isBas= */ false); } } @@ -1372,7 +1418,7 @@ public class RemoteDevices { return; } if (indicatorId == HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS) { - updateBatteryLevel(device, indicatorValue, /*isBas=*/ false); + updateBatteryLevel(device, indicatorValue, /* isBas= */ false); } } @@ -1421,19 +1467,23 @@ public class RemoteDevices { break; } if (batteryPercent != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { - updateBatteryLevel(device, batteryPercent, /*isBas=*/ false); - infoLog("Updated device " + device + " battery level to " + String.valueOf( - batteryPercent) + "%"); + updateBatteryLevel(device, batteryPercent, /* isBas= */ false); + infoLog( + "Updated device " + + device + + " battery level to " + + String.valueOf(batteryPercent) + + "%"); } } /** - * Parse - * AT+IPHONEACCEV=[NumberOfIndicators],[IndicatorType],[IndicatorValue] - * vendor specific event + * Parse AT+IPHONEACCEV=[NumberOfIndicators],[IndicatorType],[IndicatorValue] vendor specific + * event + * * @param args Array of arguments on the right side of assignment * @return Battery level in percents, [0-100], {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN} - * when there is an error parsing the arguments + * when there is an error parsing the arguments */ @VisibleForTesting static int getBatteryLevelFromAppleBatteryVsc(Object[] args) { @@ -1475,17 +1525,18 @@ public class RemoteDevices { } break; } - return (indicatorValue < 0 || indicatorValue > 9) ? BluetoothDevice.BATTERY_LEVEL_UNKNOWN + return (indicatorValue < 0 || indicatorValue > 9) + ? BluetoothDevice.BATTERY_LEVEL_UNKNOWN : (indicatorValue + 1) * 10; } /** - * Parse - * AT+XEVENT=BATTERY,[Level],[NumberOfLevel],[MinutesOfTalk],[IsCharging] - * vendor specific event + * Parse AT+XEVENT=BATTERY,[Level],[NumberOfLevel],[MinutesOfTalk],[IsCharging] vendor specific + * event + * * @param args Array of arguments on the right side of SET command * @return Battery level in percents, [0-100], {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN} - * when there is an error parsing the arguments + * when there is an error parsing the arguments */ @VisibleForTesting static int getBatteryLevelFromXEventVsc(Object[] args) { @@ -1505,8 +1556,10 @@ public class RemoteDevices { return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; } if (args.length != 5) { - Log.w(TAG, "getBatteryLevelFromXEventVsc() wrong battery level event length: " - + String.valueOf(args.length)); + Log.w( + TAG, + "getBatteryLevelFromXEventVsc() wrong battery level event length: " + + String.valueOf(args.length)); return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; } if (!(args[1] instanceof Integer) || !(args[2] instanceof Integer)) { @@ -1516,9 +1569,12 @@ public class RemoteDevices { int batteryLevel = (Integer) args[1]; int numberOfLevels = (Integer) args[2]; if (batteryLevel < 0 || numberOfLevels <= 1 || batteryLevel > numberOfLevels) { - Log.w(TAG, "getBatteryLevelFromXEventVsc() wrong event value, batteryLevel=" - + String.valueOf(batteryLevel) + ", numberOfLevels=" + String.valueOf( - numberOfLevels)); + Log.w( + TAG, + "getBatteryLevelFromXEventVsc() wrong event value, batteryLevel=" + + String.valueOf(batteryLevel) + + ", numberOfLevels=" + + String.valueOf(numberOfLevels)); return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; } return batteryLevel * 100 / (numberOfLevels - 1); @@ -1544,7 +1600,7 @@ public class RemoteDevices { return; } if (toState == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) { - resetBatteryLevel(device, /*isBas=*/ false); + resetBatteryLevel(device, /* isBas= */ false); } } @@ -1560,7 +1616,7 @@ public class RemoteDevices { return; } updateBatteryLevel( - device, batteryChargeIndicatorToPercentge(batteryLevel), /*isBas=*/ false); + device, batteryChargeIndicatorToPercentge(batteryLevel), /* isBas= */ false); } private static void errorLog(String msg) { @@ -1578,5 +1634,4 @@ public class RemoteDevices { private static void warnLog(String msg) { Log.w(TAG, msg); } - } diff --git a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java index 048dd3afc88..3be3d98e91a 100644 --- a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java @@ -43,16 +43,13 @@ import java.util.Map; /** * The silence device manager controls silence mode for A2DP, HFP, and AVRCP. * - * 1) If an active device (for A2DP or HFP) enters silence mode, the active device - * for that profile will be set to null. - * 2) If a device exits silence mode while the A2DP or HFP active device is null, - * the device will be set as the active device for that profile. - * 3) If a device is disconnected, it exits silence mode. - * 4) If a device is set as the active device for A2DP or HFP, while silence mode - * is enabled, then the device will exit silence mode. - * 5) If a device is in silence mode, AVRCP position change event and HFP AG indicators - * will be disabled. - * 6) If a device is not connected with A2DP or HFP, it cannot enter silence mode. + *

1) If an active device (for A2DP or HFP) enters silence mode, the active device for that + * profile will be set to null. 2) If a device exits silence mode while the A2DP or HFP active + * device is null, the device will be set as the active device for that profile. 3) If a device is + * disconnected, it exits silence mode. 4) If a device is set as the active device for A2DP or HFP, + * while silence mode is enabled, then the device will exit silence mode. 5) If a device is in + * silence mode, AVRCP position change event and HFP AG indicators will be disabled. 6) If a device + * is not connected with A2DP or HFP, it cannot enter silence mode. */ public class SilenceDeviceManager { private static final String TAG = SilenceDeviceManager.class.getSimpleName(); @@ -126,12 +123,13 @@ public class SilenceDeviceManager { public void handleMessage(Message msg) { Log.d(TAG, "handleMessage: " + msg.what); switch (msg.what) { - case MSG_SILENCE_DEVICE_STATE_CHANGED: { - BluetoothDevice device = (BluetoothDevice) msg.obj; - boolean state = (msg.arg1 == ENABLE_SILENCE); - handleSilenceDeviceStateChanged(device, state); - } - break; + case MSG_SILENCE_DEVICE_STATE_CHANGED: + { + BluetoothDevice device = (BluetoothDevice) msg.obj; + boolean state = (msg.arg1 == ENABLE_SILENCE); + handleSilenceDeviceStateChanged(device, state); + } + break; case MSG_A2DP_CONNECTION_STATE_CHANGED: BluetoothDevice device = (BluetoothDevice) msg.obj; @@ -221,8 +219,12 @@ public class SilenceDeviceManager { return false; } Log.d(TAG, "setSilenceMode: " + device + ", " + silence); - Message message = mHandler.obtainMessage(MSG_SILENCE_DEVICE_STATE_CHANGED, - silence ? ENABLE_SILENCE : DISABLE_SILENCE, 0, device); + Message message = + mHandler.obtainMessage( + MSG_SILENCE_DEVICE_STATE_CHANGED, + silence ? ENABLE_SILENCE : DISABLE_SILENCE, + 0, + device); mHandler.sendMessage(message); return true; } @@ -252,8 +254,7 @@ public class SilenceDeviceManager { if (headsetService != null) { headsetService.setSilenceMode(device, state); } - Log.i(TAG, "Silence mode change " + device + ": " + oldState + " -> " - + state); + Log.i(TAG, "Silence mode change " + device + ": " + oldState + " -> " + state); broadcastSilenceStateChange(device, state); } @@ -277,8 +278,12 @@ public class SilenceDeviceManager { } void addConnectedDevice(BluetoothDevice device, int profile) { - Log.d(TAG, "addConnectedDevice: " + device + ", profile:" - + BluetoothProfile.getProfileName(profile)); + Log.d( + TAG, + "addConnectedDevice: " + + device + + ", profile:" + + BluetoothProfile.getProfileName(profile)); switch (profile) { case BluetoothProfile.A2DP: if (!mA2dpConnectedDevices.contains(device)) { @@ -294,8 +299,12 @@ public class SilenceDeviceManager { } void removeConnectedDevice(BluetoothDevice device, int profile) { - Log.d(TAG, "removeConnectedDevice: " + device + ", profile:" - + BluetoothProfile.getProfileName(profile)); + Log.d( + TAG, + "removeConnectedDevice: " + + device + + ", profile:" + + BluetoothProfile.getProfileName(profile)); switch (profile) { case BluetoothProfile.A2DP: if (mA2dpConnectedDevices.contains(device)) { @@ -318,7 +327,7 @@ public class SilenceDeviceManager { writer.println("\nSilenceDeviceManager:"); writer.println(" Address | Is silenced?"); for (BluetoothDevice device : mSilenceDevices.keySet()) { - writer.println(" " + device+ " | " + getSilenceMode(device)); + writer.println(" " + device + " | " + getSilenceMode(device)); } } } diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java index d87fca88298..073aa343025 100644 --- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java +++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java @@ -65,9 +65,7 @@ public class BluetoothKeystoreNativeInterface { initNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ public void cleanup() { cleanupNative(); mBluetoothKeystoreService = null; @@ -112,5 +110,6 @@ public class BluetoothKeystoreNativeInterface { // Native methods that call into the JNI interface private native void initNative(); + private native void cleanupNative(); } diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java index d9b30db70b6..0c61375c911 100644 --- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java +++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java @@ -57,9 +57,7 @@ import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; -/** - * Service used for handling encryption and decryption of the bt_config.conf - */ +/** Service used for handling encryption and decryption of the bt_config.conf */ public class BluetoothKeystoreService { private static final String TAG = BluetoothKeystoreService.class.getSimpleName(); @@ -103,8 +101,15 @@ public class BluetoothKeystoreService { private Map mNameDecryptKey = new HashMap<>(); private BlockingQueue mPendingDecryptKey = new LinkedBlockingQueue<>(); private BlockingQueue mPendingEncryptKey = new LinkedBlockingQueue<>(); - private final List mEncryptKeyNameList = List.of("LinkKey", "LE_KEY_PENC", "LE_KEY_PID", - "LE_KEY_LID", "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"); + private final List mEncryptKeyNameList = + List.of( + "LinkKey", + "LE_KEY_PENC", + "LE_KEY_PID", + "LE_KEY_LID", + "LE_KEY_PCSRK", + "LE_KEY_LENC", + "LE_KEY_LCSRK"); private Base64.Decoder mDecoder = Base64.getDecoder(); private Base64.Encoder mEncoder = Base64.getEncoder(); @@ -118,9 +123,7 @@ public class BluetoothKeystoreService { startThread(); } - /** - * Start and initialize the BluetoothKeystoreService - */ + /** Start and initialize the BluetoothKeystoreService */ public void start() { debugLog("start"); KeyStore keyStore; @@ -152,9 +155,7 @@ public class BluetoothKeystoreService { loadConfigData(); } - /** - * Factory reset the keystore service. - */ + /** Factory reset the keystore service. */ public void factoryReset() { try { cleanupAll(); @@ -163,9 +164,7 @@ public class BluetoothKeystoreService { } } - /** - * Cleans up the keystore service. - */ + /** Cleans up the keystore service. */ public void cleanup() { debugLog("cleanup"); @@ -184,9 +183,7 @@ public class BluetoothKeystoreService { } } - /** - * Clean up if Common Criteria mode is enabled. - */ + /** Clean up if Common Criteria mode is enabled. */ @VisibleForTesting public void cleanupForCommonCriteriaModeEnable() { try { @@ -202,18 +199,14 @@ public class BluetoothKeystoreService { stopThread(); } - /** - * Clean up if Common Criteria mode is disabled. - */ + /** Clean up if Common Criteria mode is disabled. */ @VisibleForTesting public void cleanupForCommonCriteriaModeDisable() { mNameDecryptKey.clear(); mNameEncryptKey.clear(); } - /** - * Load decryption data from file. - */ + /** Load decryption data from file. */ @VisibleForTesting public void loadConfigData() { try { @@ -270,9 +263,7 @@ public class BluetoothKeystoreService { return SystemProperties.getBoolean("persist.bluetooth.factoryreset", false); } - /** - * Init JNI - */ + /** Init JNI */ public void initJni() { debugLog("initJni()"); // Need to make sure all keys are decrypted. @@ -282,9 +273,7 @@ public class BluetoothKeystoreService { mBluetoothKeystoreNativeInterface.init(this); } - /** - * Gets result of the checksum comparison - */ + /** Gets result of the checksum comparison */ public int getCompareResult() { debugLog("getCompareResult: " + mCompareResult); return mCompareResult; @@ -293,9 +282,9 @@ public class BluetoothKeystoreService { /** * Sets or removes the encryption key value. * - *

If the value of decryptedString matches {@link #CONFIG_FILE_HASH} then - * read the hash file and decrypt the keys and place them into {@link mPendingEncryptKey} - * otherwise cleanup all data and remove the keys. + *

If the value of decryptedString matches {@link #CONFIG_FILE_HASH} then read the hash file + * and decrypt the keys and place them into {@link mPendingEncryptKey} otherwise cleanup all + * data and remove the keys. * * @param prefixString key to use * @param decryptedString string to decrypt @@ -329,9 +318,7 @@ public class BluetoothKeystoreService { } } - /** - * Clean up memory and all files. - */ + /** Clean up memory and all files. */ @VisibleForTesting public void cleanupAll() throws IOException { cleanupFile(); @@ -344,9 +331,7 @@ public class BluetoothKeystoreService { Files.deleteIfExists(Paths.get(CONFIG_BACKUP_ENCRYPTION_PATH)); } - /** - * Clean up memory. - */ + /** Clean up memory. */ @VisibleForTesting public void cleanupMemory() { stopThread(); @@ -355,9 +340,7 @@ public class BluetoothKeystoreService { startThread(); } - /** - * Stop encrypt/decrypt thread. - */ + /** Stop encrypt/decrypt thread. */ @VisibleForTesting public void stopThread() { try { @@ -381,9 +364,7 @@ public class BluetoothKeystoreService { mDecryptDataThread.start(); } - /** - * Get key value from the mNameDecryptKey. - */ + /** Get key value from the mNameDecryptKey. */ public String getKey(String prefixString) { infoLog("getKey: prefix: " + prefixString); if (!mNameDecryptKey.containsKey(prefixString)) { @@ -393,9 +374,7 @@ public class BluetoothKeystoreService { return mNameDecryptKey.get(prefixString); } - /** - * Save encryption key into the encryption file. - */ + /** Save encryption key into the encryption file. */ @VisibleForTesting public void saveEncryptedKey() { stopThread(); @@ -450,9 +429,7 @@ public class BluetoothKeystoreService { return (mCompareResult & item) == item; } - /** - * Compare config file checksum. - */ + /** Compare config file checksum. */ @VisibleForTesting public boolean compareFileHash(String hashFilePathString) throws InterruptedException, IOException, NoSuchAlgorithmException { @@ -475,8 +452,9 @@ public class BluetoothKeystoreService { readHashFile(hashFilePathString, prefixString); if (!mNameEncryptKey.containsKey(prefixString)) { - errorLog("compareFileHash: NameEncryptKey doesn't contain the key, prefix:" - + prefixString); + errorLog( + "compareFileHash: NameEncryptKey doesn't contain the key, prefix:" + + prefixString); return false; } String encryptedData = mNameEncryptKey.get(prefixString); @@ -492,7 +470,7 @@ public class BluetoothKeystoreService { private void readHashFile(String filePathString, String prefixString) throws InterruptedException, NoSuchAlgorithmException { byte[] dataBuffer = new byte[BUFFER_SIZE]; - int bytesRead = 0; + int bytesRead = 0; boolean successful = false; int counter = 0; while (!successful && counter < TRY_MAX) { @@ -506,8 +484,9 @@ public class BluetoothKeystoreService { byte[] messageDigestBytes = messageDigest.digest(); StringBuilder hashString = new StringBuilder(); for (int index = 0; index < messageDigestBytes.length; index++) { - hashString.append(Integer.toString(( - messageDigestBytes[index] & 0xff) + 0x100, 16).substring(1)); + hashString.append( + Integer.toString((messageDigestBytes[index] & 0xff) + 0x100, 16) + .substring(1)); } mNameDecryptKey.put(prefixString, hashString.toString()); @@ -523,12 +502,9 @@ public class BluetoothKeystoreService { } } - /** - * Parses a file to search for the key and put it into the pending compute queue - */ + /** Parses a file to search for the key and put it into the pending compute queue */ @VisibleForTesting - public void parseConfigFile(String filePathString) - throws IOException, InterruptedException { + public void parseConfigFile(String filePathString) throws IOException, InterruptedException { String prefixString = null; String dataString = null; String name = null; @@ -570,9 +546,7 @@ public class BluetoothKeystoreService { } } - /** - * Load encryption file and push into mNameEncryptKey and pendingDecryptKey. - */ + /** Load encryption file and push into mNameEncryptKey and pendingDecryptKey. */ @VisibleForTesting public void loadEncryptionFile(String filePathString, boolean doDecrypt) throws InterruptedException { @@ -640,9 +614,12 @@ public class BluetoothKeystoreService { if (secretKeyReference != null) { cipher.init(Cipher.ENCRYPT_MODE, secretKeyReference); - protobuf = BluetoothKeystoreProto.EncryptedData.newBuilder() - .setEncryptedData(ByteString.copyFrom(cipher.doFinal(data.getBytes()))) - .setInitVector(ByteString.copyFrom(cipher.getIV())).build(); + protobuf = + BluetoothKeystoreProto.EncryptedData.newBuilder() + .setEncryptedData( + ByteString.copyFrom(cipher.doFinal(data.getBytes()))) + .setInitVector(ByteString.copyFrom(cipher.getIV())) + .build(); outputBytes = protobuf.toByteArray(); if (outputBytes == null) { @@ -701,8 +678,8 @@ public class BluetoothKeystoreService { } catch (com.google.protobuf.InvalidProtocolBufferException e) { reportBluetoothKeystoreException(e, "decrypt: Failed to parse EncryptedData protobuf."); } catch (NoSuchAlgorithmException e) { - reportKeystoreException(e, - "decrypt could not find cipher algorithm " + CIPHER_ALGORITHM); + reportKeystoreException( + e, "decrypt could not find cipher algorithm " + CIPHER_ALGORITHM); } catch (NoSuchPaddingException e) { reportKeystoreException(e, "decrypt could not find padding algorithm"); } catch (IllegalBlockSizeException e) { @@ -725,7 +702,9 @@ public class BluetoothKeystoreService { try { keyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); - } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException + } catch (KeyStoreException + | CertificateException + | NoSuchAlgorithmException | IOException e) { reportKeystoreException(e, "cannot open keystore"); } @@ -740,8 +719,8 @@ public class BluetoothKeystoreService { try { KeyStore keyStore = getKeyStore(); if (keyStore.containsAlias(KEYALIAS)) { // The key exists in key store. Get the key. - KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore - .getEntry(KEYALIAS, null); + KeyStore.SecretKeyEntry secretKeyEntry = + (KeyStore.SecretKeyEntry) keyStore.getEntry(KEYALIAS, null); if (secretKeyEntry != null) { secretKey = secretKeyEntry.getSecretKey(); @@ -750,15 +729,18 @@ public class BluetoothKeystoreService { } } else { // The key does not exist in key store. Create the key and store it. - KeyGenerator keyGenerator = KeyGenerator - .getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE); - - KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(KEYALIAS, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) - .setKeySize(KEY_LENGTH) - .build(); + KeyGenerator keyGenerator = + KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE); + + KeyGenParameterSpec keyGenParameterSpec = + new KeyGenParameterSpec.Builder( + KEYALIAS, + KeyProperties.PURPOSE_ENCRYPT + | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .setKeySize(KEY_LENGTH) + .build(); keyGenerator.init(keyGenParameterSpec); secretKey = keyGenerator.generateKey(); @@ -772,8 +754,8 @@ public class BluetoothKeystoreService { } catch (NoSuchProviderException e) { reportKeystoreException(e, "getOrCreateSecretKey cannot find crypto provider"); } catch (UnrecoverableEntryException e) { - reportKeystoreException(e, - "getOrCreateSecretKey had an unrecoverable entry exception."); + reportKeystoreException( + e, "getOrCreateSecretKey had an unrecoverable entry exception."); } catch (ProviderException e) { reportKeystoreException(e, "getOrCreateSecretKey had a provider exception."); } @@ -800,9 +782,7 @@ public class BluetoothKeystoreService { Log.e(TAG, msg); } - /** - * A thread that decrypt data if the queue has new decrypt task. - */ + /** A thread that decrypt data if the queue has new decrypt task. */ private class ComputeDataThread extends Thread { private Map mSourceDataMap; private Map mTargetDataMap; @@ -842,8 +822,11 @@ public class BluetoothKeystoreService { if (targetData != null) { mTargetDataMap.put(prefixString, targetData); } else { - errorLog("Computing of Data failed with prefixString: " + prefixString - + ", doEncrypt: " + mDoEncrypt); + errorLog( + "Computing of Data failed with prefixString: " + + prefixString + + ", doEncrypt: " + + mDoEncrypt); } } } catch (InterruptedException e) { diff --git a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java index 024fe1a5292..b790e92c737 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java @@ -25,8 +25,10 @@ import androidx.room.Entity; class AudioPolicyEntity { @ColumnInfo(name = "call_establish_audio_policy") public int callEstablishAudioPolicy; + @ColumnInfo(name = "connecting_time_audio_policy") public int connectingTimeAudioPolicy; + @ColumnInfo(name = "in_band_ringtone_audio_policy") public int inBandRingtoneAudioPolicy; diff --git a/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java b/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java index 736a2e1caea..9743bba805f 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java @@ -29,11 +29,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * Class for regrouping the migration that occur when going mainline - */ +/** Class for regrouping the migration that occur when going mainline */ public final class BluetoothDatabaseMigration { private static final String TAG = "BluetoothDatabaseMigration"; + public static boolean run(Context ctx, Cursor cursor) { boolean result = true; MetadataDatabase database = MetadataDatabase.createDatabaseWithoutMigration(ctx); @@ -67,82 +66,100 @@ public final class BluetoothDatabaseMigration { private static final List> CONNECTION_POLICIES = Arrays.asList( - new Pair(BluetoothProfile.A2DP, "a2dp_connection_policy"), - new Pair(BluetoothProfile.A2DP_SINK, "a2dp_sink_connection_policy"), - new Pair(BluetoothProfile.HEADSET, "hfp_connection_policy"), - new Pair(BluetoothProfile.HEADSET_CLIENT, "hfp_client_connection_policy"), - new Pair(BluetoothProfile.HID_HOST, "hid_host_connection_policy"), - new Pair(BluetoothProfile.PAN, "pan_connection_policy"), - new Pair(BluetoothProfile.PBAP, "pbap_connection_policy"), - new Pair(BluetoothProfile.PBAP_CLIENT, "pbap_client_connection_policy"), - new Pair(BluetoothProfile.MAP, "map_connection_policy"), - new Pair(BluetoothProfile.SAP, "sap_connection_policy"), - new Pair(BluetoothProfile.HEARING_AID, "hearing_aid_connection_policy"), - new Pair(BluetoothProfile.HAP_CLIENT, "hap_client_connection_policy"), - new Pair(BluetoothProfile.MAP_CLIENT, "map_client_connection_policy"), - new Pair(BluetoothProfile.LE_AUDIO, "le_audio_connection_policy"), - new Pair(BluetoothProfile.VOLUME_CONTROL, "volume_control_connection_policy"), - new Pair(BluetoothProfile.CSIP_SET_COORDINATOR, - "csip_set_coordinator_connection_policy"), - new Pair(BluetoothProfile.LE_CALL_CONTROL, "le_call_control_connection_policy"), - new Pair(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, - "bass_client_connection_policy"), - new Pair(BluetoothProfile.BATTERY, "battery_connection_policy") - ); + new Pair(BluetoothProfile.A2DP, "a2dp_connection_policy"), + new Pair(BluetoothProfile.A2DP_SINK, "a2dp_sink_connection_policy"), + new Pair(BluetoothProfile.HEADSET, "hfp_connection_policy"), + new Pair(BluetoothProfile.HEADSET_CLIENT, "hfp_client_connection_policy"), + new Pair(BluetoothProfile.HID_HOST, "hid_host_connection_policy"), + new Pair(BluetoothProfile.PAN, "pan_connection_policy"), + new Pair(BluetoothProfile.PBAP, "pbap_connection_policy"), + new Pair(BluetoothProfile.PBAP_CLIENT, "pbap_client_connection_policy"), + new Pair(BluetoothProfile.MAP, "map_connection_policy"), + new Pair(BluetoothProfile.SAP, "sap_connection_policy"), + new Pair(BluetoothProfile.HEARING_AID, "hearing_aid_connection_policy"), + new Pair(BluetoothProfile.HAP_CLIENT, "hap_client_connection_policy"), + new Pair(BluetoothProfile.MAP_CLIENT, "map_client_connection_policy"), + new Pair(BluetoothProfile.LE_AUDIO, "le_audio_connection_policy"), + new Pair(BluetoothProfile.VOLUME_CONTROL, "volume_control_connection_policy"), + new Pair( + BluetoothProfile.CSIP_SET_COORDINATOR, + "csip_set_coordinator_connection_policy"), + new Pair(BluetoothProfile.LE_CALL_CONTROL, "le_call_control_connection_policy"), + new Pair( + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, + "bass_client_connection_policy"), + new Pair(BluetoothProfile.BATTERY, "battery_connection_policy")); private static final List> CUSTOMIZED_META_KEYS = Arrays.asList( - new Pair(BluetoothDevice.METADATA_MANUFACTURER_NAME, "manufacturer_name"), - new Pair(BluetoothDevice.METADATA_MODEL_NAME, "model_name"), - new Pair(BluetoothDevice.METADATA_SOFTWARE_VERSION, "software_version"), - new Pair(BluetoothDevice.METADATA_HARDWARE_VERSION, "hardware_version"), - new Pair(BluetoothDevice.METADATA_COMPANION_APP, "companion_app"), - new Pair(BluetoothDevice.METADATA_MAIN_ICON, "main_icon"), - new Pair(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, "is_untethered_headset"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, "untethered_left_icon"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, "untethered_right_icon"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, "untethered_case_icon"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, - "untethered_left_battery"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, - "untethered_right_battery"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, - "untethered_case_battery"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, - "untethered_left_charging"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, - "untethered_right_charging"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, - "untethered_case_charging"), - new Pair(BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, - "enhanced_settings_ui_uri"), - new Pair(BluetoothDevice.METADATA_DEVICE_TYPE, "device_type"), - new Pair(BluetoothDevice.METADATA_MAIN_BATTERY, "main_battery"), - new Pair(BluetoothDevice.METADATA_MAIN_CHARGING, "main_charging"), - new Pair(BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, - "main_low_battery_threshold"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, - "untethered_left_low_battery_threshold"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, - "untethered_right_low_battery_threshold"), - new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, - "untethered_case_low_battery_threshold"), - new Pair(BluetoothDevice.METADATA_SPATIAL_AUDIO, "spatial_audio"), - new Pair(BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, - "fastpair_customized") - ); + new Pair(BluetoothDevice.METADATA_MANUFACTURER_NAME, "manufacturer_name"), + new Pair(BluetoothDevice.METADATA_MODEL_NAME, "model_name"), + new Pair(BluetoothDevice.METADATA_SOFTWARE_VERSION, "software_version"), + new Pair(BluetoothDevice.METADATA_HARDWARE_VERSION, "hardware_version"), + new Pair(BluetoothDevice.METADATA_COMPANION_APP, "companion_app"), + new Pair(BluetoothDevice.METADATA_MAIN_ICON, "main_icon"), + new Pair( + BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, + "is_untethered_headset"), + new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, "untethered_left_icon"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, + "untethered_right_icon"), + new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, "untethered_case_icon"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, + "untethered_left_battery"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, + "untethered_right_battery"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, + "untethered_case_battery"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, + "untethered_left_charging"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, + "untethered_right_charging"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, + "untethered_case_charging"), + new Pair( + BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, + "enhanced_settings_ui_uri"), + new Pair(BluetoothDevice.METADATA_DEVICE_TYPE, "device_type"), + new Pair(BluetoothDevice.METADATA_MAIN_BATTERY, "main_battery"), + new Pair(BluetoothDevice.METADATA_MAIN_CHARGING, "main_charging"), + new Pair( + BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, + "main_low_battery_threshold"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, + "untethered_left_low_battery_threshold"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, + "untethered_right_low_battery_threshold"), + new Pair( + BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, + "untethered_case_low_battery_threshold"), + new Pair(BluetoothDevice.METADATA_SPATIAL_AUDIO, "spatial_audio"), + new Pair( + BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, + "fastpair_customized")); private static int fetchInt(Cursor cursor, String key) { return cursor.getInt(cursor.getColumnIndexOrThrow(key)); } - private static void migrate_a2dpSupportsOptionalCodecs(Cursor cursor, String logKey, - Metadata metadata) { + private static void migrate_a2dpSupportsOptionalCodecs( + Cursor cursor, String logKey, Metadata metadata) { final String key = "a2dpSupportsOptionalCodecs"; - final List allowedValue = new ArrayList<>(Arrays.asList( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)); + final List allowedValue = + new ArrayList<>( + Arrays.asList( + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)); final int value = fetchInt(cursor, key); if (!allowedValue.contains(value)) { throw new IllegalArgumentException(logKey + ": Bad value for [" + key + "]: " + value); @@ -150,13 +167,15 @@ public final class BluetoothDatabaseMigration { metadata.a2dpSupportsOptionalCodecs = value; } - private static void migrate_a2dpOptionalCodecsEnabled(Cursor cursor, String logKey, - Metadata metadata) { + private static void migrate_a2dpOptionalCodecsEnabled( + Cursor cursor, String logKey, Metadata metadata) { final String key = "a2dpOptionalCodecsEnabled"; - final List allowedValue = new ArrayList<>(Arrays.asList( - BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED)); + final List allowedValue = + new ArrayList<>( + Arrays.asList( + BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, + BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, + BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED)); final int value = fetchInt(cursor, key); if (!allowedValue.contains(value)) { throw new IllegalArgumentException(logKey + ": Bad value for [" + key + "]: " + value); @@ -164,20 +183,24 @@ public final class BluetoothDatabaseMigration { metadata.a2dpOptionalCodecsEnabled = value; } - private static void migrate_connectionPolicy(Cursor cursor, String logKey, - Metadata metadata) { - final List allowedValue = new ArrayList<>(Arrays.asList( - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, - BluetoothProfile.CONNECTION_POLICY_ALLOWED)); + private static void migrate_connectionPolicy(Cursor cursor, String logKey, Metadata metadata) { + final List allowedValue = + new ArrayList<>( + Arrays.asList( + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + BluetoothProfile.CONNECTION_POLICY_ALLOWED)); for (Pair p : CONNECTION_POLICIES) { final int policy = cursor.getInt(cursor.getColumnIndexOrThrow(p.second)); if (allowedValue.contains(policy)) { metadata.setProfileConnectionPolicy(p.first, policy); } else { - throw new IllegalArgumentException(logKey + ": Bad value for [" - + BluetoothProfile.getProfileName(p.first) - + "]: " + policy); + throw new IllegalArgumentException( + logKey + + ": Bad value for [" + + BluetoothProfile.getProfileName(p.first) + + "]: " + + policy); } } } @@ -189,5 +212,4 @@ public final class BluetoothDatabaseMigration { metadata.setCustomizedMeta(p.first, blob); } } - } diff --git a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java index dce3847dd5e..34ee90ee1cb 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java @@ -61,8 +61,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** - * The active device manager is responsible to handle a Room database - * for Bluetooth persistent data. + * The active device manager is responsible to handle a Room database for Bluetooth persistent data. */ public class DatabaseManager { private static final String TAG = "BluetoothDatabase"; @@ -74,8 +73,7 @@ public class DatabaseManager { private @GuardedBy("mDatabaseLock") MetadataDatabase mDatabase = null; private boolean mMigratedFromSettingsGlobal = false; - @VisibleForTesting - final Map mMetadataCache = new HashMap<>(); + @VisibleForTesting final Map mMetadataCache = new HashMap<>(); private final Semaphore mSemaphore = new Semaphore(1); private static final int METADATA_CHANGED_LOG_MAX_SIZE = 20; private final EvictingQueue mMetadataChangedLog; @@ -87,30 +85,24 @@ public class DatabaseManager { private static final int MSG_CLEAR_DATABASE = 100; private static final String LOCAL_STORAGE = "LocalStorage"; - private static final String - LEGACY_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_"; - private static final String - LEGACY_A2DP_SINK_PRIORITY_PREFIX = "bluetooth_a2dp_sink_priority_"; - private static final String - LEGACY_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_"; + private static final String LEGACY_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_"; + private static final String LEGACY_A2DP_SINK_PRIORITY_PREFIX = "bluetooth_a2dp_sink_priority_"; + private static final String LEGACY_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_"; private static final String LEGACY_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX = "bluetooth_a2dp_supports_optional_codecs_"; private static final String LEGACY_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX = "bluetooth_a2dp_optional_codecs_enabled_"; - private static final String - LEGACY_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_"; - private static final String - LEGACY_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_"; - private static final String - LEGACY_MAP_CLIENT_PRIORITY_PREFIX = "bluetooth_map_client_priority_"; - private static final String - LEGACY_PBAP_CLIENT_PRIORITY_PREFIX = "bluetooth_pbap_client_priority_"; - private static final String - LEGACY_SAP_PRIORITY_PREFIX = "bluetooth_sap_priority_"; - private static final String - LEGACY_PAN_PRIORITY_PREFIX = "bluetooth_pan_priority_"; - private static final String - LEGACY_HEARING_AID_PRIORITY_PREFIX = "bluetooth_hearing_aid_priority_"; + private static final String LEGACY_INPUT_DEVICE_PRIORITY_PREFIX = + "bluetooth_input_device_priority_"; + private static final String LEGACY_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_"; + private static final String LEGACY_MAP_CLIENT_PRIORITY_PREFIX = + "bluetooth_map_client_priority_"; + private static final String LEGACY_PBAP_CLIENT_PRIORITY_PREFIX = + "bluetooth_pbap_client_priority_"; + private static final String LEGACY_SAP_PRIORITY_PREFIX = "bluetooth_sap_priority_"; + private static final String LEGACY_PAN_PRIORITY_PREFIX = "bluetooth_pan_priority_"; + private static final String LEGACY_HEARING_AID_PRIORITY_PREFIX = + "bluetooth_hearing_aid_priority_"; /** Constructor of the DatabaseManager */ public DatabaseManager(AdapterService service) { @@ -126,67 +118,76 @@ public class DatabaseManager { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_LOAD_DATABASE: { - synchronized (mDatabaseLock) { - List list; - try { - list = mDatabase.load(); - } catch (IllegalStateException e) { - Log.e(TAG, "Unable to open database: " + e); - mDatabase = MetadataDatabase - .createDatabaseWithoutMigration(mAdapterService); - list = mDatabase.load(); + case MSG_LOAD_DATABASE: + { + synchronized (mDatabaseLock) { + List list; + try { + list = mDatabase.load(); + } catch (IllegalStateException e) { + Log.e(TAG, "Unable to open database: " + e); + mDatabase = + MetadataDatabase.createDatabaseWithoutMigration( + mAdapterService); + list = mDatabase.load(); + } + compactLastConnectionTime(list); + cacheMetadata(list); } - compactLastConnectionTime(list); - cacheMetadata(list); + break; } - break; - } - case MSG_UPDATE_DATABASE: { - Metadata data = (Metadata) msg.obj; - synchronized (mDatabaseLock) { - mDatabase.insert(data); + case MSG_UPDATE_DATABASE: + { + Metadata data = (Metadata) msg.obj; + synchronized (mDatabaseLock) { + mDatabase.insert(data); + } + break; } - break; - } - case MSG_DELETE_DATABASE: { - String address = (String) msg.obj; - synchronized (mDatabaseLock) { - mDatabase.delete(address); + case MSG_DELETE_DATABASE: + { + String address = (String) msg.obj; + synchronized (mDatabaseLock) { + mDatabase.delete(address); + } + break; } - break; - } - case MSG_CLEAR_DATABASE: { - synchronized (mDatabaseLock) { - mDatabase.deleteAll(); + case MSG_CLEAR_DATABASE: + { + synchronized (mDatabaseLock) { + mDatabase.deleteAll(); + } + break; } - break; - } } } } - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) { - Log.e(TAG, "Received intent with null action"); - return; - } - switch (action) { - case BluetoothAdapter.ACTION_STATE_CHANGED: { - int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, - BluetoothAdapter.STATE_OFF); - if (!mMigratedFromSettingsGlobal - && state == BluetoothAdapter.STATE_TURNING_ON) { - migrateSettingsGlobal(); + private final BroadcastReceiver mReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) { + Log.e(TAG, "Received intent with null action"); + return; + } + switch (action) { + case BluetoothAdapter.ACTION_STATE_CHANGED: + { + int state = + intent.getIntExtra( + BluetoothAdapter.EXTRA_STATE, + BluetoothAdapter.STATE_OFF); + if (!mMigratedFromSettingsGlobal + && state == BluetoothAdapter.STATE_TURNING_ON) { + migrateSettingsGlobal(); + } + break; + } } - break; } - } - } - }; + }; /** Process a change in the bonding state for a device */ public void handleBondStateChanged(BluetoothDevice device, int fromState, int toState) { @@ -223,9 +224,7 @@ public class DatabaseManager { return false; } - /** - * Set customized metadata to database with requested key - */ + /** Set customized metadata to database with requested key */ @VisibleForTesting public boolean setCustomMeta(BluetoothDevice device, int key, byte[] newValue) { if (device == null) { @@ -258,9 +257,7 @@ public class DatabaseManager { return true; } - /** - * Get customized metadata from database with requested key - */ + /** Get customized metadata from database with requested key */ public byte[] getCustomMeta(BluetoothDevice device, int key) { if (device == null) { Log.e(TAG, "getCustomMeta: device is null"); @@ -284,12 +281,10 @@ public class DatabaseManager { } } - /** - * Set audio policy metadata to database with requested key - */ + /** Set audio policy metadata to database with requested key */ @VisibleForTesting - public boolean setAudioPolicyMetadata(BluetoothDevice device, - BluetoothSinkAudioPolicy policies) { + public boolean setAudioPolicyMetadata( + BluetoothDevice device, BluetoothSinkAudioPolicy policies) { if (device == null) { Log.e(TAG, "setAudioPolicyMetadata: device is null"); return false; @@ -311,9 +306,7 @@ public class DatabaseManager { } } - /** - * Get audio policy metadata from database with requested key - */ + /** Get audio policy metadata from database with requested key */ @VisibleForTesting public BluetoothSinkAudioPolicy getAudioPolicyMetadata(BluetoothDevice device) { if (device == null) { @@ -342,23 +335,23 @@ public class DatabaseManager { * Set the device profile connection policy * * @param device {@link BluetoothDevice} wish to set - * @param profile The Bluetooth profile; one of {@link BluetoothProfile#HEADSET}, - * {@link BluetoothProfile#HEADSET_CLIENT}, {@link BluetoothProfile#A2DP}, - * {@link BluetoothProfile#A2DP_SINK}, {@link BluetoothProfile#HID_HOST}, - * {@link BluetoothProfile#PAN}, {@link BluetoothProfile#PBAP}, - * {@link BluetoothProfile#PBAP_CLIENT}, {@link BluetoothProfile#MAP}, - * {@link BluetoothProfile#MAP_CLIENT}, {@link BluetoothProfile#SAP}, - * {@link BluetoothProfile#HEARING_AID}, {@link BluetoothProfile#LE_AUDIO}, - * {@link BluetoothProfile#VOLUME_CONTROL}, {@link BluetoothProfile#CSIP_SET_COORDINATOR}, - * {@link BluetoothProfile#LE_AUDIO_BROADCAST_ASSISTANT}, - * @param newConnectionPolicy the connectionPolicy to set; one of - * {@link BluetoothProfile.CONNECTION_POLICY_UNKNOWN}, - * {@link BluetoothProfile.CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile.CONNECTION_POLICY_ALLOWED} + * @param profile The Bluetooth profile; one of {@link BluetoothProfile#HEADSET}, {@link + * BluetoothProfile#HEADSET_CLIENT}, {@link BluetoothProfile#A2DP}, {@link + * BluetoothProfile#A2DP_SINK}, {@link BluetoothProfile#HID_HOST}, {@link + * BluetoothProfile#PAN}, {@link BluetoothProfile#PBAP}, {@link + * BluetoothProfile#PBAP_CLIENT}, {@link BluetoothProfile#MAP}, {@link + * BluetoothProfile#MAP_CLIENT}, {@link BluetoothProfile#SAP}, {@link + * BluetoothProfile#HEARING_AID}, {@link BluetoothProfile#LE_AUDIO}, {@link + * BluetoothProfile#VOLUME_CONTROL}, {@link BluetoothProfile#CSIP_SET_COORDINATOR}, {@link + * BluetoothProfile#LE_AUDIO_BROADCAST_ASSISTANT}, + * @param newConnectionPolicy the connectionPolicy to set; one of {@link + * BluetoothProfile.CONNECTION_POLICY_UNKNOWN}, {@link + * BluetoothProfile.CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile.CONNECTION_POLICY_ALLOWED} */ @VisibleForTesting - public boolean setProfileConnectionPolicy(BluetoothDevice device, int profile, - int newConnectionPolicy) { + public boolean setProfileConnectionPolicy( + BluetoothDevice device, int profile, int newConnectionPolicy) { if (device == null) { Log.e(TAG, "setProfileConnectionPolicy: device is null"); return false; @@ -389,11 +382,22 @@ public class DatabaseManager { return true; } String profileStr = BluetoothProfile.getProfileName(profile); - logMetadataChange(data, profileStr + " connection policy changed: " - + oldConnectionPolicy + " -> " + newConnectionPolicy); - - Log.v(TAG, "setProfileConnectionPolicy: device " + device.getAnonymizedAddress() - + " profile=" + profileStr + ", connectionPolicy=" + newConnectionPolicy); + logMetadataChange( + data, + profileStr + + " connection policy changed: " + + oldConnectionPolicy + + " -> " + + newConnectionPolicy); + + Log.v( + TAG, + "setProfileConnectionPolicy: device " + + device.getAnonymizedAddress() + + " profile=" + + profileStr + + ", connectionPolicy=" + + newConnectionPolicy); data.setProfileConnectionPolicy(profile, newConnectionPolicy); updateDatabase(data); @@ -405,19 +409,19 @@ public class DatabaseManager { * Get the device profile connection policy * * @param device {@link BluetoothDevice} wish to get - * @param profile The Bluetooth profile; one of {@link BluetoothProfile#HEADSET}, - * {@link BluetoothProfile#HEADSET_CLIENT}, {@link BluetoothProfile#A2DP}, - * {@link BluetoothProfile#A2DP_SINK}, {@link BluetoothProfile#HID_HOST}, - * {@link BluetoothProfile#PAN}, {@link BluetoothProfile#PBAP}, - * {@link BluetoothProfile#PBAP_CLIENT}, {@link BluetoothProfile#MAP}, - * {@link BluetoothProfile#MAP_CLIENT}, {@link BluetoothProfile#SAP}, - * {@link BluetoothProfile#HEARING_AID}, {@link BluetoothProfile#LE_AUDIO}, - * {@link BluetoothProfile#VOLUME_CONTROL}, {@link BluetoothProfile#CSIP_SET_COORDINATOR}, - * {@link BluetoothProfile#LE_AUDIO_BROADCAST_ASSISTANT}, - * @return the profile connection policy of the device; one of - * {@link BluetoothProfile.CONNECTION_POLICY_UNKNOWN}, - * {@link BluetoothProfile.CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile.CONNECTION_POLICY_ALLOWED} + * @param profile The Bluetooth profile; one of {@link BluetoothProfile#HEADSET}, {@link + * BluetoothProfile#HEADSET_CLIENT}, {@link BluetoothProfile#A2DP}, {@link + * BluetoothProfile#A2DP_SINK}, {@link BluetoothProfile#HID_HOST}, {@link + * BluetoothProfile#PAN}, {@link BluetoothProfile#PBAP}, {@link + * BluetoothProfile#PBAP_CLIENT}, {@link BluetoothProfile#MAP}, {@link + * BluetoothProfile#MAP_CLIENT}, {@link BluetoothProfile#SAP}, {@link + * BluetoothProfile#HEARING_AID}, {@link BluetoothProfile#LE_AUDIO}, {@link + * BluetoothProfile#VOLUME_CONTROL}, {@link BluetoothProfile#CSIP_SET_COORDINATOR}, {@link + * BluetoothProfile#LE_AUDIO_BROADCAST_ASSISTANT}, + * @return the profile connection policy of the device; one of {@link + * BluetoothProfile.CONNECTION_POLICY_UNKNOWN}, {@link + * BluetoothProfile.CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile.CONNECTION_POLICY_ALLOWED} */ public int getProfileConnectionPolicy(BluetoothDevice device, int profile) { if (device == null) { @@ -429,17 +433,25 @@ public class DatabaseManager { synchronized (mMetadataCache) { if (!mMetadataCache.containsKey(address)) { - Log.d(TAG, "getProfileConnectionPolicy: device " + device.getAnonymizedAddress() - + " is not in cache"); + Log.d( + TAG, + "getProfileConnectionPolicy: device " + + device.getAnonymizedAddress() + + " is not in cache"); return BluetoothProfile.CONNECTION_POLICY_UNKNOWN; } Metadata data = mMetadataCache.get(address); int connectionPolicy = data.getProfileConnectionPolicy(profile); - Log.v(TAG, "getProfileConnectionPolicy: device " + device.getAnonymizedAddress() - + " profile=" + BluetoothProfile.getProfileName(profile) - + ", connectionPolicy=" + connectionPolicy); + Log.v( + TAG, + "getProfileConnectionPolicy: device " + + device.getAnonymizedAddress() + + " profile=" + + BluetoothProfile.getProfileName(profile) + + ", connectionPolicy=" + + connectionPolicy); return connectionPolicy; } } @@ -448,10 +460,10 @@ public class DatabaseManager { * Set the A2DP optional coedc support value * * @param device {@link BluetoothDevice} wish to set - * @param newValue the new A2DP optional coedc support value, one of - * {@link BluetoothA2dp#OPTIONAL_CODECS_SUPPORT_UNKNOWN}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_NOT_SUPPORTED}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_SUPPORTED} + * @param newValue the new A2DP optional coedc support value, one of {@link + * BluetoothA2dp#OPTIONAL_CODECS_SUPPORT_UNKNOWN}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_NOT_SUPPORTED}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_SUPPORTED} */ @VisibleForTesting public void setA2dpSupportsOptionalCodecs(BluetoothDevice device, int newValue) { @@ -477,8 +489,8 @@ public class DatabaseManager { if (oldValue == newValue) { return; } - logMetadataChange(data, "Supports optional codec changed: " - + oldValue + " -> " + newValue); + logMetadataChange( + data, "Supports optional codec changed: " + oldValue + " -> " + newValue); data.a2dpSupportsOptionalCodecs = newValue; updateDatabase(data); @@ -489,10 +501,10 @@ public class DatabaseManager { * Get the A2DP optional coedc support value * * @param device {@link BluetoothDevice} wish to get - * @return the A2DP optional coedc support value, one of - * {@link BluetoothA2dp#OPTIONAL_CODECS_SUPPORT_UNKNOWN}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_NOT_SUPPORTED}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_SUPPORTED}, + * @return the A2DP optional coedc support value, one of {@link + * BluetoothA2dp#OPTIONAL_CODECS_SUPPORT_UNKNOWN}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_NOT_SUPPORTED}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_SUPPORTED}, */ @VisibleForTesting @OptionalCodecsSupportStatus @@ -519,10 +531,10 @@ public class DatabaseManager { * Set the A2DP optional coedc enabled value * * @param device {@link BluetoothDevice} wish to set - * @param newValue the new A2DP optional coedc enabled value, one of - * {@link BluetoothA2dp#OPTIONAL_CODECS_PREF_UNKNOWN}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_PREF_DISABLED}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_PREF_ENABLED} + * @param newValue the new A2DP optional coedc enabled value, one of {@link + * BluetoothA2dp#OPTIONAL_CODECS_PREF_UNKNOWN}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_PREF_DISABLED}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_PREF_ENABLED} */ @VisibleForTesting public void setA2dpOptionalCodecsEnabled(BluetoothDevice device, int newValue) { @@ -548,8 +560,8 @@ public class DatabaseManager { if (oldValue == newValue) { return; } - logMetadataChange(data, "Enable optional codec changed: " - + oldValue + " -> " + newValue); + logMetadataChange( + data, "Enable optional codec changed: " + oldValue + " -> " + newValue); data.a2dpOptionalCodecsEnabled = newValue; updateDatabase(data); @@ -560,10 +572,10 @@ public class DatabaseManager { * Get the A2DP optional coedc enabled value * * @param device {@link BluetoothDevice} wish to get - * @return the A2DP optional coedc enabled value, one of - * {@link BluetoothA2dp#OPTIONAL_CODECS_PREF_UNKNOWN}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_PREF_DISABLED}, - * {@link BluetoothA2dp#OPTIONAL_CODECS_PREF_ENABLED} + * @return the A2DP optional coedc enabled value, one of {@link + * BluetoothA2dp#OPTIONAL_CODECS_PREF_UNKNOWN}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_PREF_DISABLED}, {@link + * BluetoothA2dp#OPTIONAL_CODECS_PREF_ENABLED} */ @VisibleForTesting @OptionalCodecsPreferenceStatus @@ -740,8 +752,8 @@ public class DatabaseManager { * Gets the most recently connected bluetooth devices in order with most recently connected * first and least recently connected last * - * @return a {@link List} of {@link BluetoothDevice} representing connected bluetooth devices - * in order of most recently connected + * @return a {@link List} of {@link BluetoothDevice} representing connected bluetooth devices in + * order of most recently connected */ public List getMostRecentlyConnectedDevices() { List mostRecentlyConnectedDevices = new ArrayList<>(); @@ -750,11 +762,15 @@ public class DatabaseManager { sortedMetadata.sort((o1, o2) -> Long.compare(o2.last_active_time, o1.last_active_time)); for (Metadata metadata : sortedMetadata) { try { - mostRecentlyConnectedDevices.add(BluetoothAdapter.getDefaultAdapter() - .getRemoteDevice(metadata.getAddress())); + mostRecentlyConnectedDevices.add( + BluetoothAdapter.getDefaultAdapter() + .getRemoteDevice(metadata.getAddress())); } catch (IllegalArgumentException ex) { - Log.d(TAG, "getBondedDevicesOrdered: Invalid address for " - + "device " + metadata.getAnonymizedAddress()); + Log.d( + TAG, + "getBondedDevicesOrdered: Invalid address for " + + "device " + + metadata.getAnonymizedAddress()); } } } @@ -765,8 +781,8 @@ public class DatabaseManager { * Gets the most recently connected bluetooth device in a given list. * * @param devicesList the list of {@link BluetoothDevice} to search in - * @return the most recently connected {@link BluetoothDevice} in the given - * {@code devicesList}, or null if an error occurred + * @return the most recently connected {@link BluetoothDevice} in the given {@code devicesList}, + * or null if an error occurred */ public BluetoothDevice getMostRecentlyConnectedDevicesInList( List devicesList) { @@ -780,8 +796,9 @@ public class DatabaseManager { for (BluetoothDevice device : devicesList) { String address = device.getAddress(); Metadata metadata = mMetadataCache.get(address); - if (metadata != null && (mostRecentLastActiveTime == -1 - || mostRecentLastActiveTime < metadata.last_active_time)) { + if (metadata != null + && (mostRecentLastActiveTime == -1 + || mostRecentLastActiveTime < metadata.last_active_time)) { mostRecentLastActiveTime = metadata.last_active_time; mostRecentDevice = device; } @@ -801,11 +818,14 @@ public class DatabaseManager { Metadata metadata = entry.getValue(); if (metadata.is_active_a2dp_device) { try { - return BluetoothAdapter.getDefaultAdapter().getRemoteDevice( - metadata.getAddress()); + return BluetoothAdapter.getDefaultAdapter() + .getRemoteDevice(metadata.getAddress()); } catch (IllegalArgumentException ex) { - Log.d(TAG, "getMostRecentlyConnectedA2dpDevice: Invalid address for " - + "device " + metadata.getAnonymizedAddress()); + Log.d( + TAG, + "getMostRecentlyConnectedA2dpDevice: Invalid address for " + + "device " + + metadata.getAnonymizedAddress()); } } } @@ -857,7 +877,6 @@ public class DatabaseManager { } /** - * * @param metadataList is the list of metadata */ private void compactLastConnectionTime(List metadataList) { @@ -868,9 +887,14 @@ public class DatabaseManager { for (int index = metadataList.size() - 1; index >= 0; index--) { Metadata metadata = metadataList.get(index); if (metadata.last_active_time != MetadataDatabase.sCurrentConnectionNumber) { - Log.d(TAG, "compactLastConnectionTime: Setting last_active_item for device: " - + metadata.getAnonymizedAddress() + " from " + metadata.last_active_time - + " to " + MetadataDatabase.sCurrentConnectionNumber); + Log.d( + TAG, + "compactLastConnectionTime: Setting last_active_item for device: " + + metadata.getAnonymizedAddress() + + " from " + + metadata.last_active_time + + " to " + + MetadataDatabase.sCurrentConnectionNumber); metadata.last_active_time = MetadataDatabase.sCurrentConnectionNumber; updateDatabase(metadata); MetadataDatabase.sCurrentConnectionNumber++; @@ -899,8 +923,7 @@ public class DatabaseManager { if (groupDevices.isEmpty()) { throw new IllegalArgumentException("groupDevices cannot be empty"); } - int outputProfile = modeToProfileBundle.getInt( - BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY); + int outputProfile = modeToProfileBundle.getInt(BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY); int duplexProfile = modeToProfileBundle.getInt(BluetoothAdapter.AUDIO_MODE_DUPLEX); boolean isPreferenceSet = false; @@ -919,20 +942,28 @@ public class DatabaseManager { // Finds the device in the group which stores the group's preferences Metadata metadata = mMetadataCache.get(address); - if (outputProfile != 0 && (metadata.preferred_output_only_profile != 0 - || metadata.preferred_duplex_profile != 0)) { - Log.i(TAG, "setPreferredAudioProfiles: Updating OUTPUT_ONLY audio profile for " - + "device: " + device + " to " - + BluetoothProfile.getProfileName(outputProfile)); + if (outputProfile != 0 + && (metadata.preferred_output_only_profile != 0 + || metadata.preferred_duplex_profile != 0)) { + Log.i( + TAG, + "setPreferredAudioProfiles: Updating OUTPUT_ONLY audio profile for " + + "device: " + + device + + " to " + + BluetoothProfile.getProfileName(outputProfile)); metadata.preferred_output_only_profile = outputProfile; isPreferenceSet = true; } - if (duplexProfile != 0 && (metadata.preferred_output_only_profile != 0 - || metadata.preferred_duplex_profile != 0)) { - Log.i(TAG, + if (duplexProfile != 0 + && (metadata.preferred_output_only_profile != 0 + || metadata.preferred_duplex_profile != 0)) { + Log.i( + TAG, "setPreferredAudioProfiles: Updating DUPLEX audio profile for device: " - + device + " to " + BluetoothProfile.getProfileName( - duplexProfile)); + + device + + " to " + + BluetoothProfile.getProfileName(duplexProfile)); metadata.preferred_duplex_profile = duplexProfile; isPreferenceSet = true; } @@ -947,16 +978,22 @@ public class DatabaseManager { // Updates preferred audio profiles for the device Metadata metadata = mMetadataCache.get(firstGroupDevice.getAddress()); if (outputProfile != 0) { - Log.i(TAG, "setPreferredAudioProfiles: Updating output only audio profile for " - + "device: " + firstGroupDevice + " to " - + BluetoothProfile.getProfileName(outputProfile)); + Log.i( + TAG, + "setPreferredAudioProfiles: Updating output only audio profile for " + + "device: " + + firstGroupDevice + + " to " + + BluetoothProfile.getProfileName(outputProfile)); metadata.preferred_output_only_profile = outputProfile; } if (duplexProfile != 0) { - Log.i(TAG, + Log.i( + TAG, "setPreferredAudioProfiles: Updating duplex audio profile for device: " - + firstGroupDevice + " to " + BluetoothProfile.getProfileName( - duplexProfile)); + + firstGroupDevice + + " to " + + BluetoothProfile.getProfileName(duplexProfile)); metadata.preferred_duplex_profile = duplexProfile; } @@ -967,8 +1004,8 @@ public class DatabaseManager { } /** - * Sets the preferred profile for the supplied audio modes. See - * {@link BluetoothAdapter#getPreferredAudioProfiles(BluetoothDevice)} for more details. + * Sets the preferred profile for the supplied audio modes. See {@link + * BluetoothAdapter#getPreferredAudioProfiles(BluetoothDevice)} for more details. * * @param device is the device for which we want to get the preferred audio profiles * @return a Bundle containing the preferred audio profiles @@ -1065,8 +1102,7 @@ public class DatabaseManager { } /** - * Get the {@link Looper} for the handler thread. This is used in testing and helper - * objects + * Get the {@link Looper} for the handler thread. This is used in testing and helper objects * * @return {@link Looper} for the handler thread */ @@ -1107,14 +1143,11 @@ public class DatabaseManager { } String getDatabaseAbsolutePath() { - //TODO backup database when Bluetooth turn off and FOTA? - return mAdapterService.getDatabasePath(MetadataDatabase.DATABASE_NAME) - .getAbsolutePath(); + // TODO backup database when Bluetooth turn off and FOTA? + return mAdapterService.getDatabasePath(MetadataDatabase.DATABASE_NAME).getAbsolutePath(); } - /** - * Clear all persistence data in database - */ + /** Clear all persistence data in database */ public void factoryReset() { Log.w(TAG, "factoryReset"); Message message = mHandler.obtainMessage(MSG_CLEAR_DATABASE); @@ -1168,19 +1201,22 @@ public class DatabaseManager { void removeUnusedMetadata() { BluetoothDevice[] bondedDevices = mAdapterService.getBondedDevices(); synchronized (mMetadataCache) { - mMetadataCache.forEach((address, metadata) -> { - if (!address.equals(LOCAL_STORAGE) - && !Arrays.asList(bondedDevices).stream().anyMatch(device -> - address.equals(device.getAddress()))) { - List list = metadata.getChangedCustomizedMeta(); - for (int key : list) { - mAdapterService.metadataChanged(address, key, null); - } - Log.i(TAG, "remove unpaired device from database " - + metadata.getAnonymizedAddress()); - deleteDatabase(mMetadataCache.get(address)); - } - }); + mMetadataCache.forEach( + (address, metadata) -> { + if (!address.equals(LOCAL_STORAGE) + && !Arrays.asList(bondedDevices).stream() + .anyMatch(device -> address.equals(device.getAddress()))) { + List list = metadata.getChangedCustomizedMeta(); + for (int key : list) { + mAdapterService.metadataChanged(address, key, null); + } + Log.i( + TAG, + "remove unpaired device from database " + + metadata.getAnonymizedAddress()); + deleteDatabase(mMetadataCache.get(address)); + } + }); } } @@ -1222,68 +1258,96 @@ public class DatabaseManager { ContentResolver contentResolver = mAdapterService.getContentResolver(); for (BluetoothDevice device : bondedDevices) { - int a2dpConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyA2dpSinkPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int a2dpSinkConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyA2dpSrcPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int hearingaidConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyHearingAidPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int headsetConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyHeadsetPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int headsetClientConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyHeadsetPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int hidHostConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyHidHostPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int mapConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyMapPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int mapClientConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyMapClientPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int panConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyPanPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int pbapConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyPbapClientPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int pbapClientConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacyPbapClientPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int sapConnectionPolicy = Settings.Global.getInt(contentResolver, - getLegacySapPriorityKey(device.getAddress()), - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - int a2dpSupportsOptionalCodec = Settings.Global.getInt(contentResolver, - getLegacyA2dpSupportsOptionalCodecsKey(device.getAddress()), - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); - int a2dpOptionalCodecEnabled = Settings.Global.getInt(contentResolver, - getLegacyA2dpOptionalCodecsEnabledKey(device.getAddress()), - BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); + int a2dpConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyA2dpSinkPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int a2dpSinkConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyA2dpSrcPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int hearingaidConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyHearingAidPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int headsetConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyHeadsetPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int headsetClientConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyHeadsetPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int hidHostConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyHidHostPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int mapConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyMapPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int mapClientConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyMapClientPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int panConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyPanPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int pbapConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyPbapClientPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int pbapClientConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacyPbapClientPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int sapConnectionPolicy = + Settings.Global.getInt( + contentResolver, + getLegacySapPriorityKey(device.getAddress()), + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + int a2dpSupportsOptionalCodec = + Settings.Global.getInt( + contentResolver, + getLegacyA2dpSupportsOptionalCodecsKey(device.getAddress()), + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); + int a2dpOptionalCodecEnabled = + Settings.Global.getInt( + contentResolver, + getLegacyA2dpOptionalCodecsEnabledKey(device.getAddress()), + BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); String address = device.getAddress(); Metadata data = new Metadata(address); data.setProfileConnectionPolicy(BluetoothProfile.A2DP, a2dpConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.A2DP_SINK, a2dpSinkConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.HEADSET, headsetConnectionPolicy); - data.setProfileConnectionPolicy(BluetoothProfile.HEADSET_CLIENT, - headsetClientConnectionPolicy); + data.setProfileConnectionPolicy( + BluetoothProfile.HEADSET_CLIENT, headsetClientConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.HID_HOST, hidHostConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.PAN, panConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.PBAP, pbapConnectionPolicy); - data.setProfileConnectionPolicy(BluetoothProfile.PBAP_CLIENT, - pbapClientConnectionPolicy); + data.setProfileConnectionPolicy( + BluetoothProfile.PBAP_CLIENT, pbapClientConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.MAP, mapConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.MAP_CLIENT, mapClientConnectionPolicy); data.setProfileConnectionPolicy(BluetoothProfile.SAP, sapConnectionPolicy); - data.setProfileConnectionPolicy(BluetoothProfile.HEARING_AID, - hearingaidConnectionPolicy); - data.setProfileConnectionPolicy(BluetoothProfile.LE_AUDIO, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + data.setProfileConnectionPolicy( + BluetoothProfile.HEARING_AID, hearingaidConnectionPolicy); + data.setProfileConnectionPolicy( + BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); data.a2dpSupportsOptionalCodecs = a2dpSupportsOptionalCodec; data.a2dpOptionalCodecsEnabled = a2dpOptionalCodecEnabled; mMetadataCache.put(address, data); @@ -1298,36 +1362,26 @@ public class DatabaseManager { // Reload database after migration is completed loadDatabase(); - } - /** - * Get the key that retrieves a bluetooth headset's priority. - */ + /** Get the key that retrieves a bluetooth headset's priority. */ private static String getLegacyHeadsetPriorityKey(String address) { return LEGACY_HEADSET_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth a2dp sink's priority. - */ + /** Get the key that retrieves a bluetooth a2dp sink's priority. */ private static String getLegacyA2dpSinkPriorityKey(String address) { return LEGACY_A2DP_SINK_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth a2dp src's priority. - */ + /** Get the key that retrieves a bluetooth a2dp src's priority. */ private static String getLegacyA2dpSrcPriorityKey(String address) { return LEGACY_A2DP_SRC_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth a2dp device's ability to support optional codecs. - */ + /** Get the key that retrieves a bluetooth a2dp device's ability to support optional codecs. */ private static String getLegacyA2dpSupportsOptionalCodecsKey(String address) { - return LEGACY_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX - + address.toUpperCase(Locale.ROOT); + return LEGACY_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX + address.toUpperCase(Locale.ROOT); } /** @@ -1335,55 +1389,40 @@ public class DatabaseManager { * enabled. */ private static String getLegacyA2dpOptionalCodecsEnabledKey(String address) { - return LEGACY_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX - + address.toUpperCase(Locale.ROOT); + return LEGACY_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth Input Device's priority. - */ + /** Get the key that retrieves a bluetooth Input Device's priority. */ private static String getLegacyHidHostPriorityKey(String address) { return LEGACY_INPUT_DEVICE_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth pan client priority. - */ + /** Get the key that retrieves a bluetooth pan client priority. */ private static String getLegacyPanPriorityKey(String address) { return LEGACY_PAN_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth hearing aid priority. - */ + /** Get the key that retrieves a bluetooth hearing aid priority. */ private static String getLegacyHearingAidPriorityKey(String address) { return LEGACY_HEARING_AID_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth map priority. - */ + /** Get the key that retrieves a bluetooth map priority. */ private static String getLegacyMapPriorityKey(String address) { return LEGACY_MAP_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth map client priority. - */ + /** Get the key that retrieves a bluetooth map client priority. */ private static String getLegacyMapClientPriorityKey(String address) { return LEGACY_MAP_CLIENT_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth pbap client priority. - */ + /** Get the key that retrieves a bluetooth pbap client priority. */ private static String getLegacyPbapClientPriorityKey(String address) { return LEGACY_PBAP_CLIENT_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } - /** - * Get the key that retrieves a bluetooth sap priority. - */ + /** Get the key that retrieves a bluetooth sap priority. */ private static String getLegacySapPriorityKey(String address) { return LEGACY_SAP_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); } @@ -1425,8 +1464,8 @@ public class DatabaseManager { } private void logManufacturerInfo(BluetoothDevice device, int key, byte[] bytesValue) { - String callingApp = mAdapterService.getPackageManager().getNameForUid( - Binder.getCallingUid()); + String callingApp = + mAdapterService.getPackageManager().getNameForUid(Binder.getCallingUid()); String manufacturerName = ""; String modelName = ""; String hardwareVersion = ""; @@ -1449,10 +1488,16 @@ public class DatabaseManager { return; } String[] macAddress = device.getAddress().split(":"); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_DEVICE_INFO_REPORTED, + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_DEVICE_INFO_REPORTED, mAdapterService.obfuscateAddress(device), - BluetoothProtoEnums.DEVICE_INFO_EXTERNAL, callingApp, manufacturerName, modelName, - hardwareVersion, softwareVersion, mAdapterService.getMetricId(device), + BluetoothProtoEnums.DEVICE_INFO_EXTERNAL, + callingApp, + manufacturerName, + modelName, + hardwareVersion, + softwareVersion, + mAdapterService.getMetricId(device), device.getAddressType(), Integer.parseInt(macAddress[0], 16), Integer.parseInt(macAddress[1], 16), @@ -1462,8 +1507,8 @@ public class DatabaseManager { private void logMetadataChange(Metadata data, String log) { String time = Utils.getLocalTimeString(); String uidPid = Utils.getUidPidString(); - mMetadataChangedLog.add(time + " (" + uidPid + ") " + data.getAnonymizedAddress() - + " " + log); + mMetadataChangedLog.add( + time + " (" + uidPid + ") " + data.getAnonymizedAddress() + " " + log); } /** diff --git a/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java b/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java index ea0cda76ade..d5b07828d02 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java @@ -36,18 +36,13 @@ import java.util.List; @Entity(tableName = "metadata") @VisibleForTesting public class Metadata { - @PrimaryKey - @NonNull - private String address; + @PrimaryKey @NonNull private String address; public boolean migrated; - @Embedded - public ProfilePrioritiesEntity profileConnectionPolicies; + @Embedded public ProfilePrioritiesEntity profileConnectionPolicies; - @Embedded - @NonNull - public CustomizedMetadataEntity publicMetadata; + @Embedded @NonNull public CustomizedMetadataEntity publicMetadata; public @OptionalCodecsSupportStatus int a2dpSupportsOptionalCodecs; public @OptionalCodecsPreferenceStatus int a2dpOptionalCodecsEnabled; @@ -57,8 +52,7 @@ public class Metadata { public boolean isActiveHfpDevice; - @Embedded - public AudioPolicyEntity audioPolicyMetadata; + @Embedded public AudioPolicyEntity audioPolicyMetadata; /** * The preferred profile to be used for {@link BluetoothDevice#AUDIO_MODE_OUTPUT_ONLY}. This can @@ -69,9 +63,9 @@ public class Metadata { public int preferred_output_only_profile; /** - * The preferred profile to be used for {@link BluetoothDevice#AUDIO_MODE_DUPLEX}. This can - * be either {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#LE_AUDIO}. This value - * is only used if the remote device supports both HFP and LE Audio and both transports are + * The preferred profile to be used for {@link BluetoothDevice#AUDIO_MODE_DUPLEX}. This can be + * either {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#LE_AUDIO}. This value is + * only used if the remote device supports both HFP and LE Audio and both transports are * connected and active. */ public int preferred_duplex_profile; @@ -131,7 +125,8 @@ public class Metadata { /** * Returns the anonymized hardware address. The first three octets will be suppressed for * anonymization. - *

For example, "XX:XX:XX:AA:BB:CC". + * + *

For example, "XX:XX:XX:AA:BB:CC". * * @return Anonymized bluetooth hardware address as string */ diff --git a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java index 5efdb245a07..7db45bf9e3d 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java @@ -25,27 +25,19 @@ import java.util.List; @Dao interface MetadataDao { - /** - * Load all items in the database - */ + /** Load all items in the database */ @Query("SELECT * FROM metadata ORDER BY last_active_time DESC") List load(); - /** - * Create or update a Metadata in the database - */ + /** Create or update a Metadata in the database */ @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(Metadata... metadata); - /** - * Delete a Metadata in the database - */ + /** Delete a Metadata in the database */ @Query("DELETE FROM metadata WHERE address = :address") void delete(String address); - /** - * Delete all Metadatas in the database - */ + /** Delete all Metadatas in the database */ @Query("DELETE FROM metadata") void deleteAll(); } diff --git a/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java index 6825adc97a7..85ec34544bd 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java @@ -67,25 +67,44 @@ class ProfilePrioritiesEntity { public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("A2DP=").append(a2dp_connection_policy) - .append("|A2DP_SINK=").append(a2dp_sink_connection_policy) - .append("|CSIP_SET_COORDINATOR=").append(csip_set_coordinator_connection_policy) - .append("|HEADSET=").append(hfp_connection_policy) - .append("|HEADSET_CLIENT=").append(hfp_client_connection_policy) - .append("|HID_HOST=").append(hid_host_connection_policy) - .append("|PAN=").append(pan_connection_policy) - .append("|PBAP=").append(pbap_connection_policy) - .append("|PBAP_CLIENT=").append(pbap_client_connection_policy) - .append("|MAP=").append(map_connection_policy) - .append("|MAP_CLIENT=").append(map_client_connection_policy) - .append("|SAP=").append(sap_connection_policy) - .append("|HAP=").append(hap_client_connection_policy) - .append("|HEARING_AID=").append(hearing_aid_connection_policy) - .append("|LE_AUDIO=").append(le_audio_connection_policy) - .append("|VOLUME_CONTROL=").append(volume_control_connection_policy) - .append("|LE_CALL_CONTROL=").append(le_call_control_connection_policy) - .append("|LE_BROADCAST_ASSISTANT=").append(bass_client_connection_policy) - .append("|BATTERY=").append(battery_connection_policy); + builder.append("A2DP=") + .append(a2dp_connection_policy) + .append("|A2DP_SINK=") + .append(a2dp_sink_connection_policy) + .append("|CSIP_SET_COORDINATOR=") + .append(csip_set_coordinator_connection_policy) + .append("|HEADSET=") + .append(hfp_connection_policy) + .append("|HEADSET_CLIENT=") + .append(hfp_client_connection_policy) + .append("|HID_HOST=") + .append(hid_host_connection_policy) + .append("|PAN=") + .append(pan_connection_policy) + .append("|PBAP=") + .append(pbap_connection_policy) + .append("|PBAP_CLIENT=") + .append(pbap_client_connection_policy) + .append("|MAP=") + .append(map_connection_policy) + .append("|MAP_CLIENT=") + .append(map_client_connection_policy) + .append("|SAP=") + .append(sap_connection_policy) + .append("|HAP=") + .append(hap_client_connection_policy) + .append("|HEARING_AID=") + .append(hearing_aid_connection_policy) + .append("|LE_AUDIO=") + .append(le_audio_connection_policy) + .append("|VOLUME_CONTROL=") + .append(volume_control_connection_policy) + .append("|LE_CALL_CONTROL=") + .append(le_call_control_connection_policy) + .append("|LE_BROADCAST_ASSISTANT=") + .append(bass_client_connection_policy) + .append("|BATTERY=") + .append(battery_connection_policy); return builder.toString(); } diff --git a/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java b/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java index e8a67acbb3d..72be2ec6b3e 100644 --- a/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java +++ b/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java @@ -23,9 +23,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothStatsLog; import com.android.internal.annotations.VisibleForTesting; -/** - * Utility method to report exceptions and error/warn logs in content profiles. - */ +/** Utility method to report exceptions and error/warn logs in content profiles. */ public class ContentProfileErrorReportUtils { private static final String TAG = ContentProfileErrorReportUtils.class.getSimpleName(); diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorNativeInterface.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorNativeInterface.java index 1ffbfe9bd4e..5fe00aaeb01 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorNativeInterface.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorNativeInterface.java @@ -27,9 +27,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.UUID; -/** - * CSIP Set Coordinator role native interface - */ +/** CSIP Set Coordinator role native interface */ public class CsipSetCoordinatorNativeInterface { private static final String TAG = "CsipSetCoordinatorNativeInterface"; private BluetoothAdapter mAdapter; @@ -46,9 +44,7 @@ public class CsipSetCoordinatorNativeInterface { } } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static CsipSetCoordinatorNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -69,16 +65,14 @@ public class CsipSetCoordinatorNativeInterface { /** * Initializes the native interface. * - * priorities to configure. + *

priorities to configure. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { initNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { cleanupNative(); @@ -140,8 +134,9 @@ public class CsipSetCoordinatorNativeInterface { /** Device connection state change */ @VisibleForTesting public void onConnectionStateChanged(byte[] address, int state) { - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.device = getDevice(address); event.valueInt1 = state; @@ -154,8 +149,9 @@ public class CsipSetCoordinatorNativeInterface { public void onDeviceAvailable( byte[] address, int groupId, int groupSize, int rank, long uuidLsb, long uuidMsb) { UUID uuid = new UUID(uuidMsb, uuidLsb); - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); event.device = getDevice(address); event.valueInt1 = groupId; event.valueInt2 = groupSize; @@ -170,13 +166,12 @@ public class CsipSetCoordinatorNativeInterface { // All callbacks are routed via the Service which will disambiguate which // state machine the message should be routed to. - /** - * Set member available callback - */ + /** Set member available callback */ @VisibleForTesting public void onSetMemberAvailable(byte[] address, int groupId) { - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_SET_MEMBER_AVAILABLE); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_SET_MEMBER_AVAILABLE); event.device = getDevice(address); event.valueInt1 = groupId; Log.d(TAG, "onSetMemberAvailable: " + event); @@ -184,8 +179,7 @@ public class CsipSetCoordinatorNativeInterface { } /** - * Group lock changed callback as a result of lock or unlock request or - * autonomous event. + * Group lock changed callback as a result of lock or unlock request or autonomous event. * * @param groupId group identifier * @param locked whether group is locked or unlocked @@ -193,8 +187,9 @@ public class CsipSetCoordinatorNativeInterface { */ @VisibleForTesting public void onGroupLockChanged(int groupId, boolean locked, int status) { - CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_GROUP_LOCK_CHANGED); + CsipSetCoordinatorStackEvent event = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent.EVENT_TYPE_GROUP_LOCK_CHANGED); event.valueInt1 = groupId; event.valueInt2 = status; event.valueBool1 = locked; @@ -204,8 +199,9 @@ public class CsipSetCoordinatorNativeInterface { /** * Set lock on the group. - * @param groupId group identifier - * @param lock True for lock, false for unlock + * + * @param groupId group identifier + * @param lock True for lock, false for unlock */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void groupLockSet(int groupId, boolean lock) { @@ -214,8 +210,12 @@ public class CsipSetCoordinatorNativeInterface { // Native methods that call into the JNI interface private native void initNative(); + private native void cleanupNative(); + private native boolean connectNative(byte[] address); + private native boolean disconnectNative(byte[] address); + private native void groupLockSetNative(int groupId, boolean lock); } diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java index 505e41f1154..2f80da61988 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java @@ -66,9 +66,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.stream.Collectors; -/** - * Provides Bluetooth CSIP Set Coordinator profile, as a service. - */ +/** Provides Bluetooth CSIP Set Coordinator profile, as a service. */ public class CsipSetCoordinatorService extends ProfileService { private static final String TAG = "CsipSetCoordinatorService"; @@ -127,14 +125,19 @@ public class CsipSetCoordinatorService extends ProfileService { // Get AdapterService, DatabaseManager, CsipSetCoordinatorNativeInterface. // None of them can be null. - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when CsipSetCoordinatorService starts"); - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when CsipSetCoordinatorService starts"); - mCsipSetCoordinatorNativeInterface = Objects.requireNonNull( - CsipSetCoordinatorNativeInterface.getInstance(), - "CsipSetCoordinatorNativeInterface cannot be null when" - .concat("CsipSetCoordinatorService starts")); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when CsipSetCoordinatorService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when CsipSetCoordinatorService starts"); + mCsipSetCoordinatorNativeInterface = + Objects.requireNonNull( + CsipSetCoordinatorNativeInterface.getInstance(), + "CsipSetCoordinatorNativeInterface cannot be null when" + .concat("CsipSetCoordinatorService starts")); // Setup Handler. mHandler = new Handler(Looper.getMainLooper()); @@ -220,6 +223,7 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Get the CsipSetCoordinatorService instance + * * @return CsipSetCoordinatorService instance */ public static synchronized CsipSetCoordinatorService getCsipSetCoordinatorService() { @@ -311,8 +315,8 @@ public class CsipSetCoordinatorService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -373,10 +377,10 @@ public class CsipSetCoordinatorService extends ProfileService { } } - /** - * Register for CSIS - */ - public void registerCsisMemberObserver(@CallbackExecutor Executor executor, ParcelUuid uuid, + /** Register for CSIS */ + public void registerCsisMemberObserver( + @CallbackExecutor Executor executor, + ParcelUuid uuid, IBluetoothCsipSetCoordinatorCallback callback) { Map entries = mCallbacks.getOrDefault(uuid, null); @@ -419,10 +423,10 @@ public class CsipSetCoordinatorService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission"); @@ -436,15 +440,14 @@ public class CsipSetCoordinatorService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device the remote device * @param connectionPolicy is the connection policy to set to for this profile @@ -479,6 +482,7 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Lock a given group. + * * @param groupId group ID to lock * @param callback callback with the lock request result * @return unique lock identifier used for unlocking @@ -493,9 +497,8 @@ public class CsipSetCoordinatorService extends ProfileService { synchronized (mGroupIdToUuidMap) { if (!mGroupIdToUuidMap.containsKey(groupId)) { try { - callback.onGroupLockSet(groupId, - BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID, - false); + callback.onGroupLockSet( + groupId, BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID, false); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -507,9 +510,8 @@ public class CsipSetCoordinatorService extends ProfileService { synchronized (mLocks) { if (mLocks.containsKey(groupId)) { try { - callback.onGroupLockSet(groupId, - BluetoothStatusCodes.ERROR_CSIP_GROUP_LOCKED_BY_OTHER, - true); + callback.onGroupLockSet( + groupId, BluetoothStatusCodes.ERROR_CSIP_GROUP_LOCKED_BY_OTHER, true); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -527,6 +529,7 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Unlock a given group. + * * @param lockUuid unique lock identifier used for unlocking */ public void unlockGroup(@NonNull UUID lockUuid) { @@ -550,6 +553,7 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Check whether a given group is currently locked. + * * @param groupId unique group identifier * @return true if group is currently locked, otherwise false. */ @@ -559,12 +563,12 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Get collection of group IDs for a given UUID + * * @param uuid profile context UUID * @return list of group IDs */ public List getAllGroupIds(ParcelUuid uuid) { - return mGroupIdToUuidMap.entrySet() - .stream() + return mGroupIdToUuidMap.entrySet().stream() .filter(e -> uuid.equals(e.getValue())) .map(Map.Entry::getKey) .collect(Collectors.toList()); @@ -572,6 +576,7 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Get group ID for a given device and UUID + * * @param device potential group member * @param uuid profile context UUID * @return group ID @@ -579,10 +584,8 @@ public class CsipSetCoordinatorService extends ProfileService { public Integer getGroupId(BluetoothDevice device, ParcelUuid uuid) { Map device_groups = mDeviceGroupIdRankMap.getOrDefault(device, new HashMap<>()); - return mGroupIdToUuidMap.entrySet() - .stream() - .filter(e -> (device_groups.containsKey(e.getKey()) - && e.getValue().equals(uuid))) + return mGroupIdToUuidMap.entrySet().stream() + .filter(e -> (device_groups.containsKey(e.getKey()) && e.getValue().equals(uuid))) .map(Map.Entry::getKey) .findFirst() .orElse(IBluetoothCsipSetCoordinator.CSIS_GROUP_ID_INVALID); @@ -590,20 +593,21 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Get device's groups/ + * * @param device group member device * @return map of group id and related uuids. */ public Map getGroupUuidMapByDevice(BluetoothDevice device) { Map device_groups = mDeviceGroupIdRankMap.getOrDefault(device, new HashMap<>()); - return mGroupIdToUuidMap.entrySet() - .stream() + return mGroupIdToUuidMap.entrySet().stream() .filter(e -> device_groups.containsKey(e.getKey())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } /** * Get grouped devices + * * @param groupId group ID * @return related list of devices sorted from the lowest to the highest rank value. */ @@ -618,8 +622,7 @@ public class CsipSetCoordinatorService extends ProfileService { } // Return device list sorted by descending rank order - return deviceRankMap.entrySet() - .stream() + return deviceRankMap.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .map(e -> e.getKey()) .collect(Collectors.toList()); @@ -627,12 +630,13 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Get grouped devices + * * @param device group member device * @param uuid profile context UUID * @return related list of devices sorted from the lowest to the highest rank value. */ - public @NonNull List getGroupDevicesOrdered(BluetoothDevice device, - ParcelUuid uuid) { + public @NonNull List getGroupDevicesOrdered( + BluetoothDevice device, ParcelUuid uuid) { List groupIds = getAllGroupIds(uuid); for (Integer id : groupIds) { List devices = getGroupDevicesOrdered(id); @@ -645,16 +649,17 @@ public class CsipSetCoordinatorService extends ProfileService { /** * Get group desired size + * * @param groupId group ID * @return the number of group members */ public int getDesiredGroupSize(int groupId) { - return mGroupIdToGroupSize.getOrDefault(groupId, - IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN); + return mGroupIdToGroupSize.getOrDefault( + groupId, IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN); } - private void handleDeviceAvailable(BluetoothDevice device, int groupId, int rank, UUID uuid, - int groupSize) { + private void handleDeviceAvailable( + BluetoothDevice device, int groupId, int rank, UUID uuid, int groupSize) { mGroupIdToGroupSize.put(groupId, groupSize); ParcelUuid parcel_uuid = new ParcelUuid(uuid); if (!getAllGroupIds(parcel_uuid).contains(groupId)) { @@ -672,6 +677,7 @@ public class CsipSetCoordinatorService extends ProfileService { /** * If all the group devices are now available, make sure CSIP connection policy mirrors the LEA * connection policy. + * * @param groupId is the group that has a new device available */ private void disableCsipIfNeeded(int groupId) { @@ -691,17 +697,26 @@ public class CsipSetCoordinatorService extends ProfileService { return; } if (mGroupIdToConnectedDevices.get(groupId).size() < mGroupIdToGroupSize.get(groupId)) { - Log.d(TAG, "disableCsipIfNeeded: groupId " + groupId + "has " - + mGroupIdToConnectedDevices.get(groupId).size() + " connected devices out" - + " of a group size of " + mGroupIdToGroupSize.get(groupId)); + Log.d( + TAG, + "disableCsipIfNeeded: groupId " + + groupId + + "has " + + mGroupIdToConnectedDevices.get(groupId).size() + + " connected devices out" + + " of a group size of " + + mGroupIdToGroupSize.get(groupId)); return; } for (BluetoothDevice groupDevice : mGroupIdToConnectedDevices.get(groupId)) { if (mLeAudioService.getConnectionPolicy(groupDevice) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - Log.i(TAG, "Setting CSIP connection policy to FORBIDDEN for device " - + groupDevice + " after all group devices bonded because LEA " - + "connection policy is FORBIDDEN"); + Log.i( + TAG, + "Setting CSIP connection policy to FORBIDDEN for device " + + groupDevice + + " after all group devices bonded because LEA " + + "connection policy is FORBIDDEN"); setConnectionPolicy(groupDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); } } @@ -710,15 +725,20 @@ public class CsipSetCoordinatorService extends ProfileService { } } - private void executeCallback(Executor exec, IBluetoothCsipSetCoordinatorCallback callback, - BluetoothDevice device, int groupId) throws RemoteException { - exec.execute(() -> { - try { - callback.onCsisSetMemberAvailable(device, groupId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - }); + private void executeCallback( + Executor exec, + IBluetoothCsipSetCoordinatorCallback callback, + BluetoothDevice device, + int groupId) + throws RemoteException { + exec.execute( + () -> { + try { + callback.onCsisSetMemberAvailable(device, groupId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + }); } private void handleSetMemberAvailable(BluetoothDevice device, int groupId) { @@ -821,7 +841,11 @@ public class CsipSetCoordinatorService extends ProfileService { intent.putExtra( BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_TYPE_UUID, stackEvent.valueUuid1); - handleDeviceAvailable(device, groupId, stackEvent.valueInt3, stackEvent.valueUuid1, + handleDeviceAvailable( + device, + groupId, + stackEvent.valueInt3, + stackEvent.valueUuid1, stackEvent.valueInt2); } else if (stackEvent.type == CsipSetCoordinatorStackEvent.EVENT_TYPE_SET_MEMBER_AVAILABLE) { @@ -839,8 +863,9 @@ public class CsipSetCoordinatorService extends ProfileService { } if (intent != null) { - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendOrderedBroadcast(intent, BLUETOOTH_PRIVILEGED); } @@ -881,14 +906,19 @@ public class CsipSetCoordinatorService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_CSIS_STATE_MACHINES) { - Log.e(TAG, + Log.e( + TAG, "Maximum number of CSIS state machines reached: " + MAX_CSIS_STATE_MACHINES); return null; } Log.d(TAG, "Creating a new state machine for " + device); - sm = CsipSetCoordinatorStateMachine.make(device, this, - mCsipSetCoordinatorNativeInterface, mStateMachinesThread.getLooper()); + sm = + CsipSetCoordinatorStateMachine.make( + device, + this, + mCsipSetCoordinatorNativeInterface, + mStateMachinesThread.getLooper()); mStateMachines.put(device, sm); return sm; } @@ -921,7 +951,7 @@ public class CsipSetCoordinatorService extends ProfileService { } mDeviceGroupIdRankMap.remove(device); - for (Map.Entry> entry: + for (Map.Entry> entry : mGroupIdToConnectedDevices.entrySet()) { entry.getValue().remove(device); } @@ -944,7 +974,8 @@ public class CsipSetCoordinatorService extends ProfileService { synchronized (mStateMachines) { CsipSetCoordinatorStateMachine sm = mStateMachines.get(device); if (sm == null) { - Log.w(TAG, + Log.w( + TAG, "removeStateMachine: device " + device + " does not have a state machine"); return; } @@ -967,9 +998,14 @@ public class CsipSetCoordinatorService extends ProfileService { } if ((device == null) || (fromState == toState)) { - Log.e(TAG, - "connectionStateChanged: unexpected invocation. device=" + device - + " fromState=" + fromState + " toState=" + toState); + Log.e( + TAG, + "connectionStateChanged: unexpected invocation. device=" + + device + + " fromState=" + + fromState + + " toState=" + + toState); return; } @@ -997,12 +1033,10 @@ public class CsipSetCoordinatorService extends ProfileService { BluetoothProfile.CSIP_SET_COORDINATOR, device, fromState, toState); } - /** - * Binder object: must be a static class or memory leak may occur - */ + /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting - static class BluetoothCsisBinder - extends IBluetoothCsipSetCoordinator.Stub implements IProfileServiceBinder { + static class BluetoothCsisBinder extends IBluetoothCsipSetCoordinator.Stub + implements IProfileServiceBinder { private CsipSetCoordinatorService mService; private CsipSetCoordinatorService getService() { @@ -1204,8 +1238,7 @@ public class CsipSetCoordinatorService extends ProfileService { ProfileService.println(sb, "mFoundSetMemberToGroupId: "); for (Map.Entry entry : mFoundSetMemberToGroupId.entrySet()) { ProfileService.println( - sb, - " member device: " + entry.getKey() + ", group ID: " + entry.getValue()); + sb, " member device: " + entry.getKey() + ", group ID: " + entry.getValue()); } } } diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStackEvent.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStackEvent.java index 1e2a355d601..ca34bbd3fd5 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStackEvent.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStackEvent.java @@ -21,9 +21,7 @@ import android.bluetooth.BluetoothDevice; import java.util.UUID; -/** - * CSIP Set Coordinator role stack event - */ +/** CSIP Set Coordinator role stack event */ public class CsipSetCoordinatorStackEvent { // Event types for STACK_EVENT message (coming from native) private static final int EVENT_TYPE_NONE = 0; diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachine.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachine.java index 1013d17851f..3a7d62745cc 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachine.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachine.java @@ -37,9 +37,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Scanner; -/** - * CSIP Set Coordinator role device state machine - */ +/** CSIP Set Coordinator role device state machine */ public class CsipSetCoordinatorStateMachine extends StateMachine { private static final String TAG = "CsipSetCoordinatorStateMachine"; @@ -62,8 +60,11 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { private final BluetoothDevice mDevice; - CsipSetCoordinatorStateMachine(BluetoothDevice device, CsipSetCoordinatorService svc, - CsipSetCoordinatorNativeInterface nativeInterface, Looper looper) { + CsipSetCoordinatorStateMachine( + BluetoothDevice device, + CsipSetCoordinatorService svc, + CsipSetCoordinatorNativeInterface nativeInterface, + Looper looper) { super(TAG, looper); mDevice = device; mService = svc; @@ -82,8 +83,10 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { setInitialState(mDisconnected); } - static CsipSetCoordinatorStateMachine make(BluetoothDevice device, - CsipSetCoordinatorService svc, CsipSetCoordinatorNativeInterface nativeInterface, + static CsipSetCoordinatorStateMachine make( + BluetoothDevice device, + CsipSetCoordinatorService svc, + CsipSetCoordinatorNativeInterface nativeInterface, Looper looper) { Log.i(TAG, "make for device " + device); CsipSetCoordinatorStateMachine CsisSm = @@ -92,17 +95,13 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { return CsisSm; } - /** - * Quit state machine execution - */ + /** Quit state machine execution */ public void doQuit() { log("doQuit for device " + mDevice); quitNow(); } - /** - * Clean up - */ + /** Clean up */ public void cleanup() { log("cleanup for device " + mDevice); } @@ -111,9 +110,12 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - Log.i(TAG, - "Enter Disconnected(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(DISCONNECT); @@ -124,15 +126,21 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { @Override public void exit() { - log("Exit Disconnected(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected process message(" + mDevice - + "): " + messageWhatToString(message.what)); + log( + "Disconnected process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -145,7 +153,8 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { transitionTo(mConnecting); } else { // Reject the request and stay in Disconnected state - Log.w(TAG, + Log.w( + TAG, "Outgoing CsipSetCoordinator Connecting request rejected: " + mDevice); } @@ -182,13 +191,15 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { break; case CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTING: if (mService.okToConnect(mDevice)) { - Log.i(TAG, + Log.i( + TAG, "Incoming CsipSetCoordinator Connecting request accepted: " + mDevice); transitionTo(mConnecting); } else { // Reject the connection and stay in Disconnected state itself - Log.w(TAG, + Log.w( + TAG, "Incoming CsipSetCoordinator Connecting request rejected: " + mDevice); mNativeInterface.disconnect(mDevice); @@ -197,13 +208,15 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { case CsipSetCoordinatorStackEvent.CONNECTION_STATE_CONNECTED: Log.w(TAG, "CsipSetCoordinator Connected from Disconnected state: " + mDevice); if (mService.okToConnect(mDevice)) { - Log.i(TAG, + Log.i( + TAG, "Incoming CsipSetCoordinator Connected request accepted: " + mDevice); transitionTo(mConnected); } else { // Reject the connection and stay in Disconnected state itself - Log.w(TAG, + Log.w( + TAG, "Incoming CsipSetCoordinator Connected request rejected: " + mDevice); mNativeInterface.disconnect(mDevice); @@ -223,25 +236,34 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { class Connecting extends State { @Override public void enter() { - Log.i(TAG, - "Enter Connecting(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); csipConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState); } @Override public void exit() { - log("Exit Connecting(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting process message(" + mDevice - + "): " + messageWhatToString(message.what)); + log( + "Connecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -250,8 +272,10 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { case CONNECT_TIMEOUT: Log.w(TAG, "Connecting connection timeout: " + mDevice); mNativeInterface.disconnect(mDevice); - CsipSetCoordinatorStackEvent disconnectEvent = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + CsipSetCoordinatorStackEvent disconnectEvent = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent + .EVENT_TYPE_CONNECTION_STATE_CHANGED); disconnectEvent.device = mDevice; disconnectEvent.valueInt1 = CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTED; @@ -310,41 +334,53 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { class Disconnecting extends State { @Override public void enter() { - Log.i(TAG, - "Enter Disconnecting(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); csipConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState); } @Override public void exit() { - log("Exit Disconnecting(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Disconnecting process message(" + mDevice - + "): " + messageWhatToString(message.what)); + log( + "Disconnecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Disconnecting connection timeout: " + mDevice); - mNativeInterface.disconnect(mDevice); - CsipSetCoordinatorStackEvent disconnectEvent = new CsipSetCoordinatorStackEvent( - CsipSetCoordinatorStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - disconnectEvent.device = mDevice; - disconnectEvent.valueInt1 = - CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, disconnectEvent); - break; - } + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Disconnecting connection timeout: " + mDevice); + mNativeInterface.disconnect(mDevice); + CsipSetCoordinatorStackEvent disconnectEvent = + new CsipSetCoordinatorStackEvent( + CsipSetCoordinatorStackEvent + .EVENT_TYPE_CONNECTION_STATE_CHANGED); + disconnectEvent.device = mDevice; + disconnectEvent.valueInt1 = + CsipSetCoordinatorStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, disconnectEvent); + break; + } case DISCONNECT: deferMessage(message); break; @@ -382,7 +418,8 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { transitionTo(mConnected); } else { // Reject the connection and stay in Disconnecting state - Log.w(TAG, + Log.w( + TAG, "Incoming CsipSetCoordinator Connected request rejected: " + mDevice); mNativeInterface.disconnect(mDevice); @@ -394,7 +431,8 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { transitionTo(mConnecting); } else { // Reject the connection and stay in Disconnecting state - Log.w(TAG, + Log.w( + TAG, "Incoming CsipSetCoordinator Connecting request rejected: " + mDevice); mNativeInterface.disconnect(mDevice); @@ -413,17 +451,23 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - Log.i(TAG, - "Enter Connected(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(CONNECT); csipConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState); } @Override public void exit() { - log("Exit Connected(" + mDevice - + "): " + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @@ -511,8 +555,13 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { // This method does not check for error condition (newState == prevState) private void csipConnectionState(int newState, int prevState) { - log("Connection state " + mDevice + ": " + profileStateToString(prevState) + "->" - + profileStateToString(newState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(prevState) + + "->" + + profileStateToString(newState)); mService.handleConnectionStateChanged(mDevice, prevState, newState); Intent intent = @@ -520,8 +569,9 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mService.sendBroadcast(intent, BLUETOOTH_CONNECT); } @@ -557,9 +607,7 @@ public class CsipSetCoordinatorStateMachine extends StateMachine { return Integer.toString(state); } - /** - * Dump the state machine logs - */ + /** Dump the state machine logs */ public void dump(StringBuilder sb) { ProfileService.println(sb, "mDevice: " + mDevice); ProfileService.println(sb, " StateMachine: " + this); diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java index 486397b34c9..cd99fb87fba 100644 --- a/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java +++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java @@ -178,7 +178,6 @@ class AdvertiseHelper { } } - if (data.getServiceSolicitationUuids() != null) { ByteArrayOutputStream serviceUuids16 = new ByteArrayOutputStream(); ByteArrayOutputStream serviceUuids32 = new ByteArrayOutputStream(); @@ -220,8 +219,7 @@ class AdvertiseHelper { for (TransportDiscoveryData transportDiscoveryData : data.getTransportDiscoveryData()) { ret.write(transportDiscoveryData.totalBytes()); - ret.write(transportDiscoveryData.toByteArray(), - 0, transportDiscoveryData.totalBytes()); + ret.write(transportDiscoveryData.toByteArray(), 0, transportDiscoveryData.totalBytes()); } return ret.toByteArray(); } @@ -239,4 +237,3 @@ class AdvertiseHelper { } } } - diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java index 9efbd1b00a2..1c563728671 100644 --- a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java +++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java @@ -95,7 +95,9 @@ public class AdvertiseManager { public AdvertisingSetDeathRecipient deathRecipient; public IAdvertisingSetCallback callback; - AdvertiserInfo(Integer id, AdvertisingSetDeathRecipient deathRecipient, + AdvertiserInfo( + Integer id, + AdvertisingSetDeathRecipient deathRecipient, IAdvertisingSetCallback callback) { this.id = id; this.deathRecipient = deathRecipient; @@ -118,9 +120,7 @@ public class AdvertiseManager { @Override public void binderDied() { - Log.d( - TAG, - "Binder is dead - unregistering advertising set (" + mPackageName + ")!"); + Log.d(TAG, "Binder is dead - unregistering advertising set (" + mPackageName + ")!"); stopAdvertisingSet(callback); } } @@ -138,9 +138,14 @@ public class AdvertiseManager { void onAdvertisingSetStarted(int regId, int advertiserId, int txPower, int status) throws Exception { - Log.d(TAG, - "onAdvertisingSetStarted() - regId=" + regId + ", advertiserId=" + advertiserId - + ", status=" + status); + Log.d( + TAG, + "onAdvertisingSetStarted() - regId=" + + regId + + ", advertiserId=" + + advertiserId + + ", status=" + + status); Map.Entry entry = findAdvertiser(regId); @@ -175,13 +180,21 @@ public class AdvertiseManager { } void onAdvertisingEnabled(int advertiserId, boolean enable, int status) throws Exception { - Log.d(TAG, "onAdvertisingSetEnabled() - advertiserId=" + advertiserId + ", enable=" - + enable + ", status=" + status); + Log.d( + TAG, + "onAdvertisingSetEnabled() - advertiserId=" + + advertiserId + + ", enable=" + + enable + + ", status=" + + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { - Log.i(TAG, "onAdvertisingSetEnable() - no callback found for advertiserId " - + advertiserId); + Log.i( + TAG, + "onAdvertisingSetEnable() - no callback found for advertiserId " + + advertiserId); return; } @@ -196,9 +209,15 @@ public class AdvertiseManager { } } - void startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData, - AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters, - AdvertiseData periodicData, int duration, int maxExtAdvEvents, int serverIf, + void startAdvertisingSet( + AdvertisingSetParameters parameters, + AdvertiseData advertiseData, + AdvertiseData scanResponse, + PeriodicAdvertisingParameters periodicParameters, + AdvertiseData periodicData, + int duration, + int maxExtAdvEvents, + int serverIf, IAdvertisingSetCallback callback) { // If we are using an isolated server, force usage of an NRPA if (serverIf != 0 @@ -246,8 +265,15 @@ public class AdvertiseManager { Log.d(TAG, "startAdvertisingSet() - reg_id=" + cbId + ", callback: " + binder); mAdvertiserMap.add(cbId, callback, mService); - mAdvertiserMap.recordAdvertiseStart(cbId, parameters, advertiseData, - scanResponse, periodicParameters, periodicData, duration, maxExtAdvEvents); + mAdvertiserMap.recordAdvertiseStart( + cbId, + parameters, + advertiseData, + scanResponse, + periodicParameters, + periodicData, + duration, + maxExtAdvEvents); mNativeInterface.startAdvertisingSet( parameters, @@ -333,8 +359,7 @@ public class AdvertiseManager { } mNativeInterface.enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents); - mAdvertiserMap.enableAdvertisingSet(advertiserId, - enable, duration, maxExtAdvEvents); + mAdvertiserMap.enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents); } void setAdvertisingData(int advertiserId, AdvertiseData data) { @@ -351,8 +376,8 @@ public class AdvertiseManager { mAdvertiserMap.setAdvertisingData(advertiserId, data); } catch (IllegalArgumentException e) { try { - onAdvertisingDataSet(advertiserId, - AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); + onAdvertisingDataSet( + advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } @@ -373,8 +398,8 @@ public class AdvertiseManager { mAdvertiserMap.setScanResponseData(advertiserId, data); } catch (IllegalArgumentException e) { try { - onScanResponseDataSet(advertiserId, - AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); + onScanResponseDataSet( + advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } @@ -392,8 +417,8 @@ public class AdvertiseManager { mAdvertiserMap.setAdvertisingParameters(advertiserId, parameters); } - void setPeriodicAdvertisingParameters(int advertiserId, - PeriodicAdvertisingParameters parameters) { + void setPeriodicAdvertisingParameters( + int advertiserId, PeriodicAdvertisingParameters parameters) { Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { Log.w(TAG, "setPeriodicAdvertisingParameters() - bad advertiserId " + advertiserId); @@ -418,8 +443,8 @@ public class AdvertiseManager { mAdvertiserMap.setPeriodicAdvertisingData(advertiserId, data); } catch (IllegalArgumentException e) { try { - onPeriodicAdvertisingDataSet(advertiserId, - AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); + onPeriodicAdvertisingDataSet( + advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } @@ -436,8 +461,7 @@ public class AdvertiseManager { } void onAdvertisingDataSet(int advertiserId, int status) throws Exception { - Log.d(TAG, - "onAdvertisingDataSet() advertiserId=" + advertiserId + ", status=" + status); + Log.d(TAG, "onAdvertisingDataSet() advertiserId=" + advertiserId + ", status=" + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { @@ -450,8 +474,7 @@ public class AdvertiseManager { } void onScanResponseDataSet(int advertiserId, int status) throws Exception { - Log.d(TAG, - "onScanResponseDataSet() advertiserId=" + advertiserId + ", status=" + status); + Log.d(TAG, "onScanResponseDataSet() advertiserId=" + advertiserId + ", status=" + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { @@ -465,9 +488,14 @@ public class AdvertiseManager { void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status) throws Exception { - Log.d(TAG, - "onAdvertisingParametersUpdated() advertiserId=" + advertiserId + ", txPower=" - + txPower + ", status=" + status); + Log.d( + TAG, + "onAdvertisingParametersUpdated() advertiserId=" + + advertiserId + + ", txPower=" + + txPower + + ", status=" + + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { @@ -480,12 +508,17 @@ public class AdvertiseManager { } void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) throws Exception { - Log.d(TAG, "onPeriodicAdvertisingParametersUpdated() advertiserId=" + advertiserId - + ", status=" + status); + Log.d( + TAG, + "onPeriodicAdvertisingParametersUpdated() advertiserId=" + + advertiserId + + ", status=" + + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { - Log.i(TAG, + Log.i( + TAG, "onPeriodicAdvertisingParametersUpdated() - bad advertiserId " + advertiserId); return; } @@ -495,8 +528,12 @@ public class AdvertiseManager { } void onPeriodicAdvertisingDataSet(int advertiserId, int status) throws Exception { - Log.d(TAG, "onPeriodicAdvertisingDataSet() advertiserId=" + advertiserId + ", status=" - + status); + Log.d( + TAG, + "onPeriodicAdvertisingDataSet() advertiserId=" + + advertiserId + + ", status=" + + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { @@ -510,8 +547,12 @@ public class AdvertiseManager { void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status) throws Exception { - Log.d(TAG, "onPeriodicAdvertisingEnabled() advertiserId=" + advertiserId + ", status=" - + status); + Log.d( + TAG, + "onPeriodicAdvertisingEnabled() advertiserId=" + + advertiserId + + ", status=" + + status); Map.Entry entry = findAdvertiser(advertiserId); if (entry == null) { diff --git a/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java b/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java index 1328dd3a191..8d22ef9d630 100644 --- a/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java +++ b/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java @@ -35,16 +35,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -/** - * ScanStats class helps keep track of information about scans - * on a per application basis. - */ +/** ScanStats class helps keep track of information about scans on a per application basis. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public class AppAdvertiseStats { private static final String TAG = AppAdvertiseStats.class.getSimpleName(); - private static DateTimeFormatter sDateFormat = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss") - .withZone(ZoneId.systemDefault()); + private static DateTimeFormatter sDateFormat = + DateTimeFormatter.ofPattern("MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()); static final String[] PHY_LE_STRINGS = {"LE_1M", "LE_2M", "LE_CODED"}; static final int UUID_STRING_FILTER_LEN = 8; @@ -61,8 +58,12 @@ public class AppAdvertiseStats { public SparseArray manufacturerData; public Map serviceData; public List serviceUuids; - AppAdvertiserData(boolean includeDeviceName, boolean includeTxPowerLevel, - SparseArray manufacturerData, Map serviceData, + + AppAdvertiserData( + boolean includeDeviceName, + boolean includeTxPowerLevel, + SparseArray manufacturerData, + Map serviceData, List serviceUuids) { this.includeDeviceName = includeDeviceName; this.includeTxPowerLevel = includeTxPowerLevel; @@ -77,6 +78,7 @@ public class AppAdvertiseStats { public Instant stopTime = null; public int duration = 0; public int maxExtendedAdvertisingEvents = 0; + AppAdvertiserRecord(Instant startTime) { this.startTime = startTime; } @@ -99,8 +101,7 @@ public class AppAdvertiseStats { private AppAdvertiserData mPeriodicAdvertisingData = null; private boolean mPeriodicIncludeTxPower = false; private int mPeriodicInterval = 0; - public ArrayList mAdvertiserRecords = - new ArrayList(); + public ArrayList mAdvertiserRecords = new ArrayList(); @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public AppAdvertiseStats(int id, String name, ContextMap map, GattService service) { @@ -110,10 +111,14 @@ public class AppAdvertiseStats { this.mGattService = service; } - void recordAdvertiseStart(AdvertisingSetParameters parameters, - AdvertiseData advertiseData, AdvertiseData scanResponse, - PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData, - int duration, int maxExtAdvEvents) { + void recordAdvertiseStart( + AdvertisingSetParameters parameters, + AdvertiseData advertiseData, + AdvertiseData scanResponse, + PeriodicAdvertisingParameters periodicParameters, + AdvertiseData periodicData, + int duration, + int maxExtAdvEvents) { mAdvertisingEnabled = true; AppAdvertiserRecord record = new AppAdvertiserRecord(Instant.now()); record.duration = duration; @@ -135,28 +140,33 @@ public class AppAdvertiseStats { } if (advertiseData != null) { - mAdvertisingData = new AppAdvertiserData(advertiseData.getIncludeDeviceName(), - advertiseData.getIncludeTxPowerLevel(), - advertiseData.getManufacturerSpecificData(), - advertiseData.getServiceData(), - advertiseData.getServiceUuids()); + mAdvertisingData = + new AppAdvertiserData( + advertiseData.getIncludeDeviceName(), + advertiseData.getIncludeTxPowerLevel(), + advertiseData.getManufacturerSpecificData(), + advertiseData.getServiceData(), + advertiseData.getServiceUuids()); } if (scanResponse != null) { - mScanResponseData = new AppAdvertiserData(scanResponse.getIncludeDeviceName(), - scanResponse.getIncludeTxPowerLevel(), - scanResponse.getManufacturerSpecificData(), - scanResponse.getServiceData(), - scanResponse.getServiceUuids()); + mScanResponseData = + new AppAdvertiserData( + scanResponse.getIncludeDeviceName(), + scanResponse.getIncludeTxPowerLevel(), + scanResponse.getManufacturerSpecificData(), + scanResponse.getServiceData(), + scanResponse.getServiceUuids()); } if (periodicData != null) { - mPeriodicAdvertisingData = new AppAdvertiserData( - periodicData.getIncludeDeviceName(), - periodicData.getIncludeTxPowerLevel(), - periodicData.getManufacturerSpecificData(), - periodicData.getServiceData(), - periodicData.getServiceUuids()); + mPeriodicAdvertisingData = + new AppAdvertiserData( + periodicData.getIncludeDeviceName(), + periodicData.getIncludeTxPowerLevel(), + periodicData.getManufacturerSpecificData(), + periodicData.getServiceData(), + periodicData.getServiceUuids()); } if (periodicParameters != null) { @@ -191,8 +201,8 @@ public class AppAdvertiseStats { } else if (instanceCount < 15) { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_INSTANCE_COUNT_15, 1); } else { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_INSTANCE_COUNT_15P, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_INSTANCE_COUNT_15P, 1); } } @@ -205,12 +215,12 @@ public class AppAdvertiseStats { void enableAdvertisingSet(boolean enable, int duration, int maxExtAdvEvents) { if (enable) { - //if the advertisingSet have not been disabled, skip enabling. + // if the advertisingSet have not been disabled, skip enabling. if (!mAdvertisingEnabled) { recordAdvertiseStart(duration, maxExtAdvEvents); } } else { - //if the advertisingSet have not been enabled, skip disabling. + // if the advertisingSet have not been enabled, skip disabling. if (mAdvertisingEnabled) { recordAdvertiseStop(); } @@ -219,11 +229,13 @@ public class AppAdvertiseStats { void setAdvertisingData(AdvertiseData data) { if (mAdvertisingData == null) { - mAdvertisingData = new AppAdvertiserData(data.getIncludeDeviceName(), - data.getIncludeTxPowerLevel(), - data.getManufacturerSpecificData(), - data.getServiceData(), - data.getServiceUuids()); + mAdvertisingData = + new AppAdvertiserData( + data.getIncludeDeviceName(), + data.getIncludeTxPowerLevel(), + data.getManufacturerSpecificData(), + data.getServiceData(), + data.getServiceUuids()); } else if (data != null) { mAdvertisingData.includeDeviceName = data.getIncludeDeviceName(); mAdvertisingData.includeTxPowerLevel = data.getIncludeTxPowerLevel(); @@ -235,11 +247,13 @@ public class AppAdvertiseStats { void setScanResponseData(AdvertiseData data) { if (mScanResponseData == null) { - mScanResponseData = new AppAdvertiserData(data.getIncludeDeviceName(), - data.getIncludeTxPowerLevel(), - data.getManufacturerSpecificData(), - data.getServiceData(), - data.getServiceUuids()); + mScanResponseData = + new AppAdvertiserData( + data.getIncludeDeviceName(), + data.getIncludeTxPowerLevel(), + data.getManufacturerSpecificData(), + data.getServiceData(), + data.getServiceUuids()); } else if (data != null) { mScanResponseData.includeDeviceName = data.getIncludeDeviceName(); mScanResponseData.includeTxPowerLevel = data.getIncludeTxPowerLevel(); @@ -271,11 +285,13 @@ public class AppAdvertiseStats { void setPeriodicAdvertisingData(AdvertiseData data) { if (mPeriodicAdvertisingData == null) { - mPeriodicAdvertisingData = new AppAdvertiserData(data.getIncludeDeviceName(), - data.getIncludeTxPowerLevel(), - data.getManufacturerSpecificData(), - data.getServiceData(), - data.getServiceUuids()); + mPeriodicAdvertisingData = + new AppAdvertiserData( + data.getIncludeDeviceName(), + data.getIncludeTxPowerLevel(), + data.getManufacturerSpecificData(), + data.getServiceData(), + data.getServiceUuids()); } else if (data != null) { mPeriodicAdvertisingData.includeDeviceName = data.getIncludeDeviceName(); mPeriodicAdvertisingData.includeTxPowerLevel = data.getIncludeTxPowerLevel(); @@ -293,115 +309,122 @@ public class AppAdvertiseStats { this.mId = id; } - private static void recordAdvertiseDurationCount(Duration duration, boolean isConnectable, - boolean inPeriodic) { + private static void recordAdvertiseDurationCount( + Duration duration, boolean isConnectable, boolean inPeriodic) { if (duration.compareTo(Duration.ofMinutes(1)) < 0) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_1M, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_1M, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_1M, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_1M, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_1M, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_1M, 1); } } else if (duration.compareTo(Duration.ofMinutes(30)) < 0) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_30M, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_30M, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_30M, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_30M, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_30M, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_30M, 1); } } else if (duration.compareTo(Duration.ofHours(1)) < 0) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_1H, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_1H, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_1H, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_1H, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_1H, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_1H, 1); } } else if (duration.compareTo(Duration.ofHours(3)) < 0) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_3H, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_3H, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_3H, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_3H, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_3H, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_3H, 1); } } else { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_3HP, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_TOTAL_3HP, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_3HP, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_CONNECTABLE_3HP, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_3HP, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_DURATION_COUNT_PERIODIC_3HP, 1); } } } - private static void recordAdvertiseEnableCount(boolean enable, boolean isConnectable, - boolean inPeriodic) { + private static void recordAdvertiseEnableCount( + boolean enable, boolean isConnectable, boolean inPeriodic) { if (enable) { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_ENABLE, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_ENABLE, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_ENABLE, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_ENABLE, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_ENABLE, 1); } } else { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_DISABLE, 1); if (isConnectable) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_DISABLE, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_DISABLE, 1); } if (inPeriodic) { - MetricsLogger.getInstance().cacheCount( - BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_DISABLE, 1); + MetricsLogger.getInstance() + .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_DISABLE, 1); } } } private static void dumpAppAdvertiserData(StringBuilder sb, AppAdvertiserData advData) { - sb.append("\n └Include Device Name : " - + advData.includeDeviceName); - sb.append("\n └Include Tx Power Level : " - + advData.includeTxPowerLevel); + sb.append( + "\n └Include Device Name : " + + advData.includeDeviceName); + sb.append( + "\n └Include Tx Power Level : " + + advData.includeTxPowerLevel); if (advData.manufacturerData.size() > 0) { - sb.append("\n └Manufacturer Data (length of data) : " - + advData.manufacturerData.size()); + sb.append( + "\n └Manufacturer Data (length of data) : " + + advData.manufacturerData.size()); } if (!advData.serviceData.isEmpty()) { sb.append("\n └Service Data(UUID, length of data) : "); for (ParcelUuid uuid : advData.serviceData.keySet()) { - sb.append("\n [" + uuid.toString().substring(0, UUID_STRING_FILTER_LEN) - + "-xxxx-xxxx-xxxx-xxxxxxxxxxxx, " - + advData.serviceData.get(uuid).length + "]"); + sb.append( + "\n [" + + uuid.toString().substring(0, UUID_STRING_FILTER_LEN) + + "-xxxx-xxxx-xxxx-xxxxxxxxxxxx, " + + advData.serviceData.get(uuid).length + + "]"); } } if (!advData.serviceUuids.isEmpty()) { - sb.append("\n └Service Uuids : \n " - + advData.serviceUuids.toString().substring(0, UUID_STRING_FILTER_LEN) - + "-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); + sb.append( + "\n └Service Uuids : \n " + + advData.serviceUuids.toString().substring(0, UUID_STRING_FILTER_LEN) + + "-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); } } @@ -415,22 +438,24 @@ public class AppAdvertiseStats { private static void dumpAppAdvertiseStats(StringBuilder sb, AppAdvertiseStats stats) { sb.append("\n └Advertising:"); - sb.append("\n └Interval(0.625ms) : " - + stats.mInterval); - sb.append("\n └TX POWER(dbm) : " - + stats.mTxPowerLevel); - sb.append("\n └Primary Phy : " - + dumpPhyString(stats.mPrimaryPhy)); - sb.append("\n └Secondary Phy : " - + dumpPhyString(stats.mSecondaryPhy)); - sb.append("\n └Legacy : " - + stats.mLegacy); - sb.append("\n └Anonymous : " - + stats.mAnonymous); - sb.append("\n └Connectable : " - + stats.mConnectable); - sb.append("\n └Scannable : " - + stats.mScannable); + sb.append("\n └Interval(0.625ms) : " + stats.mInterval); + sb.append( + "\n └TX POWER(dbm) : " + + stats.mTxPowerLevel); + sb.append( + "\n └Primary Phy : " + + dumpPhyString(stats.mPrimaryPhy)); + sb.append( + "\n └Secondary Phy : " + + dumpPhyString(stats.mSecondaryPhy)); + sb.append("\n └Legacy : " + stats.mLegacy); + sb.append( + "\n └Anonymous : " + stats.mAnonymous); + sb.append( + "\n └Connectable : " + + stats.mConnectable); + sb.append( + "\n └Scannable : " + stats.mScannable); if (stats.mAdvertisingData != null) { sb.append("\n └Advertise Data:"); @@ -443,12 +468,15 @@ public class AppAdvertiseStats { } if (stats.mPeriodicInterval > 0) { - sb.append("\n └Periodic Advertising Enabled : " - + stats.mPeriodicAdvertisingEnabled); - sb.append("\n └Periodic Include TxPower : " - + stats.mPeriodicIncludeTxPower); - sb.append("\n └Periodic Interval(1.25ms) : " - + stats.mPeriodicInterval); + sb.append( + "\n └Periodic Advertising Enabled : " + + stats.mPeriodicAdvertisingEnabled); + sb.append( + "\n └Periodic Include TxPower : " + + stats.mPeriodicIncludeTxPower); + sb.append( + "\n └Periodic Interval(1.25ms) : " + + stats.mPeriodicInterval); } if (stats.mPeriodicAdvertisingData != null) { @@ -463,26 +491,31 @@ public class AppAdvertiseStats { Instant currentTime = Instant.now(); sb.append("\n " + stats.mAppName); - sb.append("\n Advertising ID : " - + stats.mId); + sb.append("\n Advertising ID : " + stats.mId); for (int i = 0; i < stats.mAdvertiserRecords.size(); i++) { AppAdvertiserRecord record = stats.mAdvertiserRecords.get(i); sb.append("\n " + (i + 1) + ":"); - sb.append("\n └Start time : " - + sDateFormat.format(record.startTime)); + sb.append( + "\n └Start time : " + + sDateFormat.format(record.startTime)); if (record.stopTime == null) { Duration timeElapsed = Duration.between(record.startTime, currentTime); - sb.append("\n └Elapsed time : " - + timeElapsed.toMillis() + "ms"); + sb.append( + "\n └Elapsed time : " + + timeElapsed.toMillis() + + "ms"); } else { - sb.append("\n └Stop time : " - + sDateFormat.format(record.stopTime)); + sb.append( + "\n └Stop time : " + + sDateFormat.format(record.stopTime)); } - sb.append("\n └Duration(10ms unit) : " - + record.duration); - sb.append("\n └Maximum number of extended advertising events : " - + record.maxExtendedAdvertisingEvents); + sb.append( + "\n └Duration(10ms unit) : " + + record.duration); + sb.append( + "\n └Maximum number of extended advertising events : " + + record.maxExtendedAdvertisingEvents); } dumpAppAdvertiseStats(sb, stats); diff --git a/android/app/src/com/android/bluetooth/gatt/ContextMap.java b/android/app/src/com/android/bluetooth/gatt/ContextMap.java index ff3c845a89c..b1561a89b75 100644 --- a/android/app/src/com/android/bluetooth/gatt/ContextMap.java +++ b/android/app/src/com/android/bluetooth/gatt/ContextMap.java @@ -49,15 +49,13 @@ import java.util.UUID; import java.util.function.Predicate; /** - * Helper class that keeps track of registered GATT applications. - * This class manages application callbacks and keeps track of GATT connections. + * Helper class that keeps track of registered GATT applications. This class manages application + * callbacks and keeps track of GATT connections. */ public class ContextMap { private static final String TAG = GattServiceConfig.TAG_PREFIX + "ContextMap"; - /** - * Connection class helps map connection IDs to device addresses. - */ + /** Connection class helps map connection IDs to device addresses. */ public static class Connection { public int connId; public String address; @@ -72,9 +70,7 @@ public class ContextMap { } } - /** - * Application entry mapping UUIDs to appIDs and callbacks. - */ + /** Application entry mapping UUIDs to appIDs and callbacks. */ public class App { /** The UUID of the application */ public UUID uuid; @@ -93,6 +89,7 @@ public class ContextMap { /** Context information */ public T info; + /** Death receipient */ private IBinder.DeathRecipient mDeathRecipient; @@ -127,9 +124,7 @@ public class ContextMap { /** Internal callback info queue, waiting to be send on congestion clear */ private List mCongestionQueue = new ArrayList(); - /** - * Creates a new app context. - */ + /** Creates a new app context. */ App(UUID uuid, C callback, T info, String name, AppScanStats appScanStats) { this.uuid = uuid; this.callback = callback; @@ -138,9 +133,7 @@ public class ContextMap { this.appScanStats = appScanStats; } - /** - * Creates a new app context for advertiser. - */ + /** Creates a new app context for advertiser. */ App(int id, C callback, String name) { this.id = id; this.callback = callback; @@ -188,6 +181,7 @@ public class ContextMap { /** Our internal application list */ private final Object mAppsLock = new Object(); + @GuardedBy("mAppsLock") private List mApps = new ArrayList(); @@ -318,9 +312,7 @@ public class ContextMap { return appIds; } - /** - * Add a new connection for a given application ID. - */ + /** Add a new connection for a given application ID. */ void addConnection(int id, int connId, String address) { synchronized (mConnectionsLock) { App entry = getById(id); @@ -330,9 +322,7 @@ public class ContextMap { } } - /** - * Remove a connection with the given ID. - */ + /** Remove a connection with the given ID. */ void removeConnection(int id, int connId) { synchronized (mConnectionsLock) { if (Flags.bleContextMapRemoveFix()) { @@ -350,9 +340,7 @@ public class ContextMap { } } - /** - * Remove all connections for a given application ID. - */ + /** Remove all connections for a given application ID. */ void removeConnectionsByAppId(int appId) { synchronized (mConnectionsLock) { mConnections.removeIf(conn -> conn.appId == appId); @@ -416,34 +404,26 @@ public class ContextMap { return null; } - /** - * Get Logging info by application UID - */ + /** Get Logging info by application UID */ public AppScanStats getAppScanStatsByUid(int uid) { return mAppScanStats.get(uid); } - /** - * Remove the context for a given application ID. - */ + /** Remove the context for a given application ID. */ void removeAppAdvertiseStats(int id) { synchronized (this) { mAppAdvertiseStats.remove(id); } } - /** - * Get Logging info by ID - */ + /** Get Logging info by ID */ AppAdvertiseStats getAppAdvertiseStatsById(int id) { synchronized (this) { return mAppAdvertiseStats.get(id); } } - /** - * update the advertiser ID by the regiseter ID - */ + /** update the advertiser ID by the regiseter ID */ void setAdvertiserIdByRegId(int regId, int advertiserId) { synchronized (this) { AppAdvertiseStats stats = mAppAdvertiseStats.get(regId); @@ -456,17 +436,28 @@ public class ContextMap { } } - void recordAdvertiseStart(int id, AdvertisingSetParameters parameters, - AdvertiseData advertiseData, AdvertiseData scanResponse, - PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData, - int duration, int maxExtAdvEvents) { + void recordAdvertiseStart( + int id, + AdvertisingSetParameters parameters, + AdvertiseData advertiseData, + AdvertiseData scanResponse, + PeriodicAdvertisingParameters periodicParameters, + AdvertiseData periodicData, + int duration, + int maxExtAdvEvents) { synchronized (this) { AppAdvertiseStats stats = mAppAdvertiseStats.get(id); if (stats == null) { return; } - stats.recordAdvertiseStart(parameters, advertiseData, scanResponse, - periodicParameters, periodicData, duration, maxExtAdvEvents); + stats.recordAdvertiseStart( + parameters, + advertiseData, + scanResponse, + periodicParameters, + periodicData, + duration, + maxExtAdvEvents); int advertiseInstanceCount = mAppAdvertiseStats.size(); Log.d(TAG, "advertiseInstanceCount is " + advertiseInstanceCount); AppAdvertiseStats.recordAdvertiseInstanceCount(advertiseInstanceCount); @@ -555,9 +546,7 @@ public class ContextMap { } } - /** - * Get the device addresses for all connected devices - */ + /** Get the device addresses for all connected devices */ Set getConnectedDevices() { Set addresses = new HashSet(); synchronized (mConnectionsLock) { @@ -568,9 +557,7 @@ public class ContextMap { return addresses; } - /** - * Get an application context by a connection ID. - */ + /** Get an application context by a connection ID. */ App getByConnId(int connId) { int appId = -1; synchronized (mConnectionsLock) { @@ -587,9 +574,7 @@ public class ContextMap { return null; } - /** - * Returns a connection ID for a given device address. - */ + /** Returns a connection ID for a given device address. */ Integer connIdByAddress(int id, String address) { App entry = getById(id); if (entry == null) { @@ -605,9 +590,7 @@ public class ContextMap { return null; } - /** - * Returns the device address for a given connection ID. - */ + /** Returns the device address for a given connection ID. */ String addressByConnId(int connId) { synchronized (mConnectionsLock) { for (Connection connection : mConnections) { @@ -653,9 +636,7 @@ public class ContextMap { } } - /** - * Returns connect device map with addr and appid - */ + /** Returns connect device map with addr and appid */ Map getConnectedMap() { Map connectedmap = new HashMap(); synchronized (mConnectionsLock) { @@ -666,9 +647,7 @@ public class ContextMap { return connectedmap; } - /** - * Logs debug information. - */ + /** Logs debug information. */ protected void dump(StringBuilder sb) { sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); for (AppScanStats appScanStats : mAppScanStats.values()) { @@ -676,9 +655,7 @@ public class ContextMap { } } - /** - * Logs advertiser debug information. - */ + /** Logs advertiser debug information. */ void dumpAdvertiser(StringBuilder sb) { synchronized (this) { if (!mLastAdvertises.isEmpty()) { @@ -690,8 +667,9 @@ public class ContextMap { } if (!mAppAdvertiseStats.isEmpty()) { - sb.append(" Total number of ongoing advertising : " - + mAppAdvertiseStats.size()); + sb.append( + " Total number of ongoing advertising : " + + mAppAdvertiseStats.size()); sb.append("\n Ongoing advertising:"); for (Integer key : mAppAdvertiseStats.keySet()) { AppAdvertiseStats stats = mAppAdvertiseStats.get(key); diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java index e01f6ab61e7..b5bdea95e0b 100644 --- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java +++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java @@ -35,9 +35,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; -/** - * Manages distance measurement operations and interacts with Gabeldorsche stack. - */ +/** Manages distance measurement operations and interacts with Gabeldorsche stack. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public class DistanceMeasurementManager { private static final String TAG = DistanceMeasurementManager.class.getSimpleName(); @@ -73,17 +71,22 @@ public class DistanceMeasurementManager { } DistanceMeasurementMethod[] getSupportedDistanceMeasurementMethods() { - DistanceMeasurementMethod rssi = new DistanceMeasurementMethod.Builder( - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI).build(); + DistanceMeasurementMethod rssi = + new DistanceMeasurementMethod.Builder( + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI) + .build(); DistanceMeasurementMethod[] methods = {rssi}; return methods; } - - void startDistanceMeasurement(UUID uuid, DistanceMeasurementParams params, - IDistanceMeasurementCallback callback) { - Log.i(TAG, "startDistanceMeasurement device:" + params.getDevice().getAnonymizedAddress() - + ", method: " + params.getMethodId()); + void startDistanceMeasurement( + UUID uuid, DistanceMeasurementParams params, IDistanceMeasurementCallback callback) { + Log.i( + TAG, + "startDistanceMeasurement device:" + + params.getDevice().getAnonymizedAddress() + + ", method: " + + params.getMethodId()); String address = mAdapterService.getIdentityAddress(params.getDevice().getAddress()); if (address == null) { address = params.getDevice().getAddress(); @@ -96,8 +99,8 @@ public class DistanceMeasurementManager { int interval = getIntervalValue(params.getFrequency(), params.getMethodId()); if (interval == -1) { - invokeStartFail(callback, params.getDevice(), - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + invokeStartFail( + callback, params.getDevice(), BluetoothStatusCodes.ERROR_BAD_PARAMETERS); return; } @@ -121,8 +124,8 @@ public class DistanceMeasurementManager { startCsTracker(tracker); break; default: - invokeStartFail(callback, params.getDevice(), - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + invokeStartFail( + callback, params.getDevice(), BluetoothStatusCodes.ERROR_BAD_PARAMETERS); } } @@ -154,10 +157,15 @@ public class DistanceMeasurementManager { DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING); } - int stopDistanceMeasurement(UUID uuid, BluetoothDevice device, int method, - boolean timeout) { - Log.i(TAG, "stopDistanceMeasurement device:" + device.getAnonymizedAddress() - + ", method: " + method + " timeout " + timeout); + int stopDistanceMeasurement(UUID uuid, BluetoothDevice device, int method, boolean timeout) { + Log.i( + TAG, + "stopDistanceMeasurement device:" + + device.getAnonymizedAddress() + + ", method: " + + method + + " timeout " + + timeout); String address = mAdapterService.getIdentityAddress(device.getAddress()); if (address == null) { address = device.getAddress(); @@ -188,8 +196,7 @@ public class DistanceMeasurementManager { return ChannelSoundingParams.CS_SECURITY_LEVEL_ONE; } - private synchronized int stopRssiTracker(UUID uuid, String identityAddress, - boolean timeout) { + private synchronized int stopRssiTracker(UUID uuid, String identityAddress, boolean timeout) { CopyOnWriteArraySet set = mRssiTrackers.get(identityAddress); if (set == null) { Log.w(TAG, "Can't find rssi tracker"); @@ -198,8 +205,10 @@ public class DistanceMeasurementManager { for (DistanceMeasurementTracker tracker : set) { if (tracker.equals(uuid, identityAddress)) { - int reason = timeout ? BluetoothStatusCodes.ERROR_TIMEOUT : - BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST; + int reason = + timeout + ? BluetoothStatusCodes.ERROR_TIMEOUT + : BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST; invokeOnStopped(tracker.mCallback, tracker.mDevice, reason); tracker.cancelTimer(); set.remove(tracker); @@ -210,8 +219,8 @@ public class DistanceMeasurementManager { if (set.isEmpty()) { logd("no rssi tracker"); mRssiTrackers.remove(identityAddress); - mDistanceMeasurementNativeInterface.stopDistanceMeasurement(identityAddress, - DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementNativeInterface.stopDistanceMeasurement( + identityAddress, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); } return BluetoothStatusCodes.SUCCESS; } @@ -246,8 +255,8 @@ public class DistanceMeasurementManager { return BluetoothStatusCodes.SUCCESS; } - private void invokeStartFail(IDistanceMeasurementCallback callback, BluetoothDevice device, - int reason) { + private void invokeStartFail( + IDistanceMeasurementCallback callback, BluetoothDevice device, int reason) { try { callback.onStartFail(device, reason); } catch (RemoteException e) { @@ -255,8 +264,8 @@ public class DistanceMeasurementManager { } } - private void invokeOnStopped(IDistanceMeasurementCallback callback, BluetoothDevice device, - int reason) { + private void invokeOnStopped( + IDistanceMeasurementCallback callback, BluetoothDevice device, int reason) { try { callback.onStopped(device, reason); } catch (RemoteException e) { @@ -295,8 +304,11 @@ public class DistanceMeasurementManager { } void onDistanceMeasurementStarted(String address, int method) { - logd("onDistanceMeasurementStarted address:" + BluetoothUtils.toAnonymizedAddress(address) - + ", method:" + method); + logd( + "onDistanceMeasurementStarted address:" + + BluetoothUtils.toAnonymizedAddress(address) + + ", method:" + + method); switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiStarted(address); @@ -348,8 +360,11 @@ public class DistanceMeasurementManager { } void onDistanceMeasurementStartFail(String address, int reason, int method) { - logd("onDistanceMeasurementStartFail address:" + BluetoothUtils.toAnonymizedAddress(address) - + ", method:" + method); + logd( + "onDistanceMeasurementStartFail address:" + + BluetoothUtils.toAnonymizedAddress(address) + + ", method:" + + method); switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiStartFail(address, reason); @@ -391,8 +406,13 @@ public class DistanceMeasurementManager { } void onDistanceMeasurementStopped(String address, int reason, int method) { - logd("onDistanceMeasurementStopped address:" + BluetoothUtils.toAnonymizedAddress(address) - + ", reason:" + reason + ", method:" + method); + logd( + "onDistanceMeasurementStopped address:" + + BluetoothUtils.toAnonymizedAddress(address) + + ", reason:" + + reason + + ", method:" + + method); switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiStopped(address, reason); @@ -435,15 +455,26 @@ public class DistanceMeasurementManager { set.removeIf(tracker -> tracker.mStarted); } - void onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter, - int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle, + void onDistanceMeasurementResult( + String address, + int centimeter, + int errorCentimeter, + int azimuthAngle, + int errorAzimuthAngle, + int altitudeAngle, + int errorAltitudeAngle, int method) { - logd("onDistanceMeasurementResult " + BluetoothUtils.toAnonymizedAddress(address) - + ", centimeter " + centimeter); + logd( + "onDistanceMeasurementResult " + + BluetoothUtils.toAnonymizedAddress(address) + + ", centimeter " + + centimeter); switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: - DistanceMeasurementResult result = new DistanceMeasurementResult.Builder( - centimeter / 100.0, errorCentimeter / 100.0).build(); + DistanceMeasurementResult result = + new DistanceMeasurementResult.Builder( + centimeter / 100.0, errorCentimeter / 100.0) + .build(); handleRssiResult(address, result); break; default: diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java index b71e172e82f..4378d9d9db0 100644 --- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java +++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java @@ -21,9 +21,7 @@ import android.bluetooth.BluetoothStatusCodes; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -/** - * Distance Measurement Native Interface to/from JNI. - */ +/** Distance Measurement Native Interface to/from JNI. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public class DistanceMeasurementNativeInterface { private static final String TAG = DistanceMeasurementNativeInterface.class.getSimpleName(); @@ -36,10 +34,11 @@ public class DistanceMeasurementNativeInterface { private DistanceMeasurementManager mDistanceMeasurementManager; /** - * Do not modify without updating distance_measurement_manager.h - * match up with DistanceMeasurementErrorCode enum of distance_measurement_manager.h + * Do not modify without updating distance_measurement_manager.h match up with + * DistanceMeasurementErrorCode enum of distance_measurement_manager.h */ private static final int REASON_FEATURE_NOT_SUPPORTED_LOCAL = 0; + private static final int REASON_FEATURE_NOT_SUPPORTED_REMOTE = 1; private static final int REASON_LOCAL_REQUEST = 2; private static final int REASON_REMOTE_REQUEST = 3; @@ -48,7 +47,6 @@ public class DistanceMeasurementNativeInterface { private static final int REASON_INVALID_PARAMETERS = 6; private static final int REASON_INTERNAL_ERROR = 7; - private DistanceMeasurementNativeInterface() {} /** @@ -95,20 +93,32 @@ public class DistanceMeasurementNativeInterface { } void onDistanceMeasurementStartFail(String address, int reason, int method) { - mDistanceMeasurementManager.onDistanceMeasurementStartFail(address, - convertErrorCode(reason), method); + mDistanceMeasurementManager.onDistanceMeasurementStartFail( + address, convertErrorCode(reason), method); } void onDistanceMeasurementStopped(String address, int reason, int method) { - mDistanceMeasurementManager.onDistanceMeasurementStopped(address, - convertErrorCode(reason), method); + mDistanceMeasurementManager.onDistanceMeasurementStopped( + address, convertErrorCode(reason), method); } - void onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter, - int azimuthAngle, int errorAzimuthAngle, int altitudeAngle, int errorAltitudeAngle, + void onDistanceMeasurementResult( + String address, + int centimeter, + int errorCentimeter, + int azimuthAngle, + int errorAzimuthAngle, + int altitudeAngle, + int errorAltitudeAngle, int method) { - mDistanceMeasurementManager.onDistanceMeasurementResult(address, centimeter, - errorCentimeter, azimuthAngle, errorAzimuthAngle, altitudeAngle, errorAltitudeAngle, + mDistanceMeasurementManager.onDistanceMeasurementResult( + address, + centimeter, + errorCentimeter, + azimuthAngle, + errorAzimuthAngle, + altitudeAngle, + errorAltitudeAngle, method); } diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java index a4c97afab43..161bcb34310 100644 --- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java +++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java @@ -25,9 +25,7 @@ import android.os.Looper; import java.util.Objects; import java.util.UUID; -/** - * Manages information of apps that registered distance measurement - */ +/** Manages information of apps that registered distance measurement */ class DistanceMeasurementTracker { private static final String TAG = "DistanceMeasurementTracker"; @@ -61,12 +59,14 @@ class DistanceMeasurementTracker { void startTimer(Looper looper) { mHandler = new Handler(looper); - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - mManager.stopDistanceMeasurement(mUuid, mDevice, mMethod, true); - } - }, mDuration * 1000L); + mHandler.postDelayed( + new Runnable() { + @Override + public void run() { + mManager.stopDistanceMeasurement(mUuid, mDevice, mMethod, true); + } + }, + mDuration * 1000L); } void cancelTimer() { diff --git a/android/app/src/com/android/bluetooth/gatt/FilterParams.java b/android/app/src/com/android/bluetooth/gatt/FilterParams.java index c58f51bbb82..d1fddb61471 100644 --- a/android/app/src/com/android/bluetooth/gatt/FilterParams.java +++ b/android/app/src/com/android/bluetooth/gatt/FilterParams.java @@ -30,9 +30,19 @@ public class FilterParams { private int mFoundTimeOutCnt; private int mNumOfTrackEntries; - public FilterParams(int clientIf, int filtIndex, int featSeln, int listLogicType, - int filtLogicType, int rssiHighThres, int rssiLowThres, int delyMode, int foundTimeout, - int lostTimeout, int foundTimeoutCnt, int numOfTrackingEntries) { + public FilterParams( + int clientIf, + int filtIndex, + int featSeln, + int listLogicType, + int filtLogicType, + int rssiHighThres, + int rssiLowThres, + int delyMode, + int foundTimeout, + int lostTimeout, + int foundTimeoutCnt, + int numOfTrackingEntries) { mClientIf = clientIf; mFiltIndex = filtIndex; @@ -95,6 +105,4 @@ public class FilterParams { public int getNumOfTrackEntries() { return mNumOfTrackEntries; } - } - diff --git a/android/app/src/com/android/bluetooth/gatt/GattDbElement.java b/android/app/src/com/android/bluetooth/gatt/GattDbElement.java index c2bf8a5e5a8..8f24ab2987e 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattDbElement.java +++ b/android/app/src/com/android/bluetooth/gatt/GattDbElement.java @@ -19,8 +19,8 @@ package com.android.bluetooth.gatt; import java.util.UUID; /** - * Helper class for passing gatt db elements between java and JNI, equal to - * native btgatt_db_element_t. + * Helper class for passing gatt db elements between java and JNI, equal to native + * btgatt_db_element_t. */ public class GattDbElement { diff --git a/android/app/src/com/android/bluetooth/gatt/GattDebugUtils.java b/android/app/src/com/android/bluetooth/gatt/GattDebugUtils.java index 97bc0fcd1fc..60c1c865827 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattDebugUtils.java +++ b/android/app/src/com/android/bluetooth/gatt/GattDebugUtils.java @@ -25,31 +25,29 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.UUID; -/** - * Helper class containing useful tools for GATT service debugging. - */ +/** Helper class containing useful tools for GATT service debugging. */ /*package*/ class GattDebugUtils { private static final String TAG = GattServiceConfig.TAG_PREFIX + "DebugUtils"; private static final boolean DEBUG_ADMIN = GattServiceConfig.DEBUG_ADMIN; @VisibleForTesting - static final String ACTION_GATT_PAIRING_CONFIG = - "android.bluetooth.action.GATT_PAIRING_CONFIG"; + static final String ACTION_GATT_PAIRING_CONFIG = "android.bluetooth.action.GATT_PAIRING_CONFIG"; @VisibleForTesting static final String ACTION_GATT_TEST_USAGE = "android.bluetooth.action.GATT_TEST_USAGE"; + @VisibleForTesting - static final String ACTION_GATT_TEST_ENABLE = - "android.bluetooth.action.GATT_TEST_ENABLE"; + static final String ACTION_GATT_TEST_ENABLE = "android.bluetooth.action.GATT_TEST_ENABLE"; + @VisibleForTesting - static final String ACTION_GATT_TEST_CONNECT = - "android.bluetooth.action.GATT_TEST_CONNECT"; + static final String ACTION_GATT_TEST_CONNECT = "android.bluetooth.action.GATT_TEST_CONNECT"; + @VisibleForTesting static final String ACTION_GATT_TEST_DISCONNECT = "android.bluetooth.action.GATT_TEST_DISCONNECT"; + @VisibleForTesting - static final String ACTION_GATT_TEST_DISCOVER = - "android.bluetooth.action.GATT_TEST_DISCOVER"; + static final String ACTION_GATT_TEST_DISCOVER = "android.bluetooth.action.GATT_TEST_DISCOVER"; private static final String EXTRA_ENABLE = "enable"; private static final String EXTRA_ADDRESS = "address"; @@ -65,17 +63,15 @@ import java.util.UUID; private static final String EXTRA_MAX_KEY = "max_key"; /** - * Handles intents passed in via GattService.onStartCommand(). - * This allows sending debug actions to the running service. - * To trigger a debug action, invoke the following shell command: + * Handles intents passed in via GattService.onStartCommand(). This allows sending debug actions + * to the running service. To trigger a debug action, invoke the following shell command: * - * adb shell am startservice -a + *

adb shell am startservice -a * - * Where represents one of the ACTION_* constants defines above - * and identifies the GATT service. + *

Where represents one of the ACTION_* constants defines above and + * identifies the GATT service. * - * For example: - * import com.android.bluetooth.gatt.GattService; + *

For example: import com.android.bluetooth.gatt.GattService; */ static boolean handleDebugAction(GattService svc, Intent intent) { if (!DEBUG_ADMIN && !Utils.isInstrumentationTestMode()) { @@ -127,10 +123,7 @@ import java.util.UUID; return true; } - /** - * Attempts to retrieve an extra from an intent first as hex value, - * then as an ineger. - */ + /** Attempts to retrieve an extra from an intent first as hex value, then as an ineger. */ private static int getHandleExtra(Intent intent, String extra, int defaultValue) { Bundle extras = intent.getExtras(); Object uuid = extras != null ? extras.get(extra) : null; @@ -146,9 +139,8 @@ import java.util.UUID; } /** - * Retrieves the EXTRA_UUID parameter. - * If a string of length 4 is detected, a 16-bit hex UUID is assumed and - * the default Bluetooth UUID is appended. + * Retrieves the EXTRA_UUID parameter. If a string of length 4 is detected, a 16-bit hex UUID is + * assumed and the default Bluetooth UUID is appended. */ private static UUID getUuidExtra(Intent intent) { String uuidStr = intent.getStringExtra(EXTRA_UUID); diff --git a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java index 4531b49a1a9..09ddc26de54 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java +++ b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java @@ -24,9 +24,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; -/** - * GATT Profile Native Interface to/from JNI. - */ +/** GATT Profile Native Interface to/from JNI. */ public class GattNativeInterface { private static final String TAG = GattNativeInterface.class.getSimpleName(); @@ -99,10 +97,11 @@ public class GattNativeInterface { getGattService().onServiceChanged(connId); } - void onClientSubrateChange(int connId, int subrateFactor, int latency, int contNum, int timeout, - int status) throws RemoteException { - getGattService().onClientSubrateChange(connId, subrateFactor, latency, contNum, timeout, - status); + void onClientSubrateChange( + int connId, int subrateFactor, int latency, int contNum, int timeout, int status) + throws RemoteException { + getGattService() + .onClientSubrateChange(connId, subrateFactor, latency, contNum, timeout, status); } void onServerPhyUpdate(int connId, int txPhy, int rxPhy, int status) throws RemoteException { @@ -119,11 +118,11 @@ public class GattNativeInterface { getGattService().onServerConnUpdate(connId, interval, latency, timeout, status); } - void onServerSubrateChange(int connId, int subrateFactor, int latency, int contNum, int timeout, - int status) + void onServerSubrateChange( + int connId, int subrateFactor, int latency, int contNum, int timeout, int status) throws RemoteException { - getGattService().onServerSubrateChange(connId, subrateFactor, latency, contNum, timeout, - status); + getGattService() + .onServerSubrateChange(connId, subrateFactor, latency, contNum, timeout, status); } void onSearchCompleted(int connId, int status) throws RemoteException { @@ -207,8 +206,9 @@ public class GattNativeInterface { getGattService().onClientConnected(address, connected, connId, serverIf); } - void onServerReadCharacteristic(String address, int connId, int transId, int handle, int offset, - boolean isLong) throws RemoteException { + void onServerReadCharacteristic( + String address, int connId, int transId, int handle, int offset, boolean isLong) + throws RemoteException { getGattService() .onServerReadCharacteristic(address, connId, transId, handle, offset, isLong); } @@ -230,12 +230,22 @@ public class GattNativeInterface { boolean isPrep, byte[] data) throws RemoteException { - getGattService().onServerWriteCharacteristic(address, connId, transId, handle, offset, - length, needRsp, isPrep, data); + getGattService() + .onServerWriteCharacteristic( + address, connId, transId, handle, offset, length, needRsp, isPrep, data); } - void onServerWriteDescriptor(String address, int connId, int transId, int handle, int offset, - int length, boolean needRsp, boolean isPrep, byte[] data) throws RemoteException { + void onServerWriteDescriptor( + String address, + int connId, + int transId, + int handle, + int offset, + int length, + boolean needRsp, + boolean isPrep, + byte[] data) + throws RemoteException { getGattService() .onServerWriteDescriptor( address, connId, transId, handle, offset, length, needRsp, isPrep, data); @@ -269,74 +279,136 @@ public class GattNativeInterface { private native void initializeNative(); private native void cleanupNative(); + private native int gattClientGetDeviceTypeNative(String address); - private native void gattClientRegisterAppNative(long appUuidLsb, long appUuidMsb, - boolean eattSupport); + + private native void gattClientRegisterAppNative( + long appUuidLsb, long appUuidMsb, boolean eattSupport); + private native void gattClientUnregisterAppNative(int clientIf); - private native void gattClientConnectNative(int clientIf, String address, int addressType, - boolean isDirect, int transport, boolean opportunistic, int initiatingPhys); + + private native void gattClientConnectNative( + int clientIf, + String address, + int addressType, + boolean isDirect, + int transport, + boolean opportunistic, + int initiatingPhys); + private native void gattClientDisconnectNative(int clientIf, String address, int connId); - private native void gattClientSetPreferredPhyNative(int clientIf, String address, int txPhy, - int rxPhy, int phyOptions); + + private native void gattClientSetPreferredPhyNative( + int clientIf, String address, int txPhy, int rxPhy, int phyOptions); + private native void gattClientReadPhyNative(int clientIf, String address); + private native void gattClientRefreshNative(int clientIf, String address); - private native void gattClientSearchServiceNative(int connId, boolean searchAll, - long serviceUuidLsb, long serviceUuidMsb); - private native void gattClientDiscoverServiceByUuidNative(int connId, long serviceUuidLsb, - long serviceUuidMsb); + + private native void gattClientSearchServiceNative( + int connId, boolean searchAll, long serviceUuidLsb, long serviceUuidMsb); + + private native void gattClientDiscoverServiceByUuidNative( + int connId, long serviceUuidLsb, long serviceUuidMsb); + private native void gattClientGetGattDbNative(int connId); + private native void gattClientReadCharacteristicNative(int connId, int handle, int authReq); - private native void gattClientReadUsingCharacteristicUuidNative(int connId, long uuidMsb, - long uuidLsb, int sHandle, int eHandle, int authReq); + + private native void gattClientReadUsingCharacteristicUuidNative( + int connId, long uuidMsb, long uuidLsb, int sHandle, int eHandle, int authReq); + private native void gattClientReadDescriptorNative(int connId, int handle, int authReq); - private native void gattClientWriteCharacteristicNative(int connId, int handle, int writeType, - int authReq, byte[] value); - private native void gattClientWriteDescriptorNative(int connId, int handle, int authReq, - byte[] value); + + private native void gattClientWriteCharacteristicNative( + int connId, int handle, int writeType, int authReq, byte[] value); + + private native void gattClientWriteDescriptorNative( + int connId, int handle, int authReq, byte[] value); + private native void gattClientExecuteWriteNative(int connId, boolean execute); - private native void gattClientRegisterForNotificationsNative(int clientIf, String address, - int handle, boolean enable); + + private native void gattClientRegisterForNotificationsNative( + int clientIf, String address, int handle, boolean enable); + private native void gattClientReadRemoteRssiNative(int clientIf, String address); + private native void gattClientConfigureMTUNative(int connId, int mtu); - private native void gattConnectionParameterUpdateNative(int clientIf, String address, - int minInterval, int maxInterval, int latency, int timeout, int minConnectionEventLen, + + private native void gattConnectionParameterUpdateNative( + int clientIf, + String address, + int minInterval, + int maxInterval, + int latency, + int timeout, + int minConnectionEventLen, int maxConnectionEventLen); - private native void gattServerRegisterAppNative(long appUuidLsb, long appUuidMsb, - boolean eattSupport); + + private native void gattServerRegisterAppNative( + long appUuidLsb, long appUuidMsb, boolean eattSupport); + private native void gattServerUnregisterAppNative(int serverIf); private native void gattServerConnectNative( int serverIf, String address, int addressType, boolean isDirect, int transport); private native void gattServerDisconnectNative(int serverIf, String address, int connId); - private native void gattServerSetPreferredPhyNative(int clientIf, String address, int txPhy, - int rxPhy, int phyOptions); + + private native void gattServerSetPreferredPhyNative( + int clientIf, String address, int txPhy, int rxPhy, int phyOptions); + private native void gattServerReadPhyNative(int clientIf, String address); + private native void gattServerAddServiceNative(int serverIf, List service); + private native void gattServerStopServiceNative(int serverIf, int svcHandle); + private native void gattServerDeleteServiceNative(int serverIf, int svcHandle); - private native void gattServerSendIndicationNative(int serverIf, int attrHandle, int connId, - byte[] val); - private native void gattServerSendNotificationNative(int serverIf, int attrHandle, int connId, - byte[] val); - private native void gattServerSendResponseNative(int serverIf, int connId, int transId, - int status, int handle, int offset, byte[] val, int authReq); - private native void gattSubrateRequestNative(int clientIf, String address, int subrateMin, - int subrateMax, int maxLatency, int contNumber, int supervisionTimeout); - private native void gattTestNative(int command, long uuid1Lsb, long uuid1Msb, String bda1, - int p1, int p2, int p3, int p4, int p5); - /** - * Initialize the native interface and native components - */ + private native void gattServerSendIndicationNative( + int serverIf, int attrHandle, int connId, byte[] val); + + private native void gattServerSendNotificationNative( + int serverIf, int attrHandle, int connId, byte[] val); + + private native void gattServerSendResponseNative( + int serverIf, + int connId, + int transId, + int status, + int handle, + int offset, + byte[] val, + int authReq); + + private native void gattSubrateRequestNative( + int clientIf, + String address, + int subrateMin, + int subrateMax, + int maxLatency, + int contNumber, + int supervisionTimeout); + + private native void gattTestNative( + int command, + long uuid1Lsb, + long uuid1Msb, + String bda1, + int p1, + int p2, + int p3, + int p4, + int p5); + + /** Initialize the native interface and native components */ public void init(GattService gattService) { mGattService = gattService; initializeNative(); } - /** - * Clean up the native interface and native components - */ + /** Clean up the native interface and native components */ public void cleanup() { cleanupNative(); mGattService = null; @@ -353,124 +425,103 @@ public class GattNativeInterface { } /** - * Register the given client - * It will invoke {@link #onClientRegistered(int, int, long, long)}. + * Register the given client It will invoke {@link #onClientRegistered(int, int, long, long)}. */ public void gattClientRegisterApp(long appUuidLsb, long appUuidMsb, boolean eattSupport) { gattClientRegisterAppNative(appUuidLsb, appUuidMsb, eattSupport); } - /** - * Unregister the client - */ + /** Unregister the client */ public void gattClientUnregisterApp(int clientIf) { gattClientUnregisterAppNative(clientIf); } /** * Connect to the remote Gatt server + * * @see {@link BluetoothDevice#connectGatt} for parameters. */ - public void gattClientConnect(int clientIf, String address, int addressType, - boolean isDirect, int transport, boolean opportunistic, int initiatingPhys) { - gattClientConnectNative(clientIf, address, addressType, isDirect, transport, - opportunistic, initiatingPhys); + public void gattClientConnect( + int clientIf, + String address, + int addressType, + boolean isDirect, + int transport, + boolean opportunistic, + int initiatingPhys) { + gattClientConnectNative( + clientIf, address, addressType, isDirect, transport, opportunistic, initiatingPhys); } - /** - * Disconnect from the remote Gatt server - */ + /** Disconnect from the remote Gatt server */ public void gattClientDisconnect(int clientIf, String address, int connId) { gattClientDisconnectNative(clientIf, address, connId); } - /** - * Set the preferred connection PHY for the client - */ - public void gattClientSetPreferredPhy(int clientIf, String address, int txPhy, - int rxPhy, int phyOptions) { + /** Set the preferred connection PHY for the client */ + public void gattClientSetPreferredPhy( + int clientIf, String address, int txPhy, int rxPhy, int phyOptions) { gattClientSetPreferredPhyNative(clientIf, address, txPhy, rxPhy, phyOptions); } - /** - * Read the current transmitter PHY and receiver PHY of the client - */ + /** Read the current transmitter PHY and receiver PHY of the client */ public void gattClientReadPhy(int clientIf, String address) { gattClientReadPhyNative(clientIf, address); } - /** - * Clear the internal cache and force a refresh of the services from the remote device - */ + /** Clear the internal cache and force a refresh of the services from the remote device */ public void gattClientRefresh(int clientIf, String address) { gattClientRefreshNative(clientIf, address); } - /** - * Discover GATT services - */ - public void gattClientSearchService(int connId, boolean searchAll, long serviceUuidLsb, - long serviceUuidMsb) { + /** Discover GATT services */ + public void gattClientSearchService( + int connId, boolean searchAll, long serviceUuidLsb, long serviceUuidMsb) { gattClientSearchServiceNative(connId, searchAll, serviceUuidLsb, serviceUuidMsb); } - /** - * Discover the GATT service by the given UUID - */ - public void gattClientDiscoverServiceByUuid(int connId, long serviceUuidLsb, - long serviceUuidMsb) { + /** Discover the GATT service by the given UUID */ + public void gattClientDiscoverServiceByUuid( + int connId, long serviceUuidLsb, long serviceUuidMsb) { gattClientDiscoverServiceByUuidNative(connId, serviceUuidLsb, serviceUuidMsb); } - /** - * Get GATT DB of the remote device - */ + /** Get GATT DB of the remote device */ public void gattClientGetGattDb(int connId) { gattClientGetGattDbNative(connId); } - /** - * Read a characteristic by the given handle - */ + /** Read a characteristic by the given handle */ public void gattClientReadCharacteristic(int connId, int handle, int authReq) { gattClientReadCharacteristicNative(connId, handle, authReq); } - - /** - * Read a characteristic by the given UUID - */ - public void gattClientReadUsingCharacteristicUuid(int connId, long uuidMsb, - long uuidLsb, int sHandle, int eHandle, int authReq) { - gattClientReadUsingCharacteristicUuidNative(connId, uuidMsb, uuidLsb, sHandle, eHandle, - authReq); + /** Read a characteristic by the given UUID */ + public void gattClientReadUsingCharacteristicUuid( + int connId, long uuidMsb, long uuidLsb, int sHandle, int eHandle, int authReq) { + gattClientReadUsingCharacteristicUuidNative( + connId, uuidMsb, uuidLsb, sHandle, eHandle, authReq); } - /** - * Read a descriptor by the given handle - */ + /** Read a descriptor by the given handle */ public void gattClientReadDescriptor(int connId, int handle, int authReq) { gattClientReadDescriptorNative(connId, handle, authReq); } - /** - * Write a characteristic by the given handle - */ - public void gattClientWriteCharacteristic(int connId, int handle, int writeType, - int authReq, byte[] value) { + /** Write a characteristic by the given handle */ + public void gattClientWriteCharacteristic( + int connId, int handle, int writeType, int authReq, byte[] value) { gattClientWriteCharacteristicNative(connId, handle, writeType, authReq, value); } - /** - * Write a descriptor by the given handle - */ - public void gattClientWriteDescriptor(int connId, int handle, int authReq, - byte[] value) { + /** Write a descriptor by the given handle */ + public void gattClientWriteDescriptor(int connId, int handle, int authReq, byte[] value) { gattClientWriteDescriptorNative(connId, handle, authReq, value); } /** * Execute a reliable write transaction + * * @param connId * @param execute */ @@ -478,16 +529,15 @@ public class GattNativeInterface { gattClientExecuteWriteNative(connId, execute); } - /** - * Register notification for the characteristic - */ - public void gattClientRegisterForNotifications(int clientIf, String address, - int handle, boolean enable) { + /** Register notification for the characteristic */ + public void gattClientRegisterForNotifications( + int clientIf, String address, int handle, boolean enable) { gattClientRegisterForNotificationsNative(clientIf, address, handle, enable); } /** * Read the RSSI for a connected remote device + * * @param clientIf * @param address */ @@ -495,42 +545,57 @@ public class GattNativeInterface { gattClientReadRemoteRssiNative(clientIf, address); } - /** - * Configure MTU size used for the connection - */ + /** Configure MTU size used for the connection */ public void gattClientConfigureMTU(int connId, int mtu) { gattClientConfigureMTUNative(connId, mtu); } - /** - * Update connection parameter. - */ - public void gattConnectionParameterUpdate(int clientIf, String address, - int minInterval, int maxInterval, int latency, int timeout, int minConnectionEventLen, + /** Update connection parameter. */ + public void gattConnectionParameterUpdate( + int clientIf, + String address, + int minInterval, + int maxInterval, + int latency, + int timeout, + int minConnectionEventLen, int maxConnectionEventLen) { - gattConnectionParameterUpdateNative(clientIf, address, minInterval, maxInterval, latency, - timeout, minConnectionEventLen, maxConnectionEventLen); - } - - /** - * Update connection parameter. - */ - public void gattSubrateRequest(int clientIf, String address, int subrateMin, int subrateMax, - int maxLatency, int contNumber, int supervisionTimeout) { - gattSubrateRequestNative(clientIf, address, subrateMin, subrateMax, maxLatency, contNumber, + gattConnectionParameterUpdateNative( + clientIf, + address, + minInterval, + maxInterval, + latency, + timeout, + minConnectionEventLen, + maxConnectionEventLen); + } + + /** Update connection parameter. */ + public void gattSubrateRequest( + int clientIf, + String address, + int subrateMin, + int subrateMax, + int maxLatency, + int contNumber, + int supervisionTimeout) { + gattSubrateRequestNative( + clientIf, + address, + subrateMin, + subrateMax, + maxLatency, + contNumber, supervisionTimeout); } - /** - * Register GATT server - */ + /** Register GATT server */ public void gattServerRegisterApp(long appUuidLsb, long appUuidMsb, boolean eattSupport) { gattServerRegisterAppNative(appUuidLsb, appUuidMsb, eattSupport); } - /** - * Unregister GATT server - */ + /** Unregister GATT server */ public void gattServerUnregisterApp(int serverIf) { gattServerUnregisterAppNative(serverIf); } @@ -541,80 +606,72 @@ public class GattNativeInterface { gattServerConnectNative(serverIf, address, addressType, isDirect, transport); } - /** - * Disconnects from a remote device as a GATT server role - */ + /** Disconnects from a remote device as a GATT server role */ public void gattServerDisconnect(int serverIf, String address, int connId) { gattServerDisconnectNative(serverIf, address, connId); } - /** - * Set the preferred connection PHY as a GATT server role - */ - public void gattServerSetPreferredPhy(int clientIf, String address, int txPhy, - int rxPhy, int phyOptions) { + /** Set the preferred connection PHY as a GATT server role */ + public void gattServerSetPreferredPhy( + int clientIf, String address, int txPhy, int rxPhy, int phyOptions) { gattServerSetPreferredPhyNative(clientIf, address, txPhy, rxPhy, phyOptions); } - /** - * Read the current transmitter PHY and receiver PHY of the connection - */ + /** Read the current transmitter PHY and receiver PHY of the connection */ public void gattServerReadPhy(int clientIf, String address) { gattServerReadPhyNative(clientIf, address); } - /** - * Add a service to the list of services to be hosted. - */ + /** Add a service to the list of services to be hosted. */ public void gattServerAddService(int serverIf, List service) { gattServerAddServiceNative(serverIf, service); } - /** - * Stop a service - */ + /** Stop a service */ public void gattServerStopService(int serverIf, int svcHandle) { gattServerStopServiceNative(serverIf, svcHandle); } - /** - * Removes a service from the list of services to be provided - */ + /** Removes a service from the list of services to be provided */ public void gattServerDeleteService(int serverIf, int svcHandle) { gattServerDeleteServiceNative(serverIf, svcHandle); } - /** - * Send an indication of the characteristic - */ - public void gattServerSendIndication(int serverIf, int attrHandle, int connId, - byte[] val) { + /** Send an indication of the characteristic */ + public void gattServerSendIndication(int serverIf, int attrHandle, int connId, byte[] val) { gattServerSendIndicationNative(serverIf, attrHandle, connId, val); } - /** - * Send a notification of the characteristic - */ - public void gattServerSendNotification(int serverIf, int attrHandle, int connId, - byte[] val) { + /** Send a notification of the characteristic */ + public void gattServerSendNotification(int serverIf, int attrHandle, int connId, byte[] val) { gattServerSendNotificationNative(serverIf, attrHandle, connId, val); } - /** - * Send a response as a GATT server role - */ - public void gattServerSendResponse(int serverIf, int connId, int transId, - int status, int handle, int offset, byte[] val, int authReq) { - gattServerSendResponseNative(serverIf, connId, transId, status, handle, offset, val, - authReq); - } - - /** - * Send a test command - */ - public void gattTest(int command, long uuid1Lsb, long uuid1Msb, String bda1, - int p1, int p2, int p3, int p4, int p5) { + /** Send a response as a GATT server role */ + public void gattServerSendResponse( + int serverIf, + int connId, + int transId, + int status, + int handle, + int offset, + byte[] val, + int authReq) { + gattServerSendResponseNative( + serverIf, connId, transId, status, handle, offset, val, authReq); + } + + /** Send a test command */ + public void gattTest( + int command, + long uuid1Lsb, + long uuid1Msb, + String bda1, + int p1, + int p2, + int p3, + int p4, + int p5) { gattTestNative(command, uuid1Lsb, uuid1Msb, bda1, p1, p2, p3, p4, p5); } } - diff --git a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java index 0a02c2d142f..9fc589afa9b 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java +++ b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java @@ -28,16 +28,13 @@ import com.android.bluetooth.le_scan.ScanManager; import com.android.bluetooth.le_scan.ScanNativeInterface; import com.android.bluetooth.le_scan.TransitionalScanHelper; -/** - * Factory class for object initialization to help with unit testing - */ +/** Factory class for object initialization to help with unit testing */ public class GattObjectsFactory { private static final String TAG = GattObjectsFactory.class.getSimpleName(); private static GattObjectsFactory sInstance; private static final Object INSTANCE_LOCK = new Object(); - private GattObjectsFactory() { - } + private GattObjectsFactory() {} /** * Get the singleton instance of object factory diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java index 82230a6b20f..6e6518c9169 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattService.java +++ b/android/app/src/com/android/bluetooth/gatt/GattService.java @@ -96,10 +96,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -/** - * Provides Bluetooth Gatt profile, as a service in - * the Bluetooth application. - */ +/** Provides Bluetooth Gatt profile, as a service in the Bluetooth application. */ public class GattService extends ProfileService { private static final String TAG = GattServiceConfig.TAG_PREFIX + "GattService"; @@ -107,10 +104,10 @@ public class GattService extends ProfileService { UUID.fromString("00001812-0000-1000-8000-00805F9B34FB"); private static final UUID[] HID_UUIDS = { - UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"), - UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"), - UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"), - UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB") + UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"), + UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"), + UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"), + UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB") }; private static final UUID ANDROID_TV_REMOTE_SERVICE_UUID = @@ -120,14 +117,14 @@ public class GattService extends ProfileService { UUID.fromString("0000FFFD-0000-1000-8000-00805F9B34FB"); // U2F private static final UUID[] LE_AUDIO_SERVICE_UUIDS = { - UUID.fromString("00001844-0000-1000-8000-00805F9B34FB"), // VCS - UUID.fromString("00001845-0000-1000-8000-00805F9B34FB"), // VOCS - UUID.fromString("00001843-0000-1000-8000-00805F9B34FB"), // AICS - UUID.fromString("00001850-0000-1000-8000-00805F9B34FB"), // PACS - UUID.fromString("0000184E-0000-1000-8000-00805F9B34FB"), // ASCS - UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB"), // BASS - UUID.fromString("00001854-0000-1000-8000-00805F9B34FB"), // HAP - UUID.fromString("00001846-0000-1000-8000-00805F9B34FB"), // CSIS + UUID.fromString("00001844-0000-1000-8000-00805F9B34FB"), // VCS + UUID.fromString("00001845-0000-1000-8000-00805F9B34FB"), // VOCS + UUID.fromString("00001843-0000-1000-8000-00805F9B34FB"), // AICS + UUID.fromString("00001850-0000-1000-8000-00805F9B34FB"), // PACS + UUID.fromString("0000184E-0000-1000-8000-00805F9B34FB"), // ASCS + UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB"), // BASS + UUID.fromString("00001854-0000-1000-8000-00805F9B34FB"), // HAP + UUID.fromString("00001846-0000-1000-8000-00805F9B34FB"), // CSIS }; /** Example raw beacons captured from a Blue Charm BC011 */ @@ -143,31 +140,24 @@ public class GattService extends ProfileService { public final TransitionalScanHelper mTransitionalScanHelper = new TransitionalScanHelper(this, this::isTestModeEnabled); - /** - * List of our registered advertisers. - */ + /** List of our registered advertisers. */ static class AdvertiserMap extends ContextMap {} private AdvertiserMap mAdvertiserMap = new AdvertiserMap(); - /** - * List of our registered clients. - */ + /** List of our registered clients. */ class ClientMap extends ContextMap {} ClientMap mClientMap = new ClientMap(); - /** - * List of our registered server apps. - */ + /** List of our registered server apps. */ class ServerMap extends ContextMap {} ServerMap mServerMap = new ServerMap(); - /** - * Server handle map. - */ + /** Server handle map. */ HandleMap mHandleMap = new HandleMap(); + private List mAdvertisingServiceUuids = new ArrayList(); /** @@ -197,11 +187,8 @@ public class GattService extends ProfileService { return BluetoothProperties.isProfileGattEnabled().orElse(true); } - /** - * Reliable write queue - */ - @VisibleForTesting - Set mReliableQueue = new HashSet(); + /** Reliable write queue */ + @VisibleForTesting Set mReliableQueue = new HashSet(); private GattNativeInterface mNativeInterface; @@ -221,17 +208,15 @@ public class GattService extends ProfileService { mAdapterService = AdapterService.getAdapterService(); mAdvertiseManager = new AdvertiseManager( - this, - AdvertiseManagerNativeInterface.getInstance(), - mAdvertiserMap); + this, AdvertiseManagerNativeInterface.getInstance(), mAdvertiserMap); if (!Flags.scanManagerRefactor()) { HandlerThread thread = new HandlerThread("BluetoothScanManager"); thread.start(); mTransitionalScanHelper.start(thread.getLooper()); } - mDistanceMeasurementManager = GattObjectsFactory.getInstance() - .createDistanceMeasurementManager(mAdapterService); + mDistanceMeasurementManager = + GattObjectsFactory.getInstance().createDistanceMeasurementManager(mAdapterService); mActivityManager = getSystemService(ActivityManager.class); mPackageManager = mAdapterService.getPackageManager(); @@ -357,11 +342,7 @@ public class GattService extends ProfileService { public void binderDied() { Log.d( TAG, - "Binder is dead - unregistering server (" - + mPackageName - + " " - + mAppIf - + ")!"); + "Binder is dead - unregistering server (" + mPackageName + " " + mAppIf + ")!"); unregisterServer(mAppIf, getAttributionSource()); } } @@ -379,21 +360,14 @@ public class GattService extends ProfileService { public void binderDied() { Log.d( TAG, - "Binder is dead - unregistering client (" - + mPackageName - + " " - + mAppIf - + ")!"); + "Binder is dead - unregistering client (" + mPackageName + " " + mAppIf + ")!"); unregisterClient(mAppIf, getAttributionSource()); } } - /** - * Handlers for incoming service calls - */ + /** Handlers for incoming service calls */ @VisibleForTesting - static class BluetoothGattBinder extends IBluetoothGatt.Stub - implements IProfileServiceBinder { + static class BluetoothGattBinder extends IBluetoothGatt.Stub implements IProfileServiceBinder { private GattService mService; BluetoothGattBinder(GattService svc) { @@ -469,7 +443,10 @@ public class GattService extends ProfileService { } @Override - public void startScan(int scannerId, ScanSettings settings, List filters, + public void startScan( + int scannerId, + ScanSettings settings, + List filters, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -535,13 +512,20 @@ public class GattService extends ProfileService { if (service == null) { return; } - service.clientConnect(clientIf, address, addressType, isDirect, transport, - opportunistic, phy, attributionSource); + service.clientConnect( + clientIf, + address, + addressType, + isDirect, + transport, + opportunistic, + phy, + attributionSource); } @Override - public void clientDisconnect(int clientIf, String address, - AttributionSource attributionSource) { + public void clientDisconnect( + int clientIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -550,19 +534,24 @@ public class GattService extends ProfileService { } @Override - public void clientSetPreferredPhy(int clientIf, String address, int txPhy, int rxPhy, - int phyOptions, AttributionSource attributionSource) { + public void clientSetPreferredPhy( + int clientIf, + String address, + int txPhy, + int rxPhy, + int phyOptions, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; } - service.clientSetPreferredPhy(clientIf, address, txPhy, rxPhy, phyOptions, - attributionSource); + service.clientSetPreferredPhy( + clientIf, address, txPhy, rxPhy, phyOptions, attributionSource); } @Override - public void clientReadPhy(int clientIf, String address, - AttributionSource attributionSource) { + public void clientReadPhy( + int clientIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -571,8 +560,8 @@ public class GattService extends ProfileService { } @Override - public void refreshDevice(int clientIf, String address, - AttributionSource attributionSource) { + public void refreshDevice( + int clientIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -581,8 +570,8 @@ public class GattService extends ProfileService { } @Override - public void discoverServices(int clientIf, String address, - AttributionSource attributionSource) { + public void discoverServices( + int clientIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -591,7 +580,10 @@ public class GattService extends ProfileService { } @Override - public void discoverServiceByUuid(int clientIf, String address, ParcelUuid uuid, + public void discoverServiceByUuid( + int clientIf, + String address, + ParcelUuid uuid, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -601,7 +593,11 @@ public class GattService extends ProfileService { } @Override - public void readCharacteristic(int clientIf, String address, int handle, int authReq, + public void readCharacteristic( + int clientIf, + String address, + int handle, + int authReq, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -611,14 +607,26 @@ public class GattService extends ProfileService { } @Override - public void readUsingCharacteristicUuid(int clientIf, String address, ParcelUuid uuid, - int startHandle, int endHandle, int authReq, AttributionSource attributionSource) { + public void readUsingCharacteristicUuid( + int clientIf, + String address, + ParcelUuid uuid, + int startHandle, + int endHandle, + int authReq, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; } - service.readUsingCharacteristicUuid(clientIf, address, uuid.getUuid(), startHandle, - endHandle, authReq, attributionSource); + service.readUsingCharacteristicUuid( + clientIf, + address, + uuid.getUuid(), + startHandle, + endHandle, + authReq, + attributionSource); } @Override @@ -634,12 +642,16 @@ public class GattService extends ProfileService { if (service == null) { return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND; } - return service.writeCharacteristic(clientIf, address, handle, writeType, authReq, value, - attributionSource); + return service.writeCharacteristic( + clientIf, address, handle, writeType, authReq, value, attributionSource); } @Override - public void readDescriptor(int clientIf, String address, int handle, int authReq, + public void readDescriptor( + int clientIf, + String address, + int handle, + int authReq, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -660,13 +672,13 @@ public class GattService extends ProfileService { if (service == null) { return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND; } - return service.writeDescriptor(clientIf, address, handle, authReq, value, - attributionSource); + return service.writeDescriptor( + clientIf, address, handle, authReq, value, attributionSource); } @Override - public void beginReliableWrite(int clientIf, String address, - AttributionSource attributionSource) { + public void beginReliableWrite( + int clientIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -675,7 +687,10 @@ public class GattService extends ProfileService { } @Override - public void endReliableWrite(int clientIf, String address, boolean execute, + public void endReliableWrite( + int clientIf, + String address, + boolean execute, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -685,8 +700,12 @@ public class GattService extends ProfileService { } @Override - public void registerForNotification(int clientIf, String address, int handle, - boolean enable, AttributionSource attributionSource) { + public void registerForNotification( + int clientIf, + String address, + int handle, + boolean enable, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -695,8 +714,8 @@ public class GattService extends ProfileService { } @Override - public void readRemoteRssi(int clientIf, String address, - AttributionSource attributionSource) { + public void readRemoteRssi( + int clientIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -705,8 +724,8 @@ public class GattService extends ProfileService { } @Override - public void configureMTU(int clientIf, String address, int mtu, - AttributionSource attributionSource) { + public void configureMTU( + int clientIf, String address, int mtu, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -715,8 +734,11 @@ public class GattService extends ProfileService { } @Override - public void connectionParameterUpdate(int clientIf, String address, - int connectionPriority, AttributionSource attributionSource) { + public void connectionParameterUpdate( + int clientIf, + String address, + int connectionPriority, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -726,23 +748,37 @@ public class GattService extends ProfileService { } @Override - public void leConnectionUpdate(int clientIf, String address, - int minConnectionInterval, int maxConnectionInterval, - int peripheralLatency, int supervisionTimeout, - int minConnectionEventLen, int maxConnectionEventLen, + public void leConnectionUpdate( + int clientIf, + String address, + int minConnectionInterval, + int maxConnectionInterval, + int peripheralLatency, + int supervisionTimeout, + int minConnectionEventLen, + int maxConnectionEventLen, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; } - service.leConnectionUpdate(clientIf, address, minConnectionInterval, - maxConnectionInterval, peripheralLatency, - supervisionTimeout, minConnectionEventLen, - maxConnectionEventLen, attributionSource); + service.leConnectionUpdate( + clientIf, + address, + minConnectionInterval, + maxConnectionInterval, + peripheralLatency, + supervisionTimeout, + minConnectionEventLen, + maxConnectionEventLen, + attributionSource); } @Override - public void subrateModeRequest(int clientIf, String address, int subrateMode, + public void subrateModeRequest( + int clientIf, + String address, + int subrateMode, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -752,15 +788,28 @@ public class GattService extends ProfileService { } @Override - public void leSubrateRequest(int clientIf, String address, int subrateMin, int subrateMax, - int maxLatency, int contNumber, int supervisionTimeout, + public void leSubrateRequest( + int clientIf, + String address, + int subrateMin, + int subrateMax, + int maxLatency, + int contNumber, + int supervisionTimeout, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; } - service.leSubrateRequest(clientIf, address, subrateMin, subrateMax, maxLatency, - contNumber, supervisionTimeout, attributionSource); + service.leSubrateRequest( + clientIf, + address, + subrateMin, + subrateMax, + maxLatency, + contNumber, + supervisionTimeout, + attributionSource); } @Override @@ -802,8 +851,8 @@ public class GattService extends ProfileService { } @Override - public void serverDisconnect(int serverIf, String address, - AttributionSource attributionSource) { + public void serverDisconnect( + int serverIf, String address, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -812,8 +861,13 @@ public class GattService extends ProfileService { } @Override - public void serverSetPreferredPhy(int serverIf, String address, int txPhy, int rxPhy, - int phyOptions, AttributionSource attributionSource) { + public void serverSetPreferredPhy( + int serverIf, + String address, + int txPhy, + int rxPhy, + int phyOptions, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -833,8 +887,8 @@ public class GattService extends ProfileService { } @Override - public void addService(int serverIf, BluetoothGattService svc, - AttributionSource attributionSource) { + public void addService( + int serverIf, BluetoothGattService svc, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -861,8 +915,14 @@ public class GattService extends ProfileService { } @Override - public void sendResponse(int serverIf, String address, int requestId, int status, - int offset, byte[] value, AttributionSource attributionSource) { + public void sendResponse( + int serverIf, + String address, + int requestId, + int status, + int offset, + byte[] value, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -883,27 +943,42 @@ public class GattService extends ProfileService { if (service == null) { return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND; } - return service.sendNotification(serverIf, address, handle, confirm, value, - attributionSource); + return service.sendNotification( + serverIf, address, handle, confirm, value, attributionSource); } @Override - public void startAdvertisingSet(AdvertisingSetParameters parameters, - AdvertiseData advertiseData, AdvertiseData scanResponse, - PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData, - int duration, int maxExtAdvEvents, int serverIf, IAdvertisingSetCallback callback, + public void startAdvertisingSet( + AdvertisingSetParameters parameters, + AdvertiseData advertiseData, + AdvertiseData scanResponse, + PeriodicAdvertisingParameters periodicParameters, + AdvertiseData periodicData, + int duration, + int maxExtAdvEvents, + int serverIf, + IAdvertisingSetCallback callback, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; } - service.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters, - periodicData, duration, maxExtAdvEvents, serverIf, callback, attributionSource); + service.startAdvertisingSet( + parameters, + advertiseData, + scanResponse, + periodicParameters, + periodicData, + duration, + maxExtAdvEvents, + serverIf, + callback, + attributionSource); } @Override - public void stopAdvertisingSet(IAdvertisingSetCallback callback, - AttributionSource attributionSource) { + public void stopAdvertisingSet( + IAdvertisingSetCallback callback, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -921,8 +996,12 @@ public class GattService extends ProfileService { } @Override - public void enableAdvertisingSet(int advertiserId, boolean enable, int duration, - int maxExtAdvEvents, AttributionSource attributionSource) { + public void enableAdvertisingSet( + int advertiserId, + boolean enable, + int duration, + int maxExtAdvEvents, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -932,8 +1011,8 @@ public class GattService extends ProfileService { } @Override - public void setAdvertisingData(int advertiserId, AdvertiseData data, - AttributionSource attributionSource) { + public void setAdvertisingData( + int advertiserId, AdvertiseData data, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -942,8 +1021,8 @@ public class GattService extends ProfileService { } @Override - public void setScanResponseData(int advertiserId, AdvertiseData data, - AttributionSource attributionSource) { + public void setScanResponseData( + int advertiserId, AdvertiseData data, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -952,8 +1031,10 @@ public class GattService extends ProfileService { } @Override - public void setAdvertisingParameters(int advertiserId, - AdvertisingSetParameters parameters, AttributionSource attributionSource) { + public void setAdvertisingParameters( + int advertiserId, + AdvertisingSetParameters parameters, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -962,8 +1043,10 @@ public class GattService extends ProfileService { } @Override - public void setPeriodicAdvertisingParameters(int advertiserId, - PeriodicAdvertisingParameters parameters, AttributionSource attributionSource) { + public void setPeriodicAdvertisingParameters( + int advertiserId, + PeriodicAdvertisingParameters parameters, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -972,8 +1055,8 @@ public class GattService extends ProfileService { } @Override - public void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data, - AttributionSource attributionSource) { + public void setPeriodicAdvertisingData( + int advertiserId, AdvertiseData data, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -982,8 +1065,8 @@ public class GattService extends ProfileService { } @Override - public void setPeriodicAdvertisingEnable(int advertiserId, boolean enable, - AttributionSource attributionSource) { + public void setPeriodicAdvertisingEnable( + int advertiserId, boolean enable, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -992,8 +1075,12 @@ public class GattService extends ProfileService { } @Override - public void registerSync(ScanResult scanResult, int skip, int timeout, - IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) { + public void registerSync( + ScanResult scanResult, + int skip, + int timeout, + IPeriodicAdvertisingCallback callback, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -1003,7 +1090,10 @@ public class GattService extends ProfileService { } @Override - public void transferSync(BluetoothDevice bda, int serviceData , int syncHandle, + public void transferSync( + BluetoothDevice bda, + int serviceData, + int syncHandle, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { @@ -1014,8 +1104,12 @@ public class GattService extends ProfileService { } @Override - public void transferSetInfo(BluetoothDevice bda, int serviceData , int advHandle, - IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) { + public void transferSetInfo( + BluetoothDevice bda, + int serviceData, + int advHandle, + IPeriodicAdvertisingCallback callback, + AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -1025,8 +1119,8 @@ public class GattService extends ProfileService { } @Override - public void unregisterSync(IPeriodicAdvertisingCallback callback, - AttributionSource attributionSource) { + public void unregisterSync( + IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; @@ -1057,11 +1151,13 @@ public class GattService extends ProfileService { public List getSupportedDistanceMeasurementMethods( AttributionSource attributionSource) { GattService service = getService(); - if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, - "GattService getSupportedDistanceMeasurementMethods") + if (service == null + || !callerIsSystemOrActiveOrManagedUser( + service, TAG, "GattService getSupportedDistanceMeasurementMethods") || !Utils.checkConnectPermissionForDataDelivery( - service, attributionSource, - "GattService getSupportedDistanceMeasurementMethods")) { + service, + attributionSource, + "GattService getSupportedDistanceMeasurementMethods")) { return Collections.emptyList(); } enforceBluetoothPrivilegedPermission(service); @@ -1069,13 +1165,17 @@ public class GattService extends ProfileService { } @Override - public void startDistanceMeasurement(ParcelUuid uuid, + public void startDistanceMeasurement( + ParcelUuid uuid, DistanceMeasurementParams distanceMeasurementParams, - IDistanceMeasurementCallback callback, AttributionSource attributionSource) { + IDistanceMeasurementCallback callback, + AttributionSource attributionSource) { GattService service = getService(); - if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, - "startDistanceMeasurement") || !Utils.checkConnectPermissionForDataDelivery( - service, attributionSource, "GattService startDistanceMeasurement")) { + if (service == null + || !callerIsSystemOrActiveOrManagedUser( + service, TAG, "startDistanceMeasurement") + || !Utils.checkConnectPermissionForDataDelivery( + service, attributionSource, "GattService startDistanceMeasurement")) { return; } enforceBluetoothPrivilegedPermission(service); @@ -1091,8 +1191,8 @@ public class GattService extends ProfileService { GattService service = getService(); if (service == null) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; - } else if (!callerIsSystemOrActiveOrManagedUser(service, TAG, - "stopDistanceMeasurement")) { + } else if (!callerIsSystemOrActiveOrManagedUser( + service, TAG, "stopDistanceMeasurement")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } else if (!Utils.checkConnectPermissionForDataDelivery( service, attributionSource, "GattService stopDistanceMeasurement")) { @@ -1137,7 +1237,8 @@ public class GattService extends ProfileService { enforceBluetoothPrivilegedPermission(service); return service.getLocalChannelSoundingMaxSupportedSecurityLevel(); } - }; + } + ; /************************************************************************** * Callback functions - CLIENT @@ -1160,25 +1261,29 @@ public class GattService extends ProfileService { } void onConnected(int clientIf, int connId, int status, String address) throws RemoteException { - Log.d(TAG, "onConnected() - clientIf=" + clientIf + ", connId=" + connId + ", address=" - + address); + Log.d( + TAG, + "onConnected() - clientIf=" + + clientIf + + ", connId=" + + connId + + ", address=" + + address); int connectionState = BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED; if (status == 0) { mClientMap.addConnection(clientIf, connId, address); // Allow one writeCharacteristic operation at a time for each connected remote device. synchronized (mPermits) { - Log.d(TAG, "onConnected() - adding permit for address=" - + address); + Log.d(TAG, "onConnected() - adding permit for address=" + address); mPermits.putIfAbsent(address, -1); } connectionState = BluetoothProtoEnums.CONNECTION_STATE_CONNECTED; - } ClientMap.App app = mClientMap.getById(clientIf); if (app != null) { - app.callback.onClientConnectionState(status, clientIf, - (status == BluetoothGatt.GATT_SUCCESS), address); + app.callback.onClientConnectionState( + status, clientIf, (status == BluetoothGatt.GATT_SUCCESS), address); } statsLogGattConnectionStateChange( BluetoothProfile.GATT, address, clientIf, connectionState, status); @@ -1186,8 +1291,13 @@ public class GattService extends ProfileService { void onDisconnected(int clientIf, int connId, int status, String address) throws RemoteException { - Log.d(TAG, - "onDisconnected() - clientIf=" + clientIf + ", connId=" + connId + ", address=" + Log.d( + TAG, + "onDisconnected() - clientIf=" + + clientIf + + ", connId=" + + connId + + ", address=" + address); mClientMap.removeConnection(clientIf, connId); @@ -1197,11 +1307,11 @@ public class GattService extends ProfileService { mRestrictedHandles.remove(connId); } - // Remove AtomicBoolean representing permit if no other connections rely on this remote device. + // Remove AtomicBoolean representing permit if no other connections rely on this remote + // device. if (!mClientMap.getConnectedDevices().contains(address)) { synchronized (mPermits) { - Log.d(TAG, "onDisconnected() - removing permit for address=" - + address); + Log.d(TAG, "onDisconnected() - removing permit for address=" + address); mPermits.remove(address); } } else { @@ -1217,8 +1327,11 @@ public class GattService extends ProfileService { app.callback.onClientConnectionState(status, clientIf, false, address); } statsLogGattConnectionStateChange( - BluetoothProfile.GATT, address, clientIf, - BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED, status); + BluetoothProfile.GATT, + address, + clientIf, + BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED, + status); } void onClientPhyUpdate(int connId, int txPhy, int rxPhy, int status) throws RemoteException { @@ -1239,8 +1352,13 @@ public class GattService extends ProfileService { void onClientPhyRead(int clientIf, String address, int txPhy, int rxPhy, int status) throws RemoteException { - Log.d(TAG, - "onClientPhyRead() - address=" + address + ", status=" + status + ", clientIf=" + Log.d( + TAG, + "onClientPhyRead() - address=" + + address + + ", status=" + + status + + ", clientIf=" + clientIf); Integer connId = mClientMap.connIdByAddress(clientIf, address); @@ -1290,8 +1408,9 @@ public class GattService extends ProfileService { app.callback.onServiceChanged(address); } - void onClientSubrateChange(int connId, int subrateFactor, int latency, int contNum, - int timeout, int status) throws RemoteException { + void onClientSubrateChange( + int connId, int subrateFactor, int latency, int contNum, int timeout, int status) + throws RemoteException { Log.d(TAG, "onClientSubrateChange() - connId=" + connId + ", status=" + status); String address = mClientMap.addressByConnId(connId); @@ -1358,8 +1477,8 @@ public class GattService extends ProfileService { app.callback.onConnectionUpdated(address, interval, latency, timeout, status); } - void onServerSubrateChange(int connId, int subrateFactor, int latency, int contNum, - int timeout, int status) + void onServerSubrateChange( + int connId, int subrateFactor, int latency, int contNum, int timeout, int status) throws RemoteException { Log.d(TAG, "onServerSubrateChange() - connId=" + connId + ", status=" + status); @@ -1382,12 +1501,14 @@ public class GattService extends ProfileService { // This callback was called from the jni_workqueue thread. If we make request to the stack // on the same thread, it might cause deadlock. Schedule request on a new thread instead. - Thread t = new Thread(new Runnable() { - @Override - public void run() { - mNativeInterface.gattClientGetGattDb(connId); - } - }); + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + mNativeInterface.gattClientGetGattDb(connId); + } + }); t.start(); } @@ -1451,16 +1572,28 @@ public class GattService extends ProfileService { break; case GattDbElement.TYPE_INCLUDED_SERVICE: - Log.d(TAG, "got included service with UUID=" + el.uuid + " id: " + el.id - + " startHandle: " + el.startHandle); + Log.d( + TAG, + "got included service with UUID=" + + el.uuid + + " id: " + + el.id + + " startHandle: " + + el.startHandle); currSrvc.addIncludedService( new BluetoothGattService(el.uuid, el.startHandle, el.type)); break; default: - Log.e(TAG, "got unknown element with type=" + el.type + " and UUID=" + el.uuid - + " id: " + el.id); + Log.e( + TAG, + "got unknown element with type=" + + el.type + + " and UUID=" + + el.uuid + + " id: " + + el.id); } } @@ -1474,15 +1607,29 @@ public class GattService extends ProfileService { void onRegisterForNotifications(int connId, int status, int registered, int handle) { String address = mClientMap.addressByConnId(connId); - Log.d(TAG, "onRegisterForNotifications() - address=" + address + ", status=" + status - + ", registered=" + registered + ", handle=" + handle); + Log.d( + TAG, + "onRegisterForNotifications() - address=" + + address + + ", status=" + + status + + ", registered=" + + registered + + ", handle=" + + handle); } void onNotify(int connId, String address, int handle, boolean isNotify, byte[] data) throws RemoteException { - Log.v(TAG, "onNotify() - address=" + address + ", handle=" + handle + ", length=" - + data.length); + Log.v( + TAG, + "onNotify() - address=" + + address + + ", handle=" + + handle + + ", length=" + + data.length); ClientMap.App app = mClientMap.getByConnId(connId); if (app != null) { @@ -1504,8 +1651,14 @@ public class GattService extends ProfileService { throws RemoteException { String address = mClientMap.addressByConnId(connId); - Log.v(TAG, "onReadCharacteristic() - address=" + address + ", status=" + status - + ", length=" + data.length); + Log.v( + TAG, + "onReadCharacteristic() - address=" + + address + + ", status=" + + status + + ", length=" + + data.length); ClientMap.App app = mClientMap.getByConnId(connId); if (app != null) { @@ -1517,13 +1670,18 @@ public class GattService extends ProfileService { throws RemoteException { String address = mClientMap.addressByConnId(connId); synchronized (mPermits) { - Log.d(TAG, "onWriteCharacteristic() - increasing permit for address=" - + address); + Log.d(TAG, "onWriteCharacteristic() - increasing permit for address=" + address); mPermits.put(address, -1); } - Log.v(TAG, "onWriteCharacteristic() - address=" + address + ", status=" + status - + ", length=" + data.length); + Log.v( + TAG, + "onWriteCharacteristic() - address=" + + address + + ", status=" + + status + + ", length=" + + data.length); ClientMap.App app = mClientMap.getByConnId(connId); if (app == null) { @@ -1536,10 +1694,11 @@ public class GattService extends ProfileService { if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) { status = BluetoothGatt.GATT_SUCCESS; } - CallbackInfo callbackInfo = new CallbackInfo.Builder(address, status) - .setHandle(handle) - .setValue(data) - .build(); + CallbackInfo callbackInfo = + new CallbackInfo.Builder(address, status) + .setHandle(handle) + .setValue(data) + .build(); app.queueCallback(callbackInfo); } } @@ -1557,8 +1716,13 @@ public class GattService extends ProfileService { void onReadDescriptor(int connId, int status, int handle, byte[] data) throws RemoteException { String address = mClientMap.addressByConnId(connId); - Log.v(TAG, - "onReadDescriptor() - address=" + address + ", status=" + status + ", length=" + Log.v( + TAG, + "onReadDescriptor() - address=" + + address + + ", status=" + + status + + ", length=" + data.length); ClientMap.App app = mClientMap.getByConnId(connId); @@ -1567,12 +1731,17 @@ public class GattService extends ProfileService { } } - void onWriteDescriptor(int connId, int status, int handle, byte[] data) - throws RemoteException { + void onWriteDescriptor(int connId, int status, int handle, byte[] data) throws RemoteException { String address = mClientMap.addressByConnId(connId); - Log.v(TAG, "onWriteDescriptor() - address=" + address + ", status=" + status - + ", length=" + data.length); + Log.v( + TAG, + "onWriteDescriptor() - address=" + + address + + ", status=" + + status + + ", length=" + + data.length); ClientMap.App app = mClientMap.getByConnId(connId); if (app != null) { @@ -1582,9 +1751,16 @@ public class GattService extends ProfileService { void onReadRemoteRssi(int clientIf, String address, int rssi, int status) throws RemoteException { - Log.d(TAG, - "onReadRemoteRssi() - clientIf=" + clientIf + " address=" + address + ", rssi=" - + rssi + ", status=" + status); + Log.d( + TAG, + "onReadRemoteRssi() - clientIf=" + + clientIf + + " address=" + + address + + ", rssi=" + + rssi + + ", status=" + + status); ClientMap.App app = mClientMap.getById(clientIf); if (app != null) { @@ -1595,8 +1771,7 @@ public class GattService extends ProfileService { void onConfigureMTU(int connId, int status, int mtu) throws RemoteException { String address = mClientMap.addressByConnId(connId); - Log.d(TAG, - "onConfigureMTU() address=" + address + ", status=" + status + ", mtu=" + mtu); + Log.d(TAG, "onConfigureMTU() address=" + address + ", status=" + status + ", mtu=" + mtu); ClientMap.App app = mClientMap.getByConnId(connId); if (app != null) { @@ -1616,8 +1791,11 @@ public class GattService extends ProfileService { if (callbackInfo == null) { return; } - app.callback.onCharacteristicWrite(callbackInfo.address, callbackInfo.status, - callbackInfo.handle, callbackInfo.value); + app.callback.onCharacteristicWrite( + callbackInfo.address, + callbackInfo.status, + callbackInfo.handle, + callbackInfo.value); } } } @@ -1630,8 +1808,7 @@ public class GattService extends ProfileService { List getDevicesMatchingConnectionStates( int[] states, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( - this, attributionSource, - "GattService getDevicesMatchingConnectionStates")) { + this, attributionSource, "GattService getDevicesMatchingConnectionStates")) { return Collections.emptyList(); } @@ -1681,7 +1858,7 @@ public class GattService extends ProfileService { for (Map.Entry entry : connMap.entrySet()) { Log.d(TAG, "disconnecting addr:" + entry.getValue()); clientDisconnect(entry.getKey(), entry.getValue(), attributionSource); - //clientDisconnect(int clientIf, String address) + // clientDisconnect(int clientIf, String address) } } @@ -1697,10 +1874,17 @@ public class GattService extends ProfileService { * ADVERTISING SET *************************************************************************/ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) - void startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData, - AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters, - AdvertiseData periodicData, int duration, int maxExtAdvEvents, int serverIf, - IAdvertisingSetCallback callback, AttributionSource attributionSource) { + void startAdvertisingSet( + AdvertisingSetParameters parameters, + AdvertiseData advertiseData, + AdvertiseData scanResponse, + PeriodicAdvertisingParameters periodicParameters, + AdvertiseData periodicData, + int duration, + int maxExtAdvEvents, + int serverIf, + IAdvertisingSetCallback callback, + AttributionSource attributionSource) { if (!Utils.checkAdvertisePermissionForDataDelivery( this, attributionSource, "GattService startAdvertisingSet")) { return; @@ -1709,8 +1893,16 @@ public class GattService extends ProfileService { || serverIf != 0) { Utils.enforceBluetoothPrivilegedPermission(this); } - mAdvertiseManager.startAdvertisingSet(parameters, advertiseData, scanResponse, - periodicParameters, periodicData, duration, maxExtAdvEvents, serverIf, callback); + mAdvertiseManager.startAdvertisingSet( + parameters, + advertiseData, + scanResponse, + periodicParameters, + periodicData, + duration, + maxExtAdvEvents, + serverIf, + callback); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) @@ -1722,10 +1914,11 @@ public class GattService extends ProfileService { mAdvertiseManager.stopAdvertisingSet(callback); } - @RequiresPermission(allOf = { - android.Manifest.permission.BLUETOOTH_ADVERTISE, - android.Manifest.permission.BLUETOOTH_PRIVILEGED, - }) + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_ADVERTISE, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) void getOwnAddress(int advertiserId, AttributionSource attributionSource) { if (!Utils.checkAdvertisePermissionForDataDelivery( this, attributionSource, "GattService getOwnAddress")) { @@ -1736,7 +1929,11 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) - void enableAdvertisingSet(int advertiserId, boolean enable, int duration, int maxExtAdvEvents, + void enableAdvertisingSet( + int advertiserId, + boolean enable, + int duration, + int maxExtAdvEvents, AttributionSource attributionSource) { if (!Utils.checkAdvertisePermissionForDataDelivery( this, attributionSource, "GattService enableAdvertisingSet")) { @@ -1766,7 +1963,9 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) - void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters, + void setAdvertisingParameters( + int advertiserId, + AdvertisingSetParameters parameters, AttributionSource attributionSource) { if (!Utils.checkAdvertisePermissionForDataDelivery( this, attributionSource, "GattService setAdvertisingParameters")) { @@ -1776,8 +1975,10 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) - void setPeriodicAdvertisingParameters(int advertiserId, - PeriodicAdvertisingParameters parameters, AttributionSource attributionSource) { + void setPeriodicAdvertisingParameters( + int advertiserId, + PeriodicAdvertisingParameters parameters, + AttributionSource attributionSource) { if (!Utils.checkAdvertisePermissionForDataDelivery( this, attributionSource, "GattService setPeriodicAdvertisingParameters")) { return; @@ -1813,12 +2014,12 @@ public class GattService extends ProfileService { return mDistanceMeasurementManager.getSupportedDistanceMeasurementMethods(); } - - void startDistanceMeasurement(UUID uuid, + void startDistanceMeasurement( + UUID uuid, DistanceMeasurementParams distanceMeasurementParams, IDistanceMeasurementCallback callback) { - mDistanceMeasurementManager.startDistanceMeasurement(uuid, distanceMeasurementParams, - callback); + mDistanceMeasurementManager.startDistanceMeasurement( + uuid, distanceMeasurementParams, callback); } int stopDistanceMeasurement(UUID uuid, BluetoothDevice device, int method) { @@ -1839,7 +2040,10 @@ public class GattService extends ProfileService { *************************************************************************/ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void registerClient(UUID uuid, IBluetoothGattCallback callback, boolean eatt_support, + void registerClient( + UUID uuid, + IBluetoothGattCallback callback, + boolean eatt_support, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService registerClient")) { @@ -1848,8 +2052,8 @@ public class GattService extends ProfileService { Log.d(TAG, "registerClient() - UUID=" + uuid); mClientMap.add(uuid, null, callback, null, this, mTransitionalScanHelper); - mNativeInterface.gattClientRegisterApp(uuid.getLeastSignificantBits(), - uuid.getMostSignificantBits(), eatt_support); + mNativeInterface.gattClientRegisterApp( + uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(), eatt_support); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) @@ -1865,25 +2069,44 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void clientConnect(int clientIf, String address, int addressType, boolean isDirect, - int transport, boolean opportunistic, int phy, AttributionSource attributionSource) { + void clientConnect( + int clientIf, + String address, + int addressType, + boolean isDirect, + int transport, + boolean opportunistic, + int phy, + AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService clientConnect")) { return; } - Log.d(TAG, "clientConnect() - address=" + address + ", addressType=" - + addressType + ", isDirect=" + isDirect + ", opportunistic=" - + opportunistic + ", phy=" + phy); + Log.d( + TAG, + "clientConnect() - address=" + + address + + ", addressType=" + + addressType + + ", isDirect=" + + isDirect + + ", opportunistic=" + + opportunistic + + ", phy=" + + phy); statsLogAppPackage(address, attributionSource.getUid(), clientIf); logClientForegroundInfo(attributionSource.getUid(), isDirect); statsLogGattConnectionStateChange( - BluetoothProfile.GATT, address, clientIf, - BluetoothProtoEnums.CONNECTION_STATE_CONNECTING, -1); - mNativeInterface.gattClientConnect(clientIf, address, addressType, isDirect, transport, - opportunistic, phy); + BluetoothProfile.GATT, + address, + clientIf, + BluetoothProtoEnums.CONNECTION_STATE_CONNECTING, + -1); + mNativeInterface.gattClientConnect( + clientIf, address, addressType, isDirect, transport, opportunistic, phy); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) @@ -1896,13 +2119,21 @@ public class GattService extends ProfileService { Integer connId = mClientMap.connIdByAddress(clientIf, address); Log.d(TAG, "clientDisconnect() - address=" + address + ", connId=" + connId); statsLogGattConnectionStateChange( - BluetoothProfile.GATT, address, clientIf, - BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING, -1); + BluetoothProfile.GATT, + address, + clientIf, + BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING, + -1); mNativeInterface.gattClientDisconnect(clientIf, address, connId != null ? connId : 0); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void clientSetPreferredPhy(int clientIf, String address, int txPhy, int rxPhy, int phyOptions, + void clientSetPreferredPhy( + int clientIf, + String address, + int txPhy, + int rxPhy, + int phyOptions, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService clientSetPreferredPhy")) { @@ -2001,15 +2232,19 @@ public class GattService extends ProfileService { Integer connId = mClientMap.connIdByAddress(clientIf, address); if (connId != null) { - mNativeInterface.gattClientDiscoverServiceByUuid(connId, uuid.getLeastSignificantBits(), - uuid.getMostSignificantBits()); + mNativeInterface.gattClientDiscoverServiceByUuid( + connId, uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); } else { Log.e(TAG, "discoverServiceByUuid() - No connection for " + address + "..."); } } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void readCharacteristic(int clientIf, String address, int handle, int authReq, + void readCharacteristic( + int clientIf, + String address, + int handle, + int authReq, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService readCharacteristic")) { @@ -2040,8 +2275,14 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void readUsingCharacteristicUuid(int clientIf, String address, UUID uuid, int startHandle, - int endHandle, int authReq, AttributionSource attributionSource) { + void readUsingCharacteristicUuid( + int clientIf, + String address, + UUID uuid, + int startHandle, + int endHandle, + int authReq, + AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService readUsingCharacteristicUuid")) { return; @@ -2067,14 +2308,24 @@ public class GattService extends ProfileService { return; } - mNativeInterface.gattClientReadUsingCharacteristicUuid(connId, - uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(), startHandle, - endHandle, authReq); + mNativeInterface.gattClientReadUsingCharacteristicUuid( + connId, + uuid.getLeastSignificantBits(), + uuid.getMostSignificantBits(), + startHandle, + endHandle, + authReq); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - int writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, - byte[] value, AttributionSource attributionSource) { + int writeCharacteristic( + int clientIf, + String address, + int handle, + int writeType, + int authReq, + byte[] value, + AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService writeCharacteristic")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; @@ -2115,7 +2366,11 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void readDescriptor(int clientIf, String address, int handle, int authReq, + void readDescriptor( + int clientIf, + String address, + int handle, + int authReq, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService readDescriptor")) { @@ -2146,7 +2401,12 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - int writeDescriptor(int clientIf, String address, int handle, int authReq, byte[] value, + int writeDescriptor( + int clientIf, + String address, + int handle, + int authReq, + byte[] value, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService writeDescriptor")) { @@ -2194,7 +2454,11 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void registerForNotification(int clientIf, String address, int handle, boolean enable, + void registerForNotification( + int clientIf, + String address, + int handle, + boolean enable, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService registerForNotification")) { @@ -2252,7 +2516,10 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void connectionParameterUpdate(int clientIf, String address, int connectionPriority, + void connectionParameterUpdate( + int clientIf, + String address, + int connectionPriority, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService connectionParameterUpdate")) { @@ -2268,48 +2535,83 @@ public class GattService extends ProfileService { // Link supervision timeout is measured in N * 10ms int timeout = 500; // 5s - - CompanionManager manager = - AdapterService.getAdapterService().getCompanionManager(); - - minInterval = manager.getGattConnParameters( - address, CompanionManager.GATT_CONN_INTERVAL_MIN, connectionPriority); - maxInterval = manager.getGattConnParameters( - address, CompanionManager.GATT_CONN_INTERVAL_MAX, connectionPriority); - latency = manager.getGattConnParameters( - address, CompanionManager.GATT_CONN_LATENCY, connectionPriority); - - Log.d(TAG, "connectionParameterUpdate() - address=" + address + " params=" - + connectionPriority + " interval=" + minInterval + "/" + maxInterval - + " timeout=" + timeout); - - mNativeInterface.gattConnectionParameterUpdate(clientIf, address, minInterval, maxInterval, - latency, timeout, 0, 0); + CompanionManager manager = AdapterService.getAdapterService().getCompanionManager(); + + minInterval = + manager.getGattConnParameters( + address, CompanionManager.GATT_CONN_INTERVAL_MIN, connectionPriority); + maxInterval = + manager.getGattConnParameters( + address, CompanionManager.GATT_CONN_INTERVAL_MAX, connectionPriority); + latency = + manager.getGattConnParameters( + address, CompanionManager.GATT_CONN_LATENCY, connectionPriority); + + Log.d( + TAG, + "connectionParameterUpdate() - address=" + + address + + " params=" + + connectionPriority + + " interval=" + + minInterval + + "/" + + maxInterval + + " timeout=" + + timeout); + + mNativeInterface.gattConnectionParameterUpdate( + clientIf, address, minInterval, maxInterval, latency, timeout, 0, 0); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void leConnectionUpdate(int clientIf, String address, int minInterval, - int maxInterval, int peripheralLatency, - int supervisionTimeout, int minConnectionEventLen, - int maxConnectionEventLen, AttributionSource attributionSource) { + void leConnectionUpdate( + int clientIf, + String address, + int minInterval, + int maxInterval, + int peripheralLatency, + int supervisionTimeout, + int minConnectionEventLen, + int maxConnectionEventLen, + AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService leConnectionUpdate")) { return; } - Log.d(TAG, "leConnectionUpdate() - address=" + address + ", intervals=" - + minInterval + "/" + maxInterval + ", latency=" + peripheralLatency - + ", timeout=" + supervisionTimeout + "msec" + ", min_ce=" - + minConnectionEventLen + ", max_ce=" + maxConnectionEventLen); - - mNativeInterface.gattConnectionParameterUpdate(clientIf, address, minInterval, maxInterval, - peripheralLatency, supervisionTimeout, - minConnectionEventLen, maxConnectionEventLen); + Log.d( + TAG, + "leConnectionUpdate() - address=" + + address + + ", intervals=" + + minInterval + + "/" + + maxInterval + + ", latency=" + + peripheralLatency + + ", timeout=" + + supervisionTimeout + + "msec" + + ", min_ce=" + + minConnectionEventLen + + ", max_ce=" + + maxConnectionEventLen); + + mNativeInterface.gattConnectionParameterUpdate( + clientIf, + address, + minInterval, + maxInterval, + peripheralLatency, + supervisionTimeout, + minConnectionEventLen, + maxConnectionEventLen); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void subrateModeRequest(int clientIf, String address, int subrateMode, - AttributionSource attributionSource) { + void subrateModeRequest( + int clientIf, String address, int subrateMode, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService subrateModeRequest")) { return; @@ -2348,35 +2650,71 @@ public class GattService extends ProfileService { break; } - Log.d(TAG, "subrateModeRequest() - " - + "address=" + BluetoothUtils.toAnonymizedAddress(address) - + ", subrate min/max=" + subrateMin + "/" + subrateMax - + ", maxLatency=" + maxLatency - + ", continuation Number=" + contNumber - + ", timeout=" + supervisionTimeout); - - mNativeInterface.gattSubrateRequest(clientIf, address, subrateMin, subrateMax, maxLatency, - contNumber, supervisionTimeout); + Log.d( + TAG, + "subrateModeRequest() - " + + "address=" + + BluetoothUtils.toAnonymizedAddress(address) + + ", subrate min/max=" + + subrateMin + + "/" + + subrateMax + + ", maxLatency=" + + maxLatency + + ", continuation Number=" + + contNumber + + ", timeout=" + + supervisionTimeout); + + mNativeInterface.gattSubrateRequest( + clientIf, + address, + subrateMin, + subrateMax, + maxLatency, + contNumber, + supervisionTimeout); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void leSubrateRequest(int clientIf, String address, int subrateMin, int subrateMax, - int maxLatency, int contNumber, int supervisionTimeout, + void leSubrateRequest( + int clientIf, + String address, + int subrateMin, + int subrateMax, + int maxLatency, + int contNumber, + int supervisionTimeout, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService leSubrateRequest")) { return; } - Log.d(TAG, "leSubrateRequest() - " - + "address=" + BluetoothUtils.toAnonymizedAddress(address) - + ", subrate min/max=" + subrateMin + "/" + subrateMax - + ", maxLatency=" + maxLatency - + ", continuation Number=" + contNumber - + ", timeout=" + supervisionTimeout); - - mNativeInterface.gattSubrateRequest(clientIf, address, subrateMin, subrateMax, maxLatency, - contNumber, supervisionTimeout); + Log.d( + TAG, + "leSubrateRequest() - " + + "address=" + + BluetoothUtils.toAnonymizedAddress(address) + + ", subrate min/max=" + + subrateMin + + "/" + + subrateMax + + ", maxLatency=" + + maxLatency + + ", continuation Number=" + + contNumber + + ", timeout=" + + supervisionTimeout); + + mNativeInterface.gattSubrateRequest( + clientIf, + address, + subrateMin, + subrateMax, + maxLatency, + contNumber, + supervisionTimeout); } /************************************************************************** @@ -2411,26 +2749,43 @@ public class GattService extends ProfileService { for (GattDbElement el : service) { if (el.type == GattDbElement.TYPE_PRIMARY_SERVICE) { - mHandleMap.addService(serverIf, el.attributeHandle, el.uuid, - BluetoothGattService.SERVICE_TYPE_PRIMARY, 0, false); - svc = new BluetoothGattService(svcEl.uuid, svcEl.attributeHandle, - BluetoothGattService.SERVICE_TYPE_PRIMARY); + mHandleMap.addService( + serverIf, + el.attributeHandle, + el.uuid, + BluetoothGattService.SERVICE_TYPE_PRIMARY, + 0, + false); + svc = + new BluetoothGattService( + svcEl.uuid, + svcEl.attributeHandle, + BluetoothGattService.SERVICE_TYPE_PRIMARY); } else if (el.type == GattDbElement.TYPE_SECONDARY_SERVICE) { - mHandleMap.addService(serverIf, el.attributeHandle, el.uuid, - BluetoothGattService.SERVICE_TYPE_SECONDARY, 0, false); - svc = new BluetoothGattService(svcEl.uuid, svcEl.attributeHandle, - BluetoothGattService.SERVICE_TYPE_SECONDARY); + mHandleMap.addService( + serverIf, + el.attributeHandle, + el.uuid, + BluetoothGattService.SERVICE_TYPE_SECONDARY, + 0, + false); + svc = + new BluetoothGattService( + svcEl.uuid, + svcEl.attributeHandle, + BluetoothGattService.SERVICE_TYPE_SECONDARY); } else if (el.type == GattDbElement.TYPE_CHARACTERISTIC) { mHandleMap.addCharacteristic(serverIf, el.attributeHandle, el.uuid, srvcHandle); svc.addCharacteristic( - new BluetoothGattCharacteristic(el.uuid, el.attributeHandle, el.properties, - el.permissions)); + new BluetoothGattCharacteristic( + el.uuid, el.attributeHandle, el.properties, el.permissions)); } else if (el.type == GattDbElement.TYPE_DESCRIPTOR) { mHandleMap.addDescriptor(serverIf, el.attributeHandle, el.uuid, srvcHandle); List chars = svc.getCharacteristics(); chars.get(chars.size() - 1) - .addDescriptor(new BluetoothGattDescriptor(el.uuid, el.attributeHandle, - el.permissions)); + .addDescriptor( + new BluetoothGattDescriptor( + el.uuid, el.attributeHandle, el.permissions)); } } mHandleMap.setStarted(serverIf, srvcHandle, true); @@ -2457,8 +2812,13 @@ public class GattService extends ProfileService { void onClientConnected(String address, boolean connected, int connId, int serverIf) throws RemoteException { - Log.d(TAG, - "onClientConnected() connId=" + connId + ", address=" + address + ", connected=" + Log.d( + TAG, + "onClientConnected() connId=" + + connId + + ", address=" + + address + + ", connected=" + connected); ServerMap.App app = mServerMap.getById(serverIf); @@ -2477,10 +2837,11 @@ public class GattService extends ProfileService { int applicationUid = -1; try { - applicationUid = this.getPackageManager().getPackageUid(app.name, PackageInfoFlags.of(0)); + applicationUid = + this.getPackageManager().getPackageUid(app.name, PackageInfoFlags.of(0)); } catch (NameNotFoundException e) { - Log.d(TAG, "onClientConnected() uid_not_found=" + app.name); + Log.d(TAG, "onClientConnected() uid_not_found=" + app.name); } app.callback.onServerConnectionState((byte) 0, serverIf, connected, address); @@ -2489,10 +2850,21 @@ public class GattService extends ProfileService { BluetoothProfile.GATT_SERVER, address, serverIf, connectionState, -1); } - void onServerReadCharacteristic(String address, int connId, int transId, int handle, int offset, - boolean isLong) throws RemoteException { - Log.v(TAG, "onServerReadCharacteristic() connId=" + connId + ", address=" + address - + ", handle=" + handle + ", requestId=" + transId + ", offset=" + offset); + void onServerReadCharacteristic( + String address, int connId, int transId, int handle, int offset, boolean isLong) + throws RemoteException { + Log.v( + TAG, + "onServerReadCharacteristic() connId=" + + connId + + ", address=" + + address + + ", handle=" + + handle + + ", requestId=" + + transId + + ", offset=" + + offset); HandleMap.Entry entry = mHandleMap.getByHandle(handle); if (entry == null) { @@ -2509,10 +2881,21 @@ public class GattService extends ProfileService { app.callback.onCharacteristicReadRequest(address, transId, offset, isLong, handle); } - void onServerReadDescriptor(String address, int connId, int transId, int handle, int offset, - boolean isLong) throws RemoteException { - Log.v(TAG, "onServerReadDescriptor() connId=" + connId + ", address=" + address - + ", handle=" + handle + ", requestId=" + transId + ", offset=" + offset); + void onServerReadDescriptor( + String address, int connId, int transId, int handle, int offset, boolean isLong) + throws RemoteException { + Log.v( + TAG, + "onServerReadDescriptor() connId=" + + connId + + ", address=" + + address + + ", handle=" + + handle + + ", requestId=" + + transId + + ", offset=" + + offset); HandleMap.Entry entry = mHandleMap.getByHandle(handle); if (entry == null) { @@ -2529,12 +2912,31 @@ public class GattService extends ProfileService { app.callback.onDescriptorReadRequest(address, transId, offset, isLong, handle); } - void onServerWriteCharacteristic(String address, int connId, int transId, int handle, - int offset, int length, boolean needRsp, boolean isPrep, byte[] data) + void onServerWriteCharacteristic( + String address, + int connId, + int transId, + int handle, + int offset, + int length, + boolean needRsp, + boolean isPrep, + byte[] data) throws RemoteException { - Log.v(TAG, "onServerWriteCharacteristic() connId=" + connId + ", address=" + address - + ", handle=" + handle + ", requestId=" + transId + ", isPrep=" + isPrep - + ", offset=" + offset); + Log.v( + TAG, + "onServerWriteCharacteristic() connId=" + + connId + + ", address=" + + address + + ", handle=" + + handle + + ", requestId=" + + transId + + ", isPrep=" + + isPrep + + ", offset=" + + offset); HandleMap.Entry entry = mHandleMap.getByHandle(handle); if (entry == null) { @@ -2548,15 +2950,35 @@ public class GattService extends ProfileService { return; } - app.callback.onCharacteristicWriteRequest(address, transId, offset, length, isPrep, needRsp, - handle, data); + app.callback.onCharacteristicWriteRequest( + address, transId, offset, length, isPrep, needRsp, handle, data); } - void onServerWriteDescriptor(String address, int connId, int transId, int handle, int offset, - int length, boolean needRsp, boolean isPrep, byte[] data) throws RemoteException { - Log.v(TAG, "onAttributeWrite() connId=" + connId + ", address=" + address + ", handle=" - + handle + ", requestId=" + transId + ", isPrep=" + isPrep + ", offset=" - + offset); + void onServerWriteDescriptor( + String address, + int connId, + int transId, + int handle, + int offset, + int length, + boolean needRsp, + boolean isPrep, + byte[] data) + throws RemoteException { + Log.v( + TAG, + "onAttributeWrite() connId=" + + connId + + ", address=" + + address + + ", handle=" + + handle + + ", requestId=" + + transId + + ", isPrep=" + + isPrep + + ", offset=" + + offset); HandleMap.Entry entry = mHandleMap.getByHandle(handle); if (entry == null) { @@ -2570,14 +2992,20 @@ public class GattService extends ProfileService { return; } - app.callback.onDescriptorWriteRequest(address, transId, offset, length, isPrep, needRsp, - handle, data); + app.callback.onDescriptorWriteRequest( + address, transId, offset, length, isPrep, needRsp, handle, data); } void onExecuteWrite(String address, int connId, int transId, int execWrite) throws RemoteException { - Log.d(TAG, "onExecuteWrite() connId=" + connId + ", address=" + address + ", transId=" - + transId); + Log.d( + TAG, + "onExecuteWrite() connId=" + + connId + + ", address=" + + address + + ", transId=" + + transId); ServerMap.App app = mServerMap.getByConnId(connId); if (app == null) { @@ -2653,7 +3081,10 @@ public class GattService extends ProfileService { *************************************************************************/ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void registerServer(UUID uuid, IBluetoothGattServerCallback callback, boolean eatt_support, + void registerServer( + UUID uuid, + IBluetoothGattServerCallback callback, + boolean eatt_support, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService registerServer")) { @@ -2662,8 +3093,8 @@ public class GattService extends ProfileService { Log.d(TAG, "registerServer() - UUID=" + uuid); mServerMap.add(uuid, null, callback, null, this, mTransitionalScanHelper); - mNativeInterface.gattServerRegisterApp(uuid.getLeastSignificantBits(), - uuid.getMostSignificantBits(), eatt_support); + mNativeInterface.gattServerRegisterApp( + uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(), eatt_support); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) @@ -2715,7 +3146,12 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void serverSetPreferredPhy(int serverIf, String address, int txPhy, int rxPhy, int phyOptions, + void serverSetPreferredPhy( + int serverIf, + String address, + int txPhy, + int rxPhy, + int phyOptions, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService serverSetPreferredPhy")) { @@ -2773,7 +3209,8 @@ public class GattService extends ProfileService { if (mHandleMap.checkServiceExists(includedService.getUuid(), inclSrvcHandle)) { db.add(GattDbElement.createIncludedService(inclSrvcHandle)); } else { - Log.e(TAG, + Log.e( + TAG, "included service with UUID " + includedService.getUuid() + " not found!"); } } @@ -2781,8 +3218,9 @@ public class GattService extends ProfileService { for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) { int permission = ((characteristic.getKeySize() - 7) << 12) + characteristic.getPermissions(); - db.add(GattDbElement.createCharacteristic(characteristic.getUuid(), - characteristic.getProperties(), permission)); + db.add( + GattDbElement.createCharacteristic( + characteristic.getUuid(), characteristic.getProperties(), permission)); for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) { permission = @@ -2818,8 +3256,14 @@ public class GattService extends ProfileService { } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - void sendResponse(int serverIf, String address, int requestId, int status, int offset, - byte[] value, AttributionSource attributionSource) { + void sendResponse( + int serverIf, + String address, + int requestId, + int status, + int offset, + byte[] value, + AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService sendResponse")) { return; @@ -2834,13 +3278,25 @@ public class GattService extends ProfileService { } Integer connId = mServerMap.connIdByAddress(serverIf, address); - mNativeInterface.gattServerSendResponse(serverIf, connId != null ? connId : 0, requestId, - (byte) status, handle, offset, value, (byte) 0); + mNativeInterface.gattServerSendResponse( + serverIf, + connId != null ? connId : 0, + requestId, + (byte) status, + handle, + offset, + value, + (byte) 0); mHandleMap.deleteRequest(requestId); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - int sendNotification(int serverIf, String address, int handle, boolean confirm, byte[] value, + int sendNotification( + int serverIf, + String address, + int handle, + boolean confirm, + byte[] value, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService sendNotification")) { @@ -2863,7 +3319,6 @@ public class GattService extends ProfileService { return BluetoothStatusCodes.SUCCESS; } - /************************************************************************** * Private functions *************************************************************************/ @@ -2899,9 +3354,7 @@ public class GattService extends ProfileService { } private boolean isRestrictedSrvcUuid(final UUID uuid) { - return isFidoSrvcUuid(uuid) - || isAndroidTvRemoteSrvcUuid(uuid) - || isLeAudioSrvcUuid(uuid); + return isFidoSrvcUuid(uuid) || isAndroidTvRemoteSrvcUuid(uuid) || isLeAudioSrvcUuid(uuid); } private int getDeviceType(BluetoothDevice device) { @@ -2972,7 +3425,8 @@ public class GattService extends ProfileService { if (status == 0) { List entries = mHandleMap.getEntries(); for (HandleMap.Entry entry : entries) { - if (entry.type != HandleMap.TYPE_SERVICE || entry.serverIf != serverIf + if (entry.type != HandleMap.TYPE_SERVICE + || entry.serverIf != serverIf || !entry.started) { continue; } @@ -3008,8 +3462,12 @@ public class GattService extends ProfileService { void dumpRegisterId(StringBuilder sb) { sb.append(" Scanner:\n"); for (Integer appId : mTransitionalScanHelper.getScannerMap().getAllAppsIds()) { - println(sb, " app_if: " + appId + ", appName: " + - mTransitionalScanHelper.getScannerMap().getById(appId).name); + println( + sb, + " app_if: " + + appId + + ", appName: " + + mTransitionalScanHelper.getScannerMap().getById(appId).name); } sb.append(" Client:\n"); for (Integer appId : mClientMap.getAllAppsIds()) { @@ -3053,23 +3511,43 @@ public class GattService extends ProfileService { BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address); BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_GATT_APP_INFO, - sessionIndex, mAdapterService.getMetricId(device), applicationUid); - Log.d(TAG, "Gatt Logging: metric_id=" + mAdapterService.getMetricId(device) - + ", app_uid=" + applicationUid); + sessionIndex, + mAdapterService.getMetricId(device), + applicationUid); + Log.d( + TAG, + "Gatt Logging: metric_id=" + + mAdapterService.getMetricId(device) + + ", app_uid=" + + applicationUid); } private void statsLogGattConnectionStateChange( - int profile, String address, int sessionIndex, int connectionState, + int profile, + String address, + int sessionIndex, + int connectionState, int connectionStatus) { BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address); BluetoothStatsLog.write( - BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, connectionState, - 0 /* deprecated */, profile, new byte[0], - mAdapterService.getMetricId(device), sessionIndex, connectionStatus); - Log.d(TAG, "Gatt Logging: metric_id=" + mAdapterService.getMetricId(device) - + ", session_index=" + sessionIndex - + ", connection state=" + connectionState - + ", connection status=" + connectionStatus); + BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, + connectionState, + 0 /* deprecated */, + profile, + new byte[0], + mAdapterService.getMetricId(device), + sessionIndex, + connectionStatus); + Log.d( + TAG, + "Gatt Logging: metric_id=" + + mAdapterService.getMetricId(device) + + ", session_index=" + + sessionIndex + + ", connection state=" + + connectionState + + ", connection status=" + + connectionStatus); } @Override @@ -3080,14 +3558,22 @@ public class GattService extends ProfileService { /************************************************************************** * GATT Test functions *************************************************************************/ - void gattTestCommand(int command, UUID uuid1, String bda1, int p1, int p2, int p3, int p4, - int p5) { + void gattTestCommand( + int command, UUID uuid1, String bda1, int p1, int p2, int p3, int p4, int p5) { if (bda1 == null) { bda1 = "00:00:00:00:00:00"; } if (uuid1 != null) { - mNativeInterface.gattTest(command, uuid1.getLeastSignificantBits(), - uuid1.getMostSignificantBits(), bda1, p1, p2, p3, p4, p5); + mNativeInterface.gattTest( + command, + uuid1.getLeastSignificantBits(), + uuid1.getMostSignificantBits(), + bda1, + p1, + p2, + p3, + p4, + p5); } else { mNativeInterface.gattTest(command, 0, 0, bda1, p1, p2, p3, p4, p5); } diff --git a/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java b/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java index ff605574113..cbf574639c6 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java +++ b/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java @@ -16,9 +16,7 @@ package com.android.bluetooth.gatt; -/** - * GattService configuration. - */ +/** GattService configuration. */ public class GattServiceConfig { public static final String TAG_PREFIX = "BtGatt."; public static final boolean DEBUG_ADMIN = false; diff --git a/android/app/src/com/android/bluetooth/gatt/HandleMap.java b/android/app/src/com/android/bluetooth/gatt/HandleMap.java index 8cfb713ab7f..ab34c6e0093 100644 --- a/android/app/src/com/android/bluetooth/gatt/HandleMap.java +++ b/android/app/src/com/android/bluetooth/gatt/HandleMap.java @@ -52,7 +52,12 @@ class HandleMap { this.serviceType = serviceType; } - Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance, + Entry( + int serverIf, + int handle, + UUID uuid, + int serviceType, + int instance, boolean advertisePreferred) { this.serverIf = serverIf; this.type = TYPE_SERVICE; @@ -95,7 +100,12 @@ class HandleMap { mRequestMap.clear(); } - void addService(int serverIf, int handle, UUID uuid, int serviceType, int instance, + void addService( + int serverIf, + int handle, + UUID uuid, + int serviceType, + int instance, boolean advertisePreferred) { mEntries.add(new Entry(serverIf, handle, uuid, serviceType, instance, advertisePreferred)); } @@ -106,13 +116,20 @@ class HandleMap { } void addDescriptor(int serverIf, int handle, UUID uuid, int serviceHandle) { - mEntries.add(new Entry(serverIf, TYPE_DESCRIPTOR, handle, uuid, serviceHandle, - mLastCharacteristic)); + mEntries.add( + new Entry( + serverIf, + TYPE_DESCRIPTOR, + handle, + uuid, + serviceHandle, + mLastCharacteristic)); } void setStarted(int serverIf, int handle, boolean started) { for (Entry entry : mEntries) { - if (entry.type != TYPE_SERVICE || entry.serverIf != serverIf + if (entry.type != TYPE_SERVICE + || entry.serverIf != serverIf || entry.handle != handle) { continue; } @@ -142,8 +159,11 @@ class HandleMap { } void deleteService(int serverIf, int serviceHandle) { - mEntries.removeIf(entry -> ((entry.serverIf == serverIf) - && (entry.handle == serviceHandle || entry.serviceHandle == serviceHandle))); + mEntries.removeIf( + entry -> + ((entry.serverIf == serverIf) + && (entry.handle == serviceHandle + || entry.serviceHandle == serviceHandle))); } List getEntries() { @@ -167,10 +187,7 @@ class HandleMap { return getByHandle(handle); } - - /** - * Logs debug information. - */ + /** Logs debug information. */ void dump(StringBuilder sb) { sb.append(" Entries: " + mEntries.size() + "\n"); sb.append(" Requests: " + mRequestMap.size() + "\n"); diff --git a/android/app/src/com/android/bluetooth/hap/HapClientNativeInterface.java b/android/app/src/com/android/bluetooth/hap/HapClientNativeInterface.java index 656539efd6a..a2e345e6fa6 100644 --- a/android/app/src/com/android/bluetooth/hap/HapClientNativeInterface.java +++ b/android/app/src/com/android/bluetooth/hap/HapClientNativeInterface.java @@ -91,17 +91,13 @@ public class HapClientNativeInterface { } } - /** - * Initializes the native interface. - */ + /** Initializes the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { initNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { cleanupNative(); @@ -180,7 +176,7 @@ public class HapClientNativeInterface { getPresetInfoNative(getByteAddress(device), presetIndex); } - /** + /** * Sets the preset name * * @param device is the device for which we want to get the preset name @@ -211,8 +207,7 @@ public class HapClientNativeInterface { @VisibleForTesting void onConnectionStateChanged(int state, byte[] address) { HapClientStackEvent event = - new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); event.device = getDevice(address); event.valueInt1 = state; @@ -222,8 +217,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onDeviceAvailable(byte[] address, int features) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); event.device = getDevice(address); event.valueInt1 = features; @@ -233,8 +228,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onFeaturesUpdate(byte[] address, int features) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); event.device = getDevice(address); event.valueInt1 = features; @@ -244,8 +239,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onActivePresetSelected(byte[] address, int presetIndex) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); event.device = getDevice(address); event.valueInt1 = presetIndex; @@ -255,8 +250,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onActivePresetGroupSelected(int groupId, int presetIndex) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED); event.valueInt1 = presetIndex; event.valueInt2 = groupId; @@ -266,8 +261,9 @@ public class HapClientNativeInterface { @VisibleForTesting void onActivePresetSelectError(byte[] address, int resultCode) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); + HapClientStackEvent event = + new HapClientStackEvent( + HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); event.device = getDevice(address); event.valueInt1 = resultCode; @@ -277,8 +273,9 @@ public class HapClientNativeInterface { @VisibleForTesting void onActivePresetGroupSelectError(int groupId, int resultCode) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); + HapClientStackEvent event = + new HapClientStackEvent( + HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR); event.valueInt1 = resultCode; event.valueInt2 = groupId; @@ -288,8 +285,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onPresetInfo(byte[] address, int infoReason, BluetoothHapPresetInfo[] presets) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); event.device = getDevice(address); event.valueInt2 = infoReason; event.valueList = new ArrayList<>(Arrays.asList(presets)); @@ -300,8 +297,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onGroupPresetInfo(int groupId, int infoReason, BluetoothHapPresetInfo[] presets) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO); event.valueInt2 = infoReason; event.valueInt3 = groupId; event.valueList = new ArrayList<>(Arrays.asList(presets)); @@ -312,8 +309,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onPresetNameSetError(byte[] address, int presetIndex, int resultCode) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); event.device = getDevice(address); event.valueInt1 = resultCode; event.valueInt2 = presetIndex; @@ -324,8 +321,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onGroupPresetNameSetError(int groupId, int presetIndex, int resultCode) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR); event.valueInt1 = resultCode; event.valueInt2 = presetIndex; event.valueInt3 = groupId; @@ -336,8 +333,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onPresetInfoError(byte[] address, int presetIndex, int resultCode) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); event.device = getDevice(address); event.valueInt1 = resultCode; event.valueInt2 = presetIndex; @@ -348,8 +345,8 @@ public class HapClientNativeInterface { @VisibleForTesting void onGroupPresetInfoError(int groupId, int presetIndex, int resultCode) { - HapClientStackEvent event = new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); + HapClientStackEvent event = + new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR); event.valueInt1 = resultCode; event.valueInt2 = presetIndex; event.valueInt3 = groupId; @@ -360,16 +357,28 @@ public class HapClientNativeInterface { // Native methods that call into the JNI interface private native void initNative(); + private native void cleanupNative(); + private native boolean connectHapClientNative(byte[] address); + private native boolean disconnectHapClientNative(byte[] address); + private native void selectActivePresetNative(byte[] byteAddress, int presetIndex); + private native void groupSelectActivePresetNative(int groupId, int presetIndex); + private native void nextActivePresetNative(byte[] byteAddress); + private native void groupNextActivePresetNative(int groupId); + private native void previousActivePresetNative(byte[] byteAddress); + private native void groupPreviousActivePresetNative(int groupId); + private native void getPresetInfoNative(byte[] byteAddress, int presetIndex); + private native void setPresetNameNative(byte[] byteAddress, int presetIndex, String name); + private native void groupSetPresetNameNative(int groupId, int presetIndex, String name); } diff --git a/android/app/src/com/android/bluetooth/hap/HapClientService.java b/android/app/src/com/android/bluetooth/hap/HapClientService.java index 63d67086c2a..49f38545fe7 100644 --- a/android/app/src/com/android/bluetooth/hap/HapClientService.java +++ b/android/app/src/com/android/bluetooth/hap/HapClientService.java @@ -61,9 +61,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.Objects; -/** - * Provides Bluetooth Hearing Access profile, as a service. - */ +/** Provides Bluetooth Hearing Access profile, as a service. */ public class HapClientService extends ProfileService { private static final String TAG = "HapClientService"; @@ -71,10 +69,8 @@ public class HapClientService extends ProfileService { private static final int MAX_HEARING_ACCESS_STATE_MACHINES = 10; private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000; private static HapClientService sHapClient; - private final Map mStateMachines = - new HashMap<>(); - @VisibleForTesting - HapClientNativeInterface mHapClientNativeInterface; + private final Map mStateMachines = new HashMap<>(); + @VisibleForTesting HapClientNativeInterface mHapClientNativeInterface; private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; @@ -82,14 +78,11 @@ public class HapClientService extends ProfileService { private final Map mDeviceCurrentPresetMap = new HashMap<>(); private final Map mDeviceFeaturesMap = new HashMap<>(); - private final Map> mPresetsMap = - new HashMap<>(); + private final Map> mPresetsMap = new HashMap<>(); - @VisibleForTesting - RemoteCallbackList mCallbacks; + @VisibleForTesting RemoteCallbackList mCallbacks; - @VisibleForTesting - ServiceFactory mFactory = new ServiceFactory(); + @VisibleForTesting ServiceFactory mFactory = new ServiceFactory(); public static boolean isEnabled() { return BluetoothProperties.isProfileHapClientEnabled().orElse(false); @@ -103,6 +96,7 @@ public class HapClientService extends ProfileService { /** * Get the HapClientService instance + * * @return HapClientService instance */ public static synchronized HapClientService getHapClientService() { @@ -253,8 +247,9 @@ public class HapClientService extends ProfileService { synchronized (mStateMachines) { HapClientStateMachine sm = mStateMachines.get(device); if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); + Log.w( + TAG, + "removeStateMachine: device " + device + " does not have a state machine"); return; } Log.i(TAG, "removeStateMachine: removing state machine for device: " + device); @@ -312,10 +307,10 @@ public class HapClientService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission"); @@ -329,25 +324,24 @@ public class HapClientService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * - * @param device the remote device + * @param device the remote device * @param connectionPolicy is the connection policy to set to for this profile * @return true on success, otherwise false */ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { enforceBluetoothPrivilegedPermission(this); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT, - connectionPolicy); + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HAP_CLIENT, connectionPolicy); if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { connect(device); } else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { @@ -359,10 +353,9 @@ public class HapClientService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device @@ -372,8 +365,8 @@ public class HapClientService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -403,11 +396,16 @@ public class HapClientService extends ProfileService { } @VisibleForTesting - synchronized void connectionStateChanged(BluetoothDevice device, int fromState, - int toState) { + synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { if ((device == null) || (fromState == toState)) { - Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device - + " fromState=" + fromState + " toState=" + toState); + Log.e( + TAG, + "connectionStateChanged: unexpected invocation. device=" + + device + + " fromState=" + + fromState + + " toState=" + + toState); return; } @@ -446,8 +444,11 @@ public class HapClientService extends ProfileService { } ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device); if (!Utils.arrayContains(featureUuids, BluetoothUuid.HAS)) { - Log.e(TAG, "Cannot connect to " + device - + " : Remote does not have Hearing Access Service UUID"); + Log.e( + TAG, + "Cannot connect to " + + device + + " : Remote does not have Hearing Access Service UUID"); return false; } synchronized (mStateMachines) { @@ -465,7 +466,7 @@ public class HapClientService extends ProfileService { * Disconnects hearing access service client for the passed in device * * @param device is the device with which we want to disconnect the hearing access service - * client + * client * @return true if hearing access service client successfully disconnected, false otherwise */ public boolean disconnect(BluetoothDevice device) { @@ -496,13 +497,19 @@ public class HapClientService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_HEARING_ACCESS_STATE_MACHINES) { - Log.e(TAG, "Maximum number of HearingAccess state machines reached: " - + MAX_HEARING_ACCESS_STATE_MACHINES); + Log.e( + TAG, + "Maximum number of HearingAccess state machines reached: " + + MAX_HEARING_ACCESS_STATE_MACHINES); return null; } Log.d(TAG, "Creating a new state machine for " + device); - sm = HapClientStateMachine.make(device, this, - mHapClientNativeInterface, mStateMachinesThread.getLooper()); + sm = + HapClientStateMachine.make( + device, + this, + mHapClientNativeInterface, + mStateMachinesThread.getLooper()); mStateMachines.put(device, sm); return sm; } @@ -535,8 +542,8 @@ public class HapClientService extends ProfileService { * @return active preset index */ public int getActivePresetIndex(BluetoothDevice device) { - return mDeviceCurrentPresetMap.getOrDefault(device, - BluetoothHapClient.PRESET_INDEX_UNAVAILABLE); + return mDeviceCurrentPresetMap.getOrDefault( + device, BluetoothHapClient.PRESET_INDEX_UNAVAILABLE); } /** @@ -573,8 +580,11 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onPresetSelectionFailed(device, - BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX); + mCallbacks + .getBroadcastItem(i) + .onPresetSelectionFailed( + device, + BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX); } catch (RemoteException e) { continue; } @@ -607,7 +617,8 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i) + mCallbacks + .getBroadcastItem(i) .onPresetSelectionForGroupFailed(groupId, status); } catch (RemoteException e) { continue; @@ -737,8 +748,12 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onPresetInfoChanged(device, current_presets, - stackEventPresetInfoReasonToProfileStatus(infoReason)); + mCallbacks + .getBroadcastItem(i) + .onPresetInfoChanged( + device, + current_presets, + stackEventPresetInfoReasonToProfileStatus(infoReason)); } catch (RemoteException e) { continue; } @@ -758,14 +773,15 @@ public class HapClientService extends ProfileService { Log.d(TAG, "HAP device: " + device + ", features: " + String.format("0x%04X", features)); } - private void notifyActivePresetChanged(BluetoothDevice device, int presetIndex, - int reasonCode) { + private void notifyActivePresetChanged( + BluetoothDevice device, int presetIndex, int reasonCode) { if (mCallbacks != null) { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onPresetSelected(device, presetIndex, - reasonCode); + mCallbacks + .getBroadcastItem(i) + .onPresetSelected(device, presetIndex, reasonCode); } catch (RemoteException e) { continue; } @@ -807,8 +823,10 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onPresetSelectionFailed(device, - stackEventStatusToProfileStatus(statusCode)); + mCallbacks + .getBroadcastItem(i) + .onPresetSelectionFailed( + device, stackEventStatusToProfileStatus(statusCode)); } catch (RemoteException e) { continue; } @@ -822,8 +840,10 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onPresetSelectionForGroupFailed(groupId, - stackEventStatusToProfileStatus(statusCode)); + mCallbacks + .getBroadcastItem(i) + .onPresetSelectionForGroupFailed( + groupId, stackEventStatusToProfileStatus(statusCode)); } catch (RemoteException e) { continue; } @@ -837,8 +857,10 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onSetPresetNameFailed(device, - stackEventStatusToProfileStatus(statusCode)); + mCallbacks + .getBroadcastItem(i) + .onSetPresetNameFailed( + device, stackEventStatusToProfileStatus(statusCode)); } catch (RemoteException e) { continue; } @@ -852,8 +874,10 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onSetPresetNameForGroupFailed(groupId, - stackEventStatusToProfileStatus(statusCode)); + mCallbacks + .getBroadcastItem(i) + .onSetPresetNameForGroupFailed( + groupId, stackEventStatusToProfileStatus(statusCode)); } catch (RemoteException e) { continue; } @@ -886,7 +910,6 @@ public class HapClientService extends ProfileService { return true; } - private boolean isGroupIdValid(int groupId) { if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return false; @@ -911,8 +934,11 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onSetPresetNameFailed(device, - BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX); + mCallbacks + .getBroadcastItem(i) + .onSetPresetNameFailed( + device, + BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX); } catch (RemoteException e) { continue; } @@ -947,8 +973,9 @@ public class HapClientService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onSetPresetNameForGroupFailed(groupId, - status); + mCallbacks + .getBroadcastItem(i) + .onSetPresetNameForGroupFailed(groupId, status); } catch (RemoteException e) { continue; } @@ -969,49 +996,53 @@ public class HapClientService extends ProfileService { } } - void updateDevicePresetsCache(BluetoothDevice device, int infoReason, - List presets) { + void updateDevicePresetsCache( + BluetoothDevice device, int infoReason, List presets) { switch (infoReason) { case HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO: mPresetsMap.put(device, presets); break; case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE: case HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED: - case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE: { - List current_presets = mPresetsMap.get(device); - if (current_presets != null) { - for (BluetoothHapPresetInfo new_preset : presets) { - ListIterator iter = current_presets.listIterator(); - while (iter.hasNext()) { - if (iter.next().getIndex() == new_preset.getIndex()) { - iter.remove(); - break; + case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE: + { + List current_presets = mPresetsMap.get(device); + if (current_presets != null) { + for (BluetoothHapPresetInfo new_preset : presets) { + ListIterator iter = + current_presets.listIterator(); + while (iter.hasNext()) { + if (iter.next().getIndex() == new_preset.getIndex()) { + iter.remove(); + break; + } } } + current_presets.addAll(presets); + mPresetsMap.put(device, current_presets); + } else { + mPresetsMap.put(device, presets); } - current_presets.addAll(presets); - mPresetsMap.put(device, current_presets); - } else { - mPresetsMap.put(device, presets); } - } break; - case HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED: { - List current_presets = mPresetsMap.get(device); - if (current_presets != null) { - for (BluetoothHapPresetInfo new_preset : presets) { - ListIterator iter = current_presets.listIterator(); - while (iter.hasNext()) { - if (iter.next().getIndex() == new_preset.getIndex()) { - iter.remove(); - break; + case HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED: + { + List current_presets = mPresetsMap.get(device); + if (current_presets != null) { + for (BluetoothHapPresetInfo new_preset : presets) { + ListIterator iter = + current_presets.listIterator(); + while (iter.hasNext()) { + if (iter.next().getIndex() == new_preset.getIndex()) { + iter.remove(); + break; + } } } + mPresetsMap.put(device, current_presets); } - mPresetsMap.put(device, current_presets); } - } break; default: @@ -1047,93 +1078,106 @@ public class HapClientService extends ProfileService { BluetoothDevice device = stackEvent.device; switch (stackEvent.type) { - case (HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE): { - int features = stackEvent.valueInt1; + case (HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE): + { + int features = stackEvent.valueInt1; - if (device != null) { - mDeviceFeaturesMap.put(device, features); + if (device != null) { + mDeviceFeaturesMap.put(device, features); - intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.putExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, features); + intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + intent.putExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, features); + } } - } break; + break; - case (HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES): { - int features = stackEvent.valueInt1; + case (HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES): + { + int features = stackEvent.valueInt1; - if (device != null) { - mDeviceFeaturesMap.put(device, features); - notifyFeaturesAvailable(device, features); + if (device != null) { + mDeviceFeaturesMap.put(device, features); + notifyFeaturesAvailable(device, features); + } } - } return; - - case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED): { - int currentPresetIndex = stackEvent.valueInt1; - int groupId = stackEvent.valueInt2; - - if (device != null) { - mDeviceCurrentPresetMap.put(device, currentPresetIndex); - // FIXME: Add app request queueing to support other reasons - int reasonCode = BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST; - notifyActivePresetChanged(device, currentPresetIndex, reasonCode); - - } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { - List all_group_devices = getGroupDevices(groupId); - for (BluetoothDevice dev : all_group_devices) { - mDeviceCurrentPresetMap.put(dev, currentPresetIndex); + return; + + case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED): + { + int currentPresetIndex = stackEvent.valueInt1; + int groupId = stackEvent.valueInt2; + + if (device != null) { + mDeviceCurrentPresetMap.put(device, currentPresetIndex); + // FIXME: Add app request queueing to support other reasons + int reasonCode = BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST; + notifyActivePresetChanged(device, currentPresetIndex, reasonCode); + + } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + List all_group_devices = getGroupDevices(groupId); + for (BluetoothDevice dev : all_group_devices) { + mDeviceCurrentPresetMap.put(dev, currentPresetIndex); + } + // FIXME: Add app request queueing to support other reasons + int reasonCode = BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST; + notifyActivePresetChangedForGroup(groupId, currentPresetIndex, reasonCode); } - // FIXME: Add app request queueing to support other reasons - int reasonCode = BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST; - notifyActivePresetChangedForGroup(groupId, currentPresetIndex, reasonCode); } - } return; + return; - case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR): { - int groupId = stackEvent.valueInt2; - int statusCode = stackEvent.valueInt1; + case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR): + { + int groupId = stackEvent.valueInt2; + int statusCode = stackEvent.valueInt1; - if (device != null) { - notifySelectActivePresetFailed(device, statusCode); - } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { - notifySelectActivePresetForGroupFailed(groupId, statusCode); + if (device != null) { + notifySelectActivePresetFailed(device, statusCode); + } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + notifySelectActivePresetForGroupFailed(groupId, statusCode); + } } - } break; + break; - case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO): { - int infoReason = stackEvent.valueInt2; - int groupId = stackEvent.valueInt3; - ArrayList presets = stackEvent.valueList; + case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO): + { + int infoReason = stackEvent.valueInt2; + int groupId = stackEvent.valueInt3; + ArrayList presets = stackEvent.valueList; - if (device != null) { - updateDevicePresetsCache(device, infoReason, presets); - notifyPresetInfoChanged(device, infoReason); + if (device != null) { + updateDevicePresetsCache(device, infoReason, presets); + notifyPresetInfoChanged(device, infoReason); - } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { - List all_group_devices = getGroupDevices(groupId); - for (BluetoothDevice dev : all_group_devices) { - updateDevicePresetsCache(dev, infoReason, presets); + } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + List all_group_devices = getGroupDevices(groupId); + for (BluetoothDevice dev : all_group_devices) { + updateDevicePresetsCache(dev, infoReason, presets); + } + notifyPresetInfoForGroupChanged(groupId, infoReason); } - notifyPresetInfoForGroupChanged(groupId, infoReason); } + return; - } return; - - case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR): { - int statusCode = stackEvent.valueInt1; - int groupId = stackEvent.valueInt3; + case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR): + { + int statusCode = stackEvent.valueInt1; + int groupId = stackEvent.valueInt3; - if (device != null) { - notifySetPresetNameFailed(device, statusCode); - } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { - notifySetPresetNameForGroupFailed(groupId, statusCode); + if (device != null) { + notifySetPresetNameFailed(device, statusCode); + } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + notifySetPresetNameForGroupFailed(groupId, statusCode); + } } - } break; + break; - case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR): { - // Used only to report back on hidden API calls used for testing. - Log.d(TAG, stackEvent.toString()); - } break; + case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR): + { + // Used only to report back on hidden API calls used for testing. + Log.d(TAG, stackEvent.toString()); + } + break; default: return; @@ -1169,14 +1213,11 @@ public class HapClientService extends ProfileService { } } - /** - * Binder object: must be a static class or memory leak may occur - */ + /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting static class BluetoothHapClientBinder extends IBluetoothHapClient.Stub implements IProfileServiceBinder { - @VisibleForTesting - boolean mIsTesting = false; + @VisibleForTesting boolean mIsTesting = false; private HapClientService mService; BluetoothHapClientBinder(HapClientService svc) { @@ -1319,8 +1360,8 @@ public class HapClientService extends ProfileService { } @Override - public void selectPreset(BluetoothDevice device, int presetIndex, - AttributionSource source) { + public void selectPreset( + BluetoothDevice device, int presetIndex, AttributionSource source) { if (source == null) { Log.w(TAG, "source cannot be null"); return; @@ -1460,8 +1501,8 @@ public class HapClientService extends ProfileService { } @Override - public void setPresetName(BluetoothDevice device, int presetIndex, String name, - AttributionSource source) { + public void setPresetName( + BluetoothDevice device, int presetIndex, String name, AttributionSource source) { if (device == null) { Log.w(TAG, "device cannot be null"); return; @@ -1485,8 +1526,8 @@ public class HapClientService extends ProfileService { } @Override - public void setPresetNameForGroup(int groupId, int presetIndex, String name, - AttributionSource source) { + public void setPresetNameForGroup( + int groupId, int presetIndex, String name, AttributionSource source) { if (name == null) { Log.w(TAG, "name cannot be null"); return; diff --git a/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java b/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java index e77e0867ef2..b7d7776a7d6 100644 --- a/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java @@ -16,34 +16,18 @@ */ /** - * Bluetooth Hap Client StateMachine. There is one instance per remote device. - * - "Disconnected" and "Connected" are steady states. - * - "Connecting" and "Disconnecting" are transient states until the - * connection / disconnection is completed. + * Bluetooth Hap Client StateMachine. There is one instance per remote device. - "Disconnected" and + * "Connected" are steady states. - "Connecting" and "Disconnecting" are transient states until the + * connection / disconnection is completed. * + *

(Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting)<--->(Disconnecting) | ^ CONNECTED + * | | DISCONNECT V | (Connected) NOTES: - If state machine is in "Connecting" state and the remote + * device sends DISCONNECT request, the state machine transitions to "Disconnecting" state. - + * Similarly, if the state machine is in "Disconnecting" state and the remote device sends CONNECT + * request, the state machine transitions to "Connecting" state. * - * (Disconnected) - * | ^ - * CONNECT | | DISCONNECTED - * V | - * (Connecting)<--->(Disconnecting) - * | ^ - * CONNECTED | | DISCONNECT - * V | - * (Connected) - * NOTES: - * - If state machine is in "Connecting" state and the remote device sends - * DISCONNECT request, the state machine transitions to "Disconnecting" state. - * - Similarly, if the state machine is in "Disconnecting" state and the remote device - * sends CONNECT request, the state machine transitions to "Connecting" state. - * - * DISCONNECT - * (Connecting) ---------------> (Disconnecting) - * <--------------- - * CONNECT - * + *

DISCONNECT (Connecting) ---------------> (Disconnecting) <--------------- CONNECT */ - package com.android.bluetooth.hap; import static android.Manifest.permission.BLUETOOTH_CONNECT; @@ -69,15 +53,12 @@ import java.util.Scanner; final class HapClientStateMachine extends StateMachine { static final int CONNECT = 1; static final int DISCONNECT = 2; - @VisibleForTesting - static final int STACK_EVENT = 101; + @VisibleForTesting static final int STACK_EVENT = 101; private static final String TAG = "HapClientStateMachine"; - @VisibleForTesting - static final int CONNECT_TIMEOUT = 201; + @VisibleForTesting static final int CONNECT_TIMEOUT = 201; // NOTE: the value is not "final" - it is modified in the unit tests - @VisibleForTesting - static int sConnectTimeoutMs = 30000; // 30s + @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s private final Disconnected mDisconnected; private final Connecting mConnecting; @@ -91,8 +72,11 @@ final class HapClientStateMachine extends StateMachine { private final BluetoothDevice mDevice; - HapClientStateMachine(BluetoothDevice device, HapClientService svc, - HapClientNativeInterface gattInterface, Looper looper) { + HapClientStateMachine( + BluetoothDevice device, + HapClientService svc, + HapClientNativeInterface gattInterface, + Looper looper) { super(TAG, looper); mDevice = device; mService = svc; @@ -111,11 +95,14 @@ final class HapClientStateMachine extends StateMachine { setInitialState(mDisconnected); } - static HapClientStateMachine make(BluetoothDevice device, HapClientService svc, - HapClientNativeInterface gattInterface, Looper looper) { + static HapClientStateMachine make( + BluetoothDevice device, + HapClientService svc, + HapClientNativeInterface gattInterface, + Looper looper) { Log.i(TAG, "make for device " + device); - HapClientStateMachine hearingAccessSm = new HapClientStateMachine(device, svc, - gattInterface, looper); + HapClientStateMachine hearingAccessSm = + new HapClientStateMachine(device, svc, gattInterface, looper); hearingAccessSm.start(); return hearingAccessSm; } @@ -175,16 +162,22 @@ final class HapClientStateMachine extends StateMachine { // This method does not check for error condition (newState == prevState) private void broadcastConnectionState(int newState, int prevState) { - log("Connection state " + mDevice + ": " + profileStateToString(prevState) - + "->" + profileStateToString(newState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(prevState) + + "->" + + profileStateToString(newState)); mService.connectionStateChanged(mDevice, prevState, newState); Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mService.sendBroadcast(intent, BLUETOOTH_CONNECT); } @@ -194,7 +187,7 @@ final class HapClientStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); @@ -215,30 +208,39 @@ final class HapClientStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_DISCONNECTED; removeDeferredMessages(DISCONNECT); if (mLastConnectionState != -1) { // Don't broadcast during startup - broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, - mLastConnectionState); + broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, mLastConnectionState); } } @Override public void exit() { - log("Exit Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + log( + "Exit Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected: process message(" + mDevice + "): " + messageWhatToString( - message.what)); + log( + "Disconnected: process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -251,8 +253,9 @@ final class HapClientStateMachine extends StateMachine { transitionTo(mConnecting); } else { // Reject the request and stay in Disconnected state - Log.w(TAG, "Outgoing HearingAccess Connecting request rejected: " - + mDevice); + Log.w( + TAG, + "Outgoing HearingAccess Connecting request rejected: " + mDevice); } break; case DISCONNECT: @@ -288,13 +291,15 @@ final class HapClientStateMachine extends StateMachine { break; case HapClientStackEvent.CONNECTION_STATE_CONNECTING: if (mService.okToConnect(mDevice)) { - Log.i(TAG, "Incoming HearingAccess Connecting request accepted: " - + mDevice); + Log.i( + TAG, + "Incoming HearingAccess Connecting request accepted: " + mDevice); transitionTo(mConnecting); } else { // Reject the connection and stay in Disconnected state itself - Log.w(TAG, "Incoming HearingAccess Connecting request rejected: " - + mDevice); + Log.w( + TAG, + "Incoming HearingAccess Connecting request rejected: " + mDevice); mNativeInterface.disconnectHapClient(mDevice); } break; @@ -323,8 +328,12 @@ final class HapClientStateMachine extends StateMachine { class Connecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_CONNECTING; broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState); @@ -332,16 +341,22 @@ final class HapClientStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting: process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connecting: process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -410,8 +425,12 @@ final class HapClientStateMachine extends StateMachine { class Disconnecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_DISCONNECTING; broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState); @@ -419,33 +438,41 @@ final class HapClientStateMachine extends StateMachine { @Override public void exit() { - log("Exit Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Disconnecting: process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Disconnecting: process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Disconnecting connection timeout: " + mDevice); - mNativeInterface.disconnectHapClient(mDevice); + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Disconnecting connection timeout: " + mDevice); + mNativeInterface.disconnectHapClient(mDevice); - HapClientStackEvent disconnectEvent = - new HapClientStackEvent( - HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - disconnectEvent.device = mDevice; - disconnectEvent.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, disconnectEvent); - break; - } + HapClientStackEvent disconnectEvent = + new HapClientStackEvent( + HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + disconnectEvent.device = mDevice; + disconnectEvent.valueInt1 = + HapClientStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, disconnectEvent); + break; + } case DISCONNECT: deferMessage(message); break; @@ -493,8 +520,9 @@ final class HapClientStateMachine extends StateMachine { transitionTo(mConnecting); } else { // Reject the connection and stay in Disconnecting state - Log.w(TAG, "Incoming HearingAccess Connecting request rejected: " - + mDevice); + Log.w( + TAG, + "Incoming HearingAccess Connecting request rejected: " + mDevice); mNativeInterface.disconnectHapClient(mDevice); } break; @@ -511,8 +539,12 @@ final class HapClientStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - Log.i(TAG, "Enter Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_CONNECTED; removeDeferredMessages(CONNECT); broadcastConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState); @@ -520,15 +552,21 @@ final class HapClientStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @Override public boolean processMessage(Message message) { - log("Connected: process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connected: process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java index 5b32da5357f..702522c9111 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java @@ -29,9 +29,7 @@ import com.android.bluetooth.Utils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -/** - * HearingAid Native Interface to/from JNI. - */ +/** HearingAid Native Interface to/from JNI. */ public class HearingAidNativeInterface { private static final String TAG = "HearingAidNativeInterface"; private BluetoothAdapter mAdapter; @@ -48,9 +46,7 @@ public class HearingAidNativeInterface { } } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static HearingAidNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -71,16 +67,14 @@ public class HearingAidNativeInterface { /** * Initializes the native interface. * - * priorities to configure. + *

priorities to configure. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { initNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { cleanupNative(); @@ -121,6 +115,7 @@ public class HearingAidNativeInterface { /** * Sets the HearingAid volume + * * @param volume */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -167,8 +162,8 @@ public class HearingAidNativeInterface { @VisibleForTesting void onDeviceAvailable(byte capabilities, long hiSyncId, byte[] address) { - HearingAidStackEvent event = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + HearingAidStackEvent event = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); event.device = getDevice(address); event.valueInt1 = capabilities; event.valueLong2 = hiSyncId; @@ -179,9 +174,14 @@ public class HearingAidNativeInterface { // Native methods that call into the JNI interface private native void initNative(); + private native void cleanupNative(); + private native boolean connectHearingAidNative(byte[] address); + private native boolean disconnectHearingAidNative(byte[] address); + private native boolean addToAcceptlistNative(byte[] address); + private native void setVolumeNative(int volume); } diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java index cc79e7d8837..68f90bd3828 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java @@ -61,9 +61,7 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -/** - * Provides Bluetooth HearingAid profile, as a service in the Bluetooth application. - */ +/** Provides Bluetooth HearingAid profile, as a service in the Bluetooth application. */ public class HearingAidService extends ProfileService { private static final String TAG = "HearingAidService"; @@ -79,13 +77,10 @@ public class HearingAidService extends ProfileService { private HandlerThread mStateMachinesThread; private BluetoothDevice mActiveDevice; - @VisibleForTesting - HearingAidNativeInterface mHearingAidNativeInterface; - @VisibleForTesting - AudioManager mAudioManager; + @VisibleForTesting HearingAidNativeInterface mHearingAidNativeInterface; + @VisibleForTesting AudioManager mAudioManager; - private final Map mStateMachines = - new HashMap<>(); + private final Map mStateMachines = new HashMap<>(); private final Map mDeviceHiSyncIdMap = new ConcurrentHashMap<>(); private final Map mDeviceCapabilitiesMap = new HashMap<>(); private final Map mHiSyncIdConnectedMap = new HashMap<>(); @@ -96,7 +91,7 @@ public class HearingAidService extends ProfileService { new AudioManagerOnAudioDevicesAddedCallback(); private final AudioManagerOnAudioDevicesRemovedCallback mAudioManagerOnAudioDevicesRemovedCallback = - new AudioManagerOnAudioDevicesRemovedCallback(); + new AudioManagerOnAudioDevicesRemovedCallback(); public HearingAidService(Context ctx) { super(ctx); @@ -118,15 +113,21 @@ public class HearingAidService extends ProfileService { throw new IllegalStateException("start() called twice"); } - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when HearingAidService starts"); - mHearingAidNativeInterface = Objects.requireNonNull(HearingAidNativeInterface.getInstance(), - "HearingAidNativeInterface cannot be null when HearingAidService starts"); - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when HearingAidService starts"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when HearingAidService starts"); + mHearingAidNativeInterface = + Objects.requireNonNull( + HearingAidNativeInterface.getInstance(), + "HearingAidNativeInterface cannot be null when HearingAidService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when HearingAidService starts"); mAudioManager = getSystemService(AudioManager.class); - Objects.requireNonNull(mAudioManager, - "AudioManager cannot be null when HearingAidService starts"); + Objects.requireNonNull( + mAudioManager, "AudioManager cannot be null when HearingAidService starts"); // Start handler thread for state machines mStateMachines.clear(); @@ -204,6 +205,7 @@ public class HearingAidService extends ProfileService { /** * Get the HearingAidService instance + * * @return HearingAidService instance */ public static synchronized HearingAidService getHearingAidService() { @@ -233,8 +235,8 @@ public class HearingAidService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "connect(): " + device); if (device == null) { return false; @@ -249,8 +251,8 @@ public class HearingAidService extends ProfileService { return false; } - long hiSyncId = mDeviceHiSyncIdMap.getOrDefault(device, - BluetoothHearingAid.HI_SYNC_ID_INVALID); + long hiSyncId = + mDeviceHiSyncIdMap.getOrDefault(device, BluetoothHearingAid.HI_SYNC_ID_INVALID); if (hiSyncId != mActiveDeviceHiSyncId && hiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID @@ -272,8 +274,9 @@ public class HearingAidService extends ProfileService { if (device.equals(storedDevice)) { continue; } - if (mDeviceHiSyncIdMap.getOrDefault(storedDevice, - BluetoothHearingAid.HI_SYNC_ID_INVALID) == hiSyncId) { + if (mDeviceHiSyncIdMap.getOrDefault( + storedDevice, BluetoothHearingAid.HI_SYNC_ID_INVALID) + == hiSyncId) { synchronized (mStateMachines) { HearingAidStateMachine sm = getOrCreateStateMachine(storedDevice); if (sm == null) { @@ -299,23 +302,25 @@ public class HearingAidService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "disconnect(): " + device); if (device == null) { return false; } - long hiSyncId = mDeviceHiSyncIdMap.getOrDefault(device, - BluetoothHearingAid.HI_SYNC_ID_INVALID); + long hiSyncId = + mDeviceHiSyncIdMap.getOrDefault(device, BluetoothHearingAid.HI_SYNC_ID_INVALID); for (BluetoothDevice storedDevice : mDeviceHiSyncIdMap.keySet()) { - if (mDeviceHiSyncIdMap.getOrDefault(storedDevice, - BluetoothHearingAid.HI_SYNC_ID_INVALID) == hiSyncId) { + if (mDeviceHiSyncIdMap.getOrDefault( + storedDevice, BluetoothHearingAid.HI_SYNC_ID_INVALID) + == hiSyncId) { synchronized (mStateMachines) { HearingAidStateMachine sm = mStateMachines.get(storedDevice); if (sm == null) { - Log.e(TAG, "Ignored disconnect request for " + device - + " : no state machine"); + Log.e( + TAG, + "Ignored disconnect request for " + device + " : no state machine"); continue; } sm.sendMessage(HearingAidStateMachine.DISCONNECT); @@ -342,8 +347,7 @@ public class HearingAidService extends ProfileService { } /** - * Check any peer device is connected. - * The check considers any peer device is connected. + * Check any peer device is connected. The check considers any peer device is connected. * * @param device the peer device to connect to * @return true if there are any peer device connected. @@ -358,8 +362,8 @@ public class HearingAidService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -450,10 +454,10 @@ public class HearingAidService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { synchronized (mStateMachines) { @@ -466,15 +470,14 @@ public class HearingAidService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -482,12 +485,12 @@ public class HearingAidService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HEARING_AID, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HEARING_AID, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -501,33 +504,31 @@ public class HearingAidService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.HEARING_AID); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HEARING_AID); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) void setVolume(int volume) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); mHearingAidNativeInterface.setVolume(volume); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getHiSyncId(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); if (device == null) { return BluetoothHearingAid.HI_SYNC_ID_INVALID; } @@ -602,8 +603,8 @@ public class HearingAidService extends ProfileService { Log.e(TAG, "setActiveDevice(" + device + "): failed because device not connected"); return false; } - Long deviceHiSyncId = mDeviceHiSyncIdMap.getOrDefault(device, - BluetoothHearingAid.HI_SYNC_ID_INVALID); + Long deviceHiSyncId = + mDeviceHiSyncIdMap.getOrDefault(device, BluetoothHearingAid.HI_SYNC_ID_INVALID); if (deviceHiSyncId != mActiveDeviceHiSyncId) { mActiveDeviceHiSyncId = deviceHiSyncId; reportActiveDevice(device, false); @@ -615,9 +616,9 @@ public class HearingAidService extends ProfileService { /** * Get the connected physical Hearing Aid devices that are active * - * @return the list of active devices. The first element is the left active - * device; the second element is the right active device. If either or both side - * is not active, it will be null on that position + * @return the list of active devices. The first element is the left active device; the second + * element is the right active device. If either or both side is not active, it will be null + * on that position */ public List getActiveDevices() { ArrayList activeDevices = new ArrayList<>(); @@ -645,15 +646,21 @@ public class HearingAidService extends ProfileService { } void messageFromNative(HearingAidStackEvent stackEvent) { - Objects.requireNonNull(stackEvent.device, - "Device should never be null, event: " + stackEvent); + Objects.requireNonNull( + stackEvent.device, "Device should never be null, event: " + stackEvent); if (stackEvent.type == HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE) { BluetoothDevice device = stackEvent.device; int capabilities = stackEvent.valueInt1; long hiSyncId = stackEvent.valueLong2; - Log.d(TAG, "Device available: device=" + device + " capabilities=" - + capabilities + " hiSyncId=" + hiSyncId); + Log.d( + TAG, + "Device available: device=" + + device + + " capabilities=" + + capabilities + + " hiSyncId=" + + hiSyncId); mDeviceCapabilitiesMap.put(device, capabilities); mDeviceHiSyncIdMap.put(device, hiSyncId); return; @@ -686,8 +693,9 @@ public class HearingAidService extends ProfileService { mAdapterService.handleActiveDeviceChange(BluetoothProfile.HEARING_AID, mActiveDevice); Intent intent = new Intent(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mActiveDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT); } @@ -739,13 +747,19 @@ public class HearingAidService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_HEARING_AID_STATE_MACHINES) { - Log.e(TAG, "Maximum number of HearingAid state machines reached: " - + MAX_HEARING_AID_STATE_MACHINES); + Log.e( + TAG, + "Maximum number of HearingAid state machines reached: " + + MAX_HEARING_AID_STATE_MACHINES); return null; } Log.d(TAG, "Creating a new state machine for " + device); - sm = HearingAidStateMachine.make(device, this, - mHearingAidNativeInterface, mStateMachinesThread.getLooper()); + sm = + HearingAidStateMachine.make( + device, + this, + mHearingAidNativeInterface, + mStateMachinesThread.getLooper()); mStateMachines.put(device, sm); return sm; } @@ -766,10 +780,13 @@ public class HearingAidService extends ProfileService { } // Note: This is just a safety check for handling illegal call - setActiveDevice(null). - if (device == null && stopAudio + if (device == null + && stopAudio && getConnectionState(mActiveDevice) == BluetoothProfile.STATE_CONNECTED) { - Log.e(TAG, "Illegal arguments: stopAudio should be false when the active hearing aid " - + "is still connected!"); + Log.e( + TAG, + "Illegal arguments: stopAudio should be false when the active hearing aid " + + "is still connected!"); stopAudio = false; } @@ -777,22 +794,32 @@ public class HearingAidService extends ProfileService { mActiveDevice = device; - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, - BluetoothProfile.HEARING_AID, mAdapterService.obfuscateAddress(device), + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, + BluetoothProfile.HEARING_AID, + mAdapterService.obfuscateAddress(device), mAdapterService.getMetricId(device)); - Log.d(TAG, "Hearing Aid audio: " + previousAudioDevice + " -> " + device - + ". Stop audio: " + stopAudio); + Log.d( + TAG, + "Hearing Aid audio: " + + previousAudioDevice + + " -> " + + device + + ". Stop audio: " + + stopAudio); if (device != null) { - mAudioManager.registerAudioDeviceCallback(mAudioManagerOnAudioDevicesAddedCallback, - mHandler); + mAudioManager.registerAudioDeviceCallback( + mAudioManagerOnAudioDevicesAddedCallback, mHandler); } else { - mAudioManager.registerAudioDeviceCallback(mAudioManagerOnAudioDevicesRemovedCallback, - mHandler); + mAudioManager.registerAudioDeviceCallback( + mAudioManagerOnAudioDevicesRemovedCallback, mHandler); } - mAudioManager.handleBluetoothActiveDeviceChanged(device, previousAudioDevice, + mAudioManager.handleBluetoothActiveDeviceChanged( + device, + previousAudioDevice, BluetoothProfileConnectionInfo.createHearingAidInfo(!stopAudio)); } @@ -835,8 +862,9 @@ public class HearingAidService extends ProfileService { synchronized (mStateMachines) { HearingAidStateMachine sm = mStateMachines.get(device); if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); + Log.w( + TAG, + "removeStateMachine: device " + device + " does not have a state machine"); return; } Log.i(TAG, "removeStateMachine: removing state machine for device: " + device); @@ -857,11 +885,16 @@ public class HearingAidService extends ProfileService { return result; } - synchronized void connectionStateChanged(BluetoothDevice device, int fromState, - int toState) { + synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { if ((device == null) || (fromState == toState)) { - Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device - + " fromState=" + fromState + " toState=" + toState); + Log.e( + TAG, + "connectionStateChanged: unexpected invocation. device=" + + device + + " fromState=" + + fromState + + " toState=" + + toState); return; } if (toState == BluetoothProfile.STATE_CONNECTED) { @@ -900,14 +933,11 @@ public class HearingAidService extends ProfileService { device, BluetoothProfile.HEARING_AID, toState, fromState); } - /** - * Binder object: must be a static class or memory leak may occur - */ + /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting static class BluetoothHearingAidBinder extends IBluetoothHearingAid.Stub implements IProfileServiceBinder { - @VisibleForTesting - boolean mIsTesting = false; + @VisibleForTesting boolean mIsTesting = false; private HearingAidService mService; @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java index 932eb184bd2..5772ed685ca 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java @@ -19,8 +19,8 @@ package com.android.bluetooth.hearingaid; import android.bluetooth.BluetoothDevice; /** - * Stack event sent via a callback from JNI to Java, or generated - * internally by the Hearing Aid State Machine. + * Stack event sent via a callback from JNI to Java, or generated internally by the Hearing Aid + * State Machine. */ public class HearingAidStackEvent { // Event types for STACK_EVENT message (coming from native) diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java index 12c2c530c4b..4fc71b373f7 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java @@ -15,34 +15,18 @@ */ /** - * Bluetooth HearingAid StateMachine. There is one instance per remote device. - * - "Disconnected" and "Connected" are steady states. - * - "Connecting" and "Disconnecting" are transient states until the - * connection / disconnection is completed. + * Bluetooth HearingAid StateMachine. There is one instance per remote device. - "Disconnected" and + * "Connected" are steady states. - "Connecting" and "Disconnecting" are transient states until the + * connection / disconnection is completed. * + *

(Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting)<--->(Disconnecting) | ^ CONNECTED + * | | DISCONNECT V | (Connected) NOTES: - If state machine is in "Connecting" state and the remote + * device sends DISCONNECT request, the state machine transitions to "Disconnecting" state. - + * Similarly, if the state machine is in "Disconnecting" state and the remote device sends CONNECT + * request, the state machine transitions to "Connecting" state. * - * (Disconnected) - * | ^ - * CONNECT | | DISCONNECTED - * V | - * (Connecting)<--->(Disconnecting) - * | ^ - * CONNECTED | | DISCONNECT - * V | - * (Connected) - * NOTES: - * - If state machine is in "Connecting" state and the remote device sends - * DISCONNECT request, the state machine transitions to "Disconnecting" state. - * - Similarly, if the state machine is in "Disconnecting" state and the remote device - * sends CONNECT request, the state machine transitions to "Connecting" state. - * - * DISCONNECT - * (Connecting) ---------------> (Disconnecting) - * <--------------- - * CONNECT - * + *

DISCONNECT (Connecting) ---------------> (Disconnecting) <--------------- CONNECT */ - package com.android.bluetooth.hearingaid; import static android.Manifest.permission.BLUETOOTH_CONNECT; @@ -71,13 +55,11 @@ final class HearingAidStateMachine extends StateMachine { static final int CONNECT = 1; static final int DISCONNECT = 2; - @VisibleForTesting - static final int STACK_EVENT = 101; + @VisibleForTesting static final int STACK_EVENT = 101; private static final int CONNECT_TIMEOUT = 201; // NOTE: the value is not "final" - it is modified in the unit tests - @VisibleForTesting - static int sConnectTimeoutMs = 30000; // 30s + @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s private Disconnected mDisconnected; private Connecting mConnecting; @@ -91,8 +73,11 @@ final class HearingAidStateMachine extends StateMachine { private final BluetoothDevice mDevice; - HearingAidStateMachine(BluetoothDevice device, HearingAidService svc, - HearingAidNativeInterface nativeInterface, Looper looper) { + HearingAidStateMachine( + BluetoothDevice device, + HearingAidService svc, + HearingAidNativeInterface nativeInterface, + Looper looper) { super(TAG, looper); mDevice = device; mService = svc; @@ -111,11 +96,14 @@ final class HearingAidStateMachine extends StateMachine { setInitialState(mDisconnected); } - static HearingAidStateMachine make(BluetoothDevice device, HearingAidService svc, - HearingAidNativeInterface nativeInterface, Looper looper) { + static HearingAidStateMachine make( + BluetoothDevice device, + HearingAidService svc, + HearingAidNativeInterface nativeInterface, + Looper looper) { Log.i(TAG, "make for device " + device); - HearingAidStateMachine HearingAidSm = new HearingAidStateMachine(device, svc, - nativeInterface, looper); + HearingAidStateMachine HearingAidSm = + new HearingAidStateMachine(device, svc, nativeInterface, looper); HearingAidSm.start(); return HearingAidSm; } @@ -133,30 +121,39 @@ final class HearingAidStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_DISCONNECTED; removeDeferredMessages(DISCONNECT); if (mLastConnectionState != -1) { // Don't broadcast during startup - broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, - mLastConnectionState); + broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, mLastConnectionState); } } @Override public void exit() { - log("Exit Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + log( + "Exit Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected process message(" + mDevice + "): " + messageWhatToString( - message.what)); + log( + "Disconnected process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -238,8 +235,12 @@ final class HearingAidStateMachine extends StateMachine { class Connecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_CONNECTING; broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState); @@ -247,16 +248,22 @@ final class HearingAidStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -329,8 +336,12 @@ final class HearingAidStateMachine extends StateMachine { class Disconnecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_DISCONNECTING; broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState); @@ -338,32 +349,40 @@ final class HearingAidStateMachine extends StateMachine { @Override public void exit() { - log("Exit Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Disconnecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Disconnecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Disconnecting connection timeout: " + mDevice); - mNativeInterface.disconnectHearingAid(mDevice); - HearingAidStackEvent disconnectEvent = - new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - disconnectEvent.device = mDevice; - disconnectEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, disconnectEvent); - break; - } + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Disconnecting connection timeout: " + mDevice); + mNativeInterface.disconnectHearingAid(mDevice); + HearingAidStackEvent disconnectEvent = + new HearingAidStackEvent( + HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + disconnectEvent.device = mDevice; + disconnectEvent.valueInt1 = + HearingAidStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, disconnectEvent); + break; + } case DISCONNECT: deferMessage(message); break; @@ -428,8 +447,12 @@ final class HearingAidStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - Log.i(TAG, "Enter Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_CONNECTED; removeDeferredMessages(CONNECT); broadcastConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState); @@ -437,15 +460,17 @@ final class HearingAidStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @Override public boolean processMessage(Message message) { - log("Connected process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log("Connected process message(" + mDevice + "): " + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -514,8 +539,13 @@ final class HearingAidStateMachine extends StateMachine { // This method does not check for error condition (newState == prevState) private void broadcastConnectionState(int newState, int prevState) { - log("Connection state " + mDevice + ": " + profileStateToString(prevState) - + "->" + profileStateToString(newState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(prevState) + + "->" + + profileStateToString(newState)); mService.connectionStateChanged(mDevice, prevState, newState); @@ -523,7 +553,8 @@ final class HearingAidStateMachine extends StateMachine { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mService.sendBroadcast( intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); @@ -567,7 +598,7 @@ final class HearingAidStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); diff --git a/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java b/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java index 13f94e69f9c..2b83a13bca6 100644 --- a/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java +++ b/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java @@ -42,29 +42,28 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.HashMap; -/** - * Helper for managing phonebook presentation over AT commands - */ +/** Helper for managing phonebook presentation over AT commands */ public class AtPhonebook { private static final String TAG = "BluetoothAtPhonebook"; - /** The projection to use when querying the call log database in response - * to AT+CPBR for the MC, RC, and DC phone books (missed, received, and - * dialed calls respectively) + /** + * The projection to use when querying the call log database in response to AT+CPBR for the MC, + * RC, and DC phone books (missed, received, and dialed calls respectively) */ - private static final String[] CALLS_PROJECTION = new String[]{ - Calls._ID, Calls.NUMBER, Calls.NUMBER_PRESENTATION - }; + private static final String[] CALLS_PROJECTION = + new String[] {Calls._ID, Calls.NUMBER, Calls.NUMBER_PRESENTATION}; - /** The projection to use when querying the contacts database in response - * to AT+CPBR for the ME phonebook (saved phone numbers). + /** + * The projection to use when querying the contacts database in response to AT+CPBR for the ME + * phonebook (saved phone numbers). */ - private static final String[] PHONES_PROJECTION = new String[]{ - Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER, Phone.TYPE - }; + private static final String[] PHONES_PROJECTION = + new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER, Phone.TYPE}; - /** Android supports as many phonebook entries as the flash can hold, but - * BT periphals don't. Limit the number we'll report. */ + /** + * Android supports as many phonebook entries as the flash can hold, but BT periphals don't. + * Limit the number we'll report. + */ private static final int MAX_PHONEBOOK_SIZE = 16384; private static final String OUTGOING_CALL_WHERE = Calls.TYPE + "=" + Calls.OUTGOING_TYPE; @@ -83,21 +82,17 @@ public class AtPhonebook { private Context mContext; private ContentResolver mContentResolver; private HeadsetNativeInterface mNativeInterface; - @VisibleForTesting - String mCurrentPhonebook; - @VisibleForTesting - String mCharacterSet = "UTF-8"; + @VisibleForTesting String mCurrentPhonebook; + @VisibleForTesting String mCharacterSet = "UTF-8"; - @VisibleForTesting - int mCpbrIndex1, mCpbrIndex2; + @VisibleForTesting int mCpbrIndex1, mCpbrIndex2; private boolean mCheckingAccessPermission; // package and class name to which we send intent to check phone book access permission private final String mPairingPackage; @VisibleForTesting - final HashMap mPhonebooks = - new HashMap(4); + final HashMap mPhonebooks = new HashMap(4); static final int TYPE_UNKNOWN = -1; static final int TYPE_READ = 0; @@ -106,16 +101,16 @@ public class AtPhonebook { public AtPhonebook(Context context, HeadsetNativeInterface nativeInterface) { mContext = context; - mPairingPackage = SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - context.getString(R.string.pairing_ui_package)); + mPairingPackage = + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, context.getString(R.string.pairing_ui_package)); mContentResolver = context.getContentResolver(); mNativeInterface = nativeInterface; - mPhonebooks.put("DC", new PhonebookResult()); // dialled calls - mPhonebooks.put("RC", new PhonebookResult()); // received calls - mPhonebooks.put("MC", new PhonebookResult()); // missed calls - mPhonebooks.put("ME", new PhonebookResult()); // mobile phonebook - mCurrentPhonebook = "ME"; // default to mobile phonebook + mPhonebooks.put("DC", new PhonebookResult()); // dialled calls + mPhonebooks.put("RC", new PhonebookResult()); // received calls + mPhonebooks.put("MC", new PhonebookResult()); // missed calls + mPhonebooks.put("ME", new PhonebookResult()); // mobile phonebook + mCurrentPhonebook = "ME"; // default to mobile phonebook mCpbrIndex1 = mCpbrIndex2 = -1; } @@ -127,8 +122,8 @@ public class AtPhonebook { public String getLastDialledNumber() { String[] projection = {Calls.NUMBER}; Bundle queryArgs = new Bundle(); - queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, - Calls.TYPE + "=" + Calls.OUTGOING_TYPE); + queryArgs.putString( + ContentResolver.QUERY_ARG_SQL_SELECTION, Calls.TYPE + "=" + Calls.OUTGOING_TYPE); queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, Calls.DEFAULT_SORT_ORDER); queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 1); @@ -188,8 +183,10 @@ public class AtPhonebook { } String characterSet = ((atString.split("="))[1]); characterSet = characterSet.replace("\"", ""); - if (characterSet.equals("GSM") || characterSet.equals("IRA") || characterSet.equals( - "UTF-8") || characterSet.equals("UTF8")) { + if (characterSet.equals("GSM") + || characterSet.equals("IRA") + || characterSet.equals("UTF-8") + || characterSet.equals("UTF8")) { mCharacterSet = characterSet; atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; } else { @@ -229,8 +226,12 @@ public class AtPhonebook { } int size = pbr.cursor.getCount(); atCommandResponse = - "+CPBS: \"" + mCurrentPhonebook + "\"," + size + "," + getMaxPhoneBookSize( - size); + "+CPBS: \"" + + mCurrentPhonebook + + "\"," + + size + + "," + + getMaxPhoneBookSize(size); pbr.cursor.close(); pbr.cursor = null; atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; @@ -291,11 +292,11 @@ public class AtPhonebook { if ("SM".equals(mCurrentPhonebook)) { size = 0; } else { - PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true); //false); + PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true); // false); if (pbr == null) { atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED; - mNativeInterface.atResponseCode(remoteDevice, atCommandResult, - atCommandErrorCode); + mNativeInterface.atResponseCode( + remoteDevice, atCommandResult, atCommandErrorCode); break; } size = pbr.cursor.getCount(); @@ -312,30 +313,30 @@ public class AtPhonebook { mNativeInterface.atResponseString(remoteDevice, atCommandResponse); mNativeInterface.atResponseCode(remoteDevice, atCommandResult, atCommandErrorCode); break; - // Read PhoneBook Entries + // Read PhoneBook Entries case TYPE_READ: case TYPE_SET: // Set & read // Phone Book Read Request // AT+CPBR=[,] Log.d(TAG, "handleCpbrCommand - set/read command"); if (mCpbrIndex1 != -1) { - /* handling a CPBR at the moment, reject this CPBR command */ + /* handling a CPBR at the moment, reject this CPBR command */ atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED; - mNativeInterface.atResponseCode(remoteDevice, atCommandResult, - atCommandErrorCode); + mNativeInterface.atResponseCode( + remoteDevice, atCommandResult, atCommandErrorCode); break; } // Parse indexes int index1; int index2; if ((atString.split("=")).length < 2) { - mNativeInterface.atResponseCode(remoteDevice, atCommandResult, - atCommandErrorCode); + mNativeInterface.atResponseCode( + remoteDevice, atCommandResult, atCommandErrorCode); break; } String atCommand = (atString.split("="))[1]; String[] indices = atCommand.split(","); - //replace AT command separator ';' from the index if any + // replace AT command separator ';' from the index if any for (int i = 0; i < indices.length; i++) { indices[i] = indices[i].replace(';', ' ').trim(); } @@ -349,8 +350,8 @@ public class AtPhonebook { } catch (Exception e) { Log.d(TAG, "handleCpbrCommand - exception - invalid chars: " + e.toString()); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; - mNativeInterface.atResponseCode(remoteDevice, atCommandResult, - atCommandErrorCode); + mNativeInterface.atResponseCode( + remoteDevice, atCommandResult, atCommandErrorCode); break; } mCpbrIndex1 = index1; @@ -362,14 +363,16 @@ public class AtPhonebook { mCheckingAccessPermission = false; atCommandResult = processCpbrCommand(remoteDevice); mCpbrIndex1 = mCpbrIndex2 = -1; - mNativeInterface.atResponseCode(remoteDevice, atCommandResult, - atCommandErrorCode); + mNativeInterface.atResponseCode( + remoteDevice, atCommandResult, atCommandErrorCode); break; } else if (permission == BluetoothDevice.ACCESS_REJECTED) { mCheckingAccessPermission = false; mCpbrIndex1 = mCpbrIndex2 = -1; - mNativeInterface.atResponseCode(remoteDevice, - HeadsetHalConstants.AT_RESPONSE_ERROR, BluetoothCmeError.AG_FAILURE); + mNativeInterface.atResponseCode( + remoteDevice, + HeadsetHalConstants.AT_RESPONSE_ERROR, + BluetoothCmeError.AG_FAILURE); } // If checkAccessPermission(remoteDevice) has returned // BluetoothDevice.ACCESS_UNKNOWN, we will continue the process in @@ -384,10 +387,9 @@ public class AtPhonebook { } } - /** Get the most recent result for the given phone book, - * with the cursor ready to go. - * If force then re-query that phonebook - * Returns null if the cursor is not ready + /** + * Get the most recent result for the given phone book, with the cursor ready to go. If force + * then re-query that phonebook Returns null if the cursor is not ready */ @VisibleForTesting synchronized PhonebookResult getPhonebookResult(String pb, boolean force) { @@ -434,8 +436,14 @@ public class AtPhonebook { queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, where); queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, Calls.DEFAULT_SORT_ORDER); queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, MAX_PHONEBOOK_SIZE); - pbr.cursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mContentResolver, - Calls.CONTENT_URI, CALLS_PROJECTION, queryArgs, null); + pbr.cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + Calls.CONTENT_URI, + CALLS_PROJECTION, + queryArgs, + null); if (pbr.cursor == null) { return false; @@ -450,8 +458,14 @@ public class AtPhonebook { queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, where); queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, MAX_PHONEBOOK_SIZE); final Uri phoneContentUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); - pbr.cursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mContentResolver, - phoneContentUri, PHONES_PROJECTION, queryArgs, null); + pbr.cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + phoneContentUri, + PHONES_PROJECTION, + queryArgs, + null); if (pbr.cursor == null) { return false; @@ -509,7 +523,7 @@ public class AtPhonebook { } // Check phonebook - PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true); //false); + PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true); // false); if (pbr == null) { Log.e(TAG, "pbr is null"); return atCommandResult; @@ -519,7 +533,9 @@ public class AtPhonebook { // Send OK instead of ERROR if these checks fail. // When we send error, certain kits like BMW disconnect the // Handsfree connection. - if (pbr.cursor.getCount() == 0 || mCpbrIndex1 <= 0 || mCpbrIndex2 < mCpbrIndex1 + if (pbr.cursor.getCount() == 0 + || mCpbrIndex1 <= 0 + || mCpbrIndex2 < mCpbrIndex1 || mCpbrIndex1 > pbr.cursor.getCount()) { atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; Log.e(TAG, "Invalid request or no results, returning"); @@ -527,8 +543,10 @@ public class AtPhonebook { } if (mCpbrIndex2 > pbr.cursor.getCount()) { - Log.w(TAG, "max index requested is greater than number of records" - + " available, resetting it"); + Log.w( + TAG, + "max index requested is greater than number of records" + + " available, resetting it"); mCpbrIndex2 = pbr.cursor.getCount(); } // Process @@ -647,7 +665,8 @@ public class AtPhonebook { Log.d(TAG, "checkAccessPermission - ACTION_CONNECTION_ACCESS_REQUEST"); Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); intent.setPackage(mPairingPackage); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, remoteDevice); // Leave EXTRA_PACKAGE_NAME and EXTRA_CLASS_NAME field empty. diff --git a/android/app/src/com/android/bluetooth/hfp/BluetoothCmeError.java b/android/app/src/com/android/bluetooth/hfp/BluetoothCmeError.java index 1f2a45dadf9..687dfc794be 100644 --- a/android/app/src/com/android/bluetooth/hfp/BluetoothCmeError.java +++ b/android/app/src/com/android/bluetooth/hfp/BluetoothCmeError.java @@ -41,4 +41,3 @@ public class BluetoothCmeError { public static final int NO_SERVICE = 30; public static final int ONLY_911_ALLOWED = 32; } - diff --git a/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java b/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java index 75c0bc37644..650f159b486 100644 --- a/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java +++ b/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java @@ -27,9 +27,9 @@ import java.util.List; /** * A proxy class that facilitates testing of the BluetoothInCallService class. * - * This is necessary due to the "final" attribute of the BluetoothHeadset class. In order to - * test the correct functioning of the BluetoothInCallService class, the final class must be put - * into a container that can be mocked correctly. + *

This is necessary due to the "final" attribute of the BluetoothHeadset class. In order to test + * the correct functioning of the BluetoothInCallService class, the final class must be put into a + * container that can be mocked correctly. */ public class BluetoothHeadsetProxy { @@ -40,24 +40,22 @@ public class BluetoothHeadsetProxy { } public void closeBluetoothHeadsetProxy(Context context) { - final BluetoothManager btManager = - context.getSystemService(BluetoothManager.class); + final BluetoothManager btManager = context.getSystemService(BluetoothManager.class); if (btManager != null) { btManager.getAdapter().closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); } } - public void clccResponse(int index, int direction, int status, int mode, boolean mpty, - String number, int type) { + public void clccResponse( + int index, int direction, int status, int mode, boolean mpty, String number, int type) { mBluetoothHeadset.clccResponse(index, direction, status, mode, mpty, number, type); } - public void phoneStateChanged(int numActive, int numHeld, int callState, String number, - int type, String name) { + public void phoneStateChanged( + int numActive, int numHeld, int callState, String number, int type, String name) { - mBluetoothHeadset.phoneStateChanged(numActive, numHeld, callState, number, type, - name); + mBluetoothHeadset.phoneStateChanged(numActive, numHeld, callState, number, type, name); } public List getConnectedDevices() { diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java index e39c6d95342..27c6343032d 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java @@ -15,17 +15,15 @@ */ package com.android.bluetooth.hfp; -/** - * An object that represents AG indicator enable states - */ +/** An object that represents AG indicator enable states */ public class HeadsetAgIndicatorEnableState extends HeadsetMessageObject { public boolean service; public boolean roam; public boolean signal; public boolean battery; - HeadsetAgIndicatorEnableState(boolean newService, boolean newRoam, boolean newSignal, - boolean newBattery) { + HeadsetAgIndicatorEnableState( + boolean newService, boolean newRoam, boolean newSignal, boolean newBattery) { service = newService; roam = newRoam; signal = newSignal; @@ -38,7 +36,9 @@ public class HeadsetAgIndicatorEnableState extends HeadsetMessageObject { return false; } HeadsetAgIndicatorEnableState other = (HeadsetAgIndicatorEnableState) obj; - return service == other.service && roam == other.roam && signal == other.signal + return service == other.service + && roam == other.roam + && signal == other.signal && battery == other.battery; } diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java index df45e75faa1..a0d32c7e300 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java @@ -17,38 +17,31 @@ package com.android.bluetooth.hfp; import java.util.Objects; -/** - * A blob of data representing an overall call state on the phone - */ +/** A blob of data representing an overall call state on the phone */ class HeadsetCallState extends HeadsetMessageObject { - /** - * Number of active calls - */ + /** Number of active calls */ int mNumActive; - /** - * Number of held calls - */ + + /** Number of held calls */ int mNumHeld; + /** - * Current call setup state as defined in bthf_call_state_t of bt_hf.h or - * {@link com.android.server.telecom.BluetoothPhoneServiceImpl} or {@link HeadsetHalConstants} + * Current call setup state as defined in bthf_call_state_t of bt_hf.h or {@link + * com.android.server.telecom.BluetoothPhoneServiceImpl} or {@link HeadsetHalConstants} */ int mCallState; - /** - * Currently active call's phone number - */ + + /** Currently active call's phone number */ String mNumber; - /** - * Phone number type - */ + + /** Phone number type */ int mType; - /** - * Caller display name - */ + + /** Caller display name */ String mName; - HeadsetCallState(int numActive, int numHeld, int callState, String number, int type, - String name) { + HeadsetCallState( + int numActive, int numHeld, int callState, String number, int type, String name) { mNumActive = numActive; mNumHeld = numHeld; mCallState = callState; @@ -93,9 +86,12 @@ class HeadsetCallState extends HeadsetMessageObject { return false; } HeadsetCallState that = (HeadsetCallState) object; - return mNumActive == that.mNumActive && mNumHeld == that.mNumHeld - && mCallState == that.mCallState && Objects.equals(mNumber, that.mNumber) - && mType == that.mType && Objects.equals(mName, that.mName); + return mNumActive == that.mNumActive + && mNumHeld == that.mNumHeld + && mCallState == that.mCallState + && Objects.equals(mNumber, that.mNumber) + && mType == that.mType + && Objects.equals(mName, that.mName); } @Override diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java b/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java index f34fb34ae87..bd47273e636 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java @@ -18,54 +18,43 @@ package com.android.bluetooth.hfp; /** * A blob of response data to AT+CLCC command from HF * - * Example: - * AT+CLCC - * +CLCC:[index],[direction],[status],[mode],[mpty][,[number],[type]] + *

Example: AT+CLCC +CLCC:[index],[direction],[status],[mode],[mpty][,[number],[type]] */ class HeadsetClccResponse extends HeadsetMessageObject { - /** - * Index of the call, starting with 1, by the sequence of setup or receiving the calls - */ + /** Index of the call, starting with 1, by the sequence of setup or receiving the calls */ int mIndex; - /** - * Direction of the call, 0 is outgoing, 1 is incoming - */ + + /** Direction of the call, 0 is outgoing, 1 is incoming */ int mDirection; + /** - * Status of the call, currently defined in bthf_call_state_t of bt_hf.h or - * {@link com.android.server.telecom.BluetoothPhoneServiceImpl} or {@link HeadsetHalConstants} + * Status of the call, currently defined in bthf_call_state_t of bt_hf.h or {@link + * com.android.server.telecom.BluetoothPhoneServiceImpl} or {@link HeadsetHalConstants} * - * 0 - Active - * 1 - Held - * 2 - Dialing - * 3 - Alerting - * 4 - Incoming - * 5 - Waiting - * 6 - Call held by response and hold + *

0 - Active 1 - Held 2 - Dialing 3 - Alerting 4 - Incoming 5 - Waiting 6 - Call held by + * response and hold */ int mStatus; - /** - * Call mode, 0 is Voice, 1 is Data, 2 is Fax - */ + + /** Call mode, 0 is Voice, 1 is Data, 2 is Fax */ int mMode; + /** * Multi-party indicator * - * 0 - this call is NOT a member of a multi-party (conference) call - * 1 - this call IS a multi-party (conference) call + *

0 - this call is NOT a member of a multi-party (conference) call 1 - this call IS a + * multi-party (conference) call */ boolean mMpty; - /** - * Phone number of the call (optional) - */ + + /** Phone number of the call (optional) */ String mNumber; - /** - * Phone number type (optional) - */ + + /** Phone number type (optional) */ int mType; - HeadsetClccResponse(int index, int direction, int status, int mode, boolean mpty, String number, - int type) { + HeadsetClccResponse( + int index, int direction, int status, int mode, boolean mpty, String number, int type) { mIndex = index; mDirection = direction; mStatus = status; diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java index ed47fc702cf..8f69c8cf604 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java @@ -15,31 +15,27 @@ */ package com.android.bluetooth.hfp; -/** - * A blob of data representing AG's device state in response to an AT+CIND command from HF - */ +/** A blob of data representing AG's device state in response to an AT+CIND command from HF */ class HeadsetDeviceState extends HeadsetMessageObject { /** * Service availability indicator * - * 0 - no service, no home/roam network is available - * 1 - presence of service, home/roam network available + *

0 - no service, no home/roam network is available 1 - presence of service, home/roam + * network available */ int mService; + /** * Roaming status indicator * - * 0 - roaming is not active - * 1 - roaming is active + *

0 - roaming is not active 1 - roaming is active */ int mRoam; - /** - * Signal strength indicator, value ranges from 0 to 5 - */ + + /** Signal strength indicator, value ranges from 0 to 5 */ int mSignal; - /** - * Battery charge indicator from AG, value ranges from 0 to 5 - */ + + /** Battery charge indicator from AG, value ranges from 0 to 5 */ int mBatteryCharge; HeadsetDeviceState(int service, int roam, int signal, int batteryCharge) { diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java b/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java index e9ab90e7d8f..3d2701a57c6 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java @@ -17,9 +17,7 @@ package com.android.bluetooth.hfp; import android.os.Message; -/** - * An object passed through {@link Message#obj} on state machines - */ +/** An object passed through {@link Message#obj} on state machines */ public abstract class HeadsetMessageObject { /** * Build a representation of this object in a {@link StringBuilder} diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java b/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java index 9cb62b45d00..6167229c69e 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java @@ -29,9 +29,9 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; /** - * Defines native calls that are used by state machine/service to either send or receive - * messages to/from the native stack. This file is registered for the native methods in - * corresponding CPP file. + * Defines native calls that are used by state machine/service to either send or receive messages + * to/from the native stack. This file is registered for the native methods in corresponding CPP + * file. */ public class HeadsetNativeInterface { private static final String TAG = "HeadsetNativeInterface"; @@ -46,8 +46,10 @@ public class HeadsetNativeInterface { private AdapterService mAdapterService; private HeadsetNativeInterface() { - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when HeadsetNativeInterface init"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when HeadsetNativeInterface init"); } /** @@ -101,7 +103,9 @@ public class HeadsetNativeInterface { void onConnectionStateChanged(int state, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, state, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, + state, getDevice(address)); sendMessageToService(event); } @@ -110,15 +114,17 @@ public class HeadsetNativeInterface { private void onAudioStateChanged(int state, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, state, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, + state, getDevice(address)); sendMessageToService(event); } private void onVrStateChanged(int state, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_VR_STATE_CHANGED, state, - getDevice(address)); + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_VR_STATE_CHANGED, state, getDevice(address)); sendMessageToService(event); } @@ -136,28 +142,33 @@ public class HeadsetNativeInterface { private void onVolumeChanged(int type, int volume, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_VOLUME_CHANGED, type, volume, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_VOLUME_CHANGED, + type, + volume, getDevice(address)); sendMessageToService(event); } private void onDialCall(String number, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_DIAL_CALL, number, - getDevice(address)); + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_DIAL_CALL, number, getDevice(address)); sendMessageToService(event); } private void onSendDtmf(int dtmf, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_SEND_DTMF, dtmf, - getDevice(address)); + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_SEND_DTMF, dtmf, getDevice(address)); sendMessageToService(event); } private void onNoiseReductionEnable(boolean enable, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_NOISE_REDUCTION, enable ? 1 : 0, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_NOISE_REDUCTION, + enable ? 1 : 0, getDevice(address)); sendMessageToService(event); } @@ -176,15 +187,16 @@ public class HeadsetNativeInterface { } private void onAtChld(int chld, byte[] address) { - HeadsetStackEvent event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AT_CHLD, chld, - getDevice(address)); + HeadsetStackEvent event = + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_AT_CHLD, chld, getDevice(address)); sendMessageToService(event); } private void onAtCnum(byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST, - getDevice(address)); + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST, getDevice(address)); sendMessageToService(event); } @@ -208,8 +220,8 @@ public class HeadsetNativeInterface { private void onUnknownAt(String atString, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, atString, - getDevice(address)); + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT, atString, getDevice(address)); sendMessageToService(event); } @@ -220,24 +232,27 @@ public class HeadsetNativeInterface { } private void onATBind(String atString, byte[] address) { - HeadsetStackEvent event = new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, - getDevice(address)); + HeadsetStackEvent event = + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_BIND, atString, getDevice(address)); sendMessageToService(event); } private void onATBiev(int indId, int indValue, byte[] address) { HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIEV, indId, indValue, - getDevice(address)); + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_BIEV, indId, indValue, getDevice(address)); sendMessageToService(event); } - private void onAtBia(boolean service, boolean roam, boolean signal, boolean battery, - byte[] address) { + private void onAtBia( + boolean service, boolean roam, boolean signal, boolean battery, byte[] address) { HeadsetAgIndicatorEnableState agIndicatorEnableState = new HeadsetAgIndicatorEnableState(service, roam, signal, battery); HeadsetStackEvent event = - new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, agIndicatorEnableState, + new HeadsetStackEvent( + HeadsetStackEvent.EVENT_TYPE_BIA, + agIndicatorEnableState, getDevice(address)); sendMessageToService(event); } @@ -255,9 +270,7 @@ public class HeadsetNativeInterface { initializeNative(maxHfClients, inbandRingingEnabled); } - /** - * Closes the interface - */ + /** Closes the interface */ @VisibleForTesting public void cleanup() { cleanupNative(); @@ -364,7 +377,6 @@ public class HeadsetNativeInterface { return startVoiceRecognitionNative(getByteAddress(device)); } - /** * Stop voice recognition * @@ -403,10 +415,24 @@ public class HeadsetNativeInterface { * @return True on success, False on failure */ @VisibleForTesting - public boolean cindResponse(BluetoothDevice device, int service, int numActive, int numHeld, - int callState, int signal, int roam, int batteryCharge) { - return cindResponseNative(service, numActive, numHeld, callState, signal, roam, - batteryCharge, getByteAddress(device)); + public boolean cindResponse( + BluetoothDevice device, + int service, + int numActive, + int numHeld, + int callState, + int signal, + int roam, + int batteryCharge) { + return cindResponseNative( + service, + numActive, + numHeld, + callState, + signal, + roam, + batteryCharge, + getByteAddress(device)); } /** @@ -418,8 +444,12 @@ public class HeadsetNativeInterface { */ @VisibleForTesting public boolean notifyDeviceStatus(BluetoothDevice device, HeadsetDeviceState deviceState) { - return notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, - deviceState.mSignal, deviceState.mBatteryCharge, getByteAddress(device)); + return notifyDeviceStatusNative( + deviceState.mService, + deviceState.mRoam, + deviceState.mSignal, + deviceState.mBatteryCharge, + getByteAddress(device)); } /** @@ -427,25 +457,32 @@ public class HeadsetNativeInterface { * will be treated as NULL termination (Completes response) * * @param device target device - * @param index index of the call given by the sequence of setting up or receiving the calls - * as seen by the served subscriber. Calls hold their number until they are released. New - * calls take the lowest available number. + * @param index index of the call given by the sequence of setting up or receiving the calls as + * seen by the served subscriber. Calls hold their number until they are released. New calls + * take the lowest available number. * @param dir direction of the call, 0 (outgoing), 1 (incoming) - * @param status 0 = Active, 1 = Held, 2 = Dialing (outgoing calls only), 3 = Alerting - * (outgoing calls only), 4 = Incoming (incoming calls only), 5 = Waiting (incoming calls - * only), 6 = Call held by Response and Hold + * @param status 0 = Active, 1 = Held, 2 = Dialing (outgoing calls only), 3 = Alerting (outgoing + * calls only), 4 = Incoming (incoming calls only), 5 = Waiting (incoming calls only), 6 = + * Call held by Response and Hold * @param mode 0 (Voice), 1 (Data), 2 (FAX) - * @param mpty 0 - this call is NOT a member of a multi-party (conference) call, 1 - this - * call IS a member of a multi-party (conference) call + * @param mpty 0 - this call is NOT a member of a multi-party (conference) call, 1 - this call + * IS a member of a multi-party (conference) call * @param number optional * @param type optional * @return True on success, False on failure */ @VisibleForTesting - public boolean clccResponse(BluetoothDevice device, int index, int dir, int status, int mode, - boolean mpty, String number, int type) { - return clccResponseNative(index, dir, status, mode, mpty, number, type, - getByteAddress(device)); + public boolean clccResponse( + BluetoothDevice device, + int index, + int dir, + int status, + int mode, + boolean mpty, + String number, + int type) { + return clccResponseNative( + index, dir, status, mode, mpty, number, type, getByteAddress(device)); } /** @@ -461,12 +498,9 @@ public class HeadsetNativeInterface { } /** - * Notify of a call state change - * Each update notifies - * 1. Number of active/held/ringing calls - * 2. call_state: This denotes the state change that triggered this msg - * This will take one of the values from BtHfCallState - * 3. number & type: valid only for incoming & waiting call + * Notify of a call state change Each update notifies 1. Number of active/held/ringing calls 2. + * call_state: This denotes the state change that triggered this msg This will take one of the + * values from BtHfCallState 3. number & type: valid only for incoming & waiting call * * @param device target device for this update * @param callState callstate structure @@ -474,8 +508,13 @@ public class HeadsetNativeInterface { */ @VisibleForTesting public boolean phoneStateChange(BluetoothDevice device, HeadsetCallState callState) { - return phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, - callState.mCallState, callState.mNumber, callState.mType, callState.mName, + return phoneStateChangeNative( + callState.mNumActive, + callState.mNumHeld, + callState.mCallState, + callState.mNumber, + callState.mType, + callState.mName, getByteAddress(device)); } @@ -504,6 +543,7 @@ public class HeadsetNativeInterface { /** * Set the current active headset device for SCO audio + * * @param device current active SCO device * @return true on success */ @@ -552,19 +592,39 @@ public class HeadsetNativeInterface { private native boolean setVolumeNative(int volumeType, int volume, byte[] address); - private native boolean cindResponseNative(int service, int numActive, int numHeld, - int callState, int signal, int roam, int batteryCharge, byte[] address); - - private native boolean notifyDeviceStatusNative(int networkState, int serviceType, int signal, - int batteryCharge, byte[] address); - - private native boolean clccResponseNative(int index, int dir, int status, int mode, - boolean mpty, String number, int type, byte[] address); + private native boolean cindResponseNative( + int service, + int numActive, + int numHeld, + int callState, + int signal, + int roam, + int batteryCharge, + byte[] address); + + private native boolean notifyDeviceStatusNative( + int networkState, int serviceType, int signal, int batteryCharge, byte[] address); + + private native boolean clccResponseNative( + int index, + int dir, + int status, + int mode, + boolean mpty, + String number, + int type, + byte[] address); private native boolean copsResponseNative(String operatorName, byte[] address); - private native boolean phoneStateChangeNative(int numActive, int numHeld, int callState, - String number, int type, String name, byte[] address); + private native boolean phoneStateChangeNative( + int numActive, + int numHeld, + int callState, + String number, + int type, + String name, + byte[] address); private native boolean setScoAllowedNative(boolean value); diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java b/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java index c0982526d32..2f2a80088f5 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java @@ -22,9 +22,7 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; -/** - * Factory class for object initialization to help with unit testing - */ +/** Factory class for object initialization to help with unit testing */ public class HeadsetObjectsFactory { private static final String TAG = HeadsetObjectsFactory.class.getSimpleName(); private static HeadsetObjectsFactory sInstance; @@ -70,11 +68,15 @@ public class HeadsetObjectsFactory { * @param systemInterface system interface * @return a state machine that is initialized and started, ready to go */ - public HeadsetStateMachine makeStateMachine(BluetoothDevice device, Looper looper, - HeadsetService headsetService, AdapterService adapterService, - HeadsetNativeInterface nativeInterface, HeadsetSystemInterface systemInterface) { - return HeadsetStateMachine.make(device, looper, headsetService, adapterService, - nativeInterface, systemInterface); + public HeadsetStateMachine makeStateMachine( + BluetoothDevice device, + Looper looper, + HeadsetService headsetService, + AdapterService adapterService, + HeadsetNativeInterface nativeInterface, + HeadsetSystemInterface systemInterface) { + return HeadsetStateMachine.make( + device, looper, headsetService, adapterService, nativeInterface, systemInterface); } /** diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetPhoneState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetPhoneState.java index 2eed8303748..c5535522727 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetPhoneState.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetPhoneState.java @@ -38,10 +38,8 @@ import java.util.concurrent.Executor; /** * Class that manages Telephony states * - * Note: - * The methods in this class are not thread safe, don't call them from - * multiple threads. Call them from the HeadsetPhoneStateMachine message - * handler only. + *

Note: The methods in this class are not thread safe, don't call them from multiple threads. + * Call them from the HeadsetPhoneStateMachine message handler only. */ public class HeadsetPhoneState { private static final String TAG = "HeadsetPhoneState"; @@ -89,16 +87,15 @@ public class HeadsetPhoneState { mOnSubscriptionsChangedListener = new HeadsetPhoneStateOnSubscriptionChangedListener(); mSubscriptionManager.addOnSubscriptionsChangedListener( command -> mHandler.post(command), mOnSubscriptionsChangedListener); - mSignalStrengthUpdateRequest = new SignalStrengthUpdateRequest.Builder() - .setSignalThresholdInfos(Collections.EMPTY_LIST) - .setSystemThresholdReportingRequestedWhileIdle(true) - .build(); + mSignalStrengthUpdateRequest = + new SignalStrengthUpdateRequest.Builder() + .setSignalThresholdInfos(Collections.EMPTY_LIST) + .setSystemThresholdReportingRequestedWhileIdle(true) + .build(); } } - /** - * Cleanup this instance. Instance can no longer be used after calling this method. - */ + /** Cleanup this instance. Instance can no longer be used after calling this method. */ public void cleanup() { synchronized (mDeviceEventMap) { mDeviceEventMap.clear(); @@ -109,16 +106,28 @@ public class HeadsetPhoneState { @Override public String toString() { - return "HeadsetPhoneState [mTelephonyServiceAvailability=" + mCindService + ", mNumActive=" - + mNumActive + ", mCallState=" + mCallState + ", mNumHeld=" + mNumHeld - + ", mSignal=" + mCindSignal + ", mRoam=" + mCindRoam + ", mBatteryCharge=" - + mCindBatteryCharge + ", TelephonyEvents=" + getTelephonyEventsToListen() + "]"; + return "HeadsetPhoneState [mTelephonyServiceAvailability=" + + mCindService + + ", mNumActive=" + + mNumActive + + ", mCallState=" + + mCallState + + ", mNumHeld=" + + mNumHeld + + ", mSignal=" + + mCindSignal + + ", mRoam=" + + mCindRoam + + ", mBatteryCharge=" + + mCindBatteryCharge + + ", TelephonyEvents=" + + getTelephonyEventsToListen() + + "]"; } private int getTelephonyEventsToListen() { synchronized (mDeviceEventMap) { - return mDeviceEventMap.values() - .stream() + return mDeviceEventMap.values().stream() .reduce(PhoneStateListener.LISTEN_NONE, (a, b) -> a | b); } } @@ -179,8 +188,10 @@ public class HeadsetPhoneState { Log.i(TAG, "stopListenForPhoneState(), no listener indicates nothing is listening"); return; } - Log.i(TAG, "stopListenForPhoneState(), stopping listener, enabled_events=" - + getTelephonyEventsToListen()); + Log.i( + TAG, + "stopListenForPhoneState(), stopping listener, enabled_events=" + + getTelephonyEventsToListen()); mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); mPhoneStateListener = null; } @@ -255,9 +266,16 @@ public class HeadsetPhoneState { // use the service indicator, but only the signal indicator int signal = mCindService == HeadsetHalConstants.NETWORK_STATE_AVAILABLE ? mCindSignal : 0; - Log.d(TAG, "sendDeviceStateChanged. mService=" + mCindService - + " mSignal=" + mCindSignal + " mRoam=" + mCindRoam - + " mBatteryCharge=" + mCindBatteryCharge); + Log.d( + TAG, + "sendDeviceStateChanged. mService=" + + mCindService + + " mSignal=" + + mCindSignal + + " mRoam=" + + mCindRoam + + " mBatteryCharge=" + + mCindBatteryCharge); mHeadsetService.onDeviceStateChanged( new HeadsetDeviceState(mCindService, mCindRoam, signal, mCindBatteryCharge)); } @@ -294,11 +312,14 @@ public class HeadsetPhoneState { @Override public synchronized void onServiceStateChanged(ServiceState serviceState) { mServiceState = serviceState; - int cindService = (serviceState.getState() == ServiceState.STATE_IN_SERVICE) - ? HeadsetHalConstants.NETWORK_STATE_AVAILABLE - : HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE; - int newRoam = serviceState.getRoaming() ? HeadsetHalConstants.SERVICE_TYPE_ROAMING - : HeadsetHalConstants.SERVICE_TYPE_HOME; + int cindService = + (serviceState.getState() == ServiceState.STATE_IN_SERVICE) + ? HeadsetHalConstants.NETWORK_STATE_AVAILABLE + : HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE; + int newRoam = + serviceState.getRoaming() + ? HeadsetHalConstants.SERVICE_TYPE_ROAMING + : HeadsetHalConstants.SERVICE_TYPE_HOME; if (cindService == mCindService && newRoam == mCindRoam) { // De-bounce the state change diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java index 2b4d81165f9..922110478cf 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java @@ -85,36 +85,34 @@ import java.util.concurrent.FutureTask; /** * Provides Bluetooth Headset and Handsfree profile, as a service in the Bluetooth application. * - * Three modes for SCO audio: - * Mode 1: Telecom call through {@link #phoneStateChanged(int, int, int, String, int, String, - * boolean)} - * Mode 2: Virtual call through {@link #startScoUsingVirtualVoiceCall()} - * Mode 3: Voice recognition through {@link #startVoiceRecognition(BluetoothDevice)} + *

Three modes for SCO audio: Mode 1: Telecom call through {@link #phoneStateChanged(int, int, + * int, String, int, String, boolean)} Mode 2: Virtual call through {@link + * #startScoUsingVirtualVoiceCall()} Mode 3: Voice recognition through {@link + * #startVoiceRecognition(BluetoothDevice)} * - * When one mode is active, other mode cannot be started. API user has to terminate existing modes - * using the correct API or just {@link #disconnectAudio()} if user is a system service, before - * starting a new mode. + *

When one mode is active, other mode cannot be started. API user has to terminate existing + * modes using the correct API or just {@link #disconnectAudio()} if user is a system service, + * before starting a new mode. * - * {@link #connectAudio()} will start SCO audio at one of the above modes, but won't change mode + *

{@link #connectAudio()} will start SCO audio at one of the above modes, but won't change mode * {@link #disconnectAudio()} can happen in any mode to disconnect SCO * - * When audio is disconnected, only Mode 1 Telecom call will be persisted, both Mode 2 virtual call - * and Mode 3 voice call will be terminated upon SCO termination and client has to restart the mode. + *

When audio is disconnected, only Mode 1 Telecom call will be persisted, both Mode 2 virtual + * call and Mode 3 voice call will be terminated upon SCO termination and client has to restart the + * mode. * - * NOTE: SCO termination can either be initiated on the AG side or the HF side - * TODO(b/79660380): As a workaround, voice recognition will be terminated if virtual call or - * Telecom call is initiated while voice recognition is ongoing, in case calling app did not call - * {@link #stopVoiceRecognition(BluetoothDevice)} + *

NOTE: SCO termination can either be initiated on the AG side or the HF side TODO(b/79660380): + * As a workaround, voice recognition will be terminated if virtual call or Telecom call is + * initiated while voice recognition is ongoing, in case calling app did not call {@link + * #stopVoiceRecognition(BluetoothDevice)} * - * AG - Audio Gateway, device running this {@link HeadsetService}, e.g. Android Phone - * HF - Handsfree device, device running headset client, e.g. Wireless headphones or car kits + *

AG - Audio Gateway, device running this {@link HeadsetService}, e.g. Android Phone HF - + * Handsfree device, device running headset client, e.g. Wireless headphones or car kits */ public class HeadsetService extends ProfileService { private static final String TAG = "HeadsetService"; - /** - * HFP AG owned/managed components - */ + /** HFP AG owned/managed components */ private static final String HFP_AG_IN_CALL_SERVICE = BluetoothInCallService.class.getCanonicalName(); @@ -123,8 +121,9 @@ public class HeadsetService extends ProfileService { private static final String REJECT_SCO_IF_HFPC_CONNECTED_PROPERTY = "bluetooth.hfp.reject_sco_if_hfpc_connected"; private static final ParcelUuid[] HEADSET_UUIDS = {BluetoothUuid.HSP, BluetoothUuid.HFP}; - private static final int[] CONNECTING_CONNECTED_STATES = - {BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED}; + private static final int[] CONNECTING_CONNECTED_STATES = { + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED + }; private static final int DIALING_OUT_TIMEOUT_MS = 10000; private static final int CLCC_END_MARK_INDEX = 0; @@ -347,8 +346,9 @@ public class HeadsetService extends ProfileService { void onDeviceStateChanged(HeadsetDeviceState deviceState) { doForEachConnectedStateMachine( - stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.DEVICE_STATE_CHANGED, - deviceState)); + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine.DEVICE_STATE_CHANGED, deviceState)); } /** @@ -358,16 +358,17 @@ public class HeadsetService extends ProfileService { * @param stackEvent event from native stack */ void messageFromNative(HeadsetStackEvent stackEvent) { - Objects.requireNonNull(stackEvent.device, - "Device should never be null, event: " + stackEvent); + Objects.requireNonNull( + stackEvent.device, "Device should never be null, event: " + stackEvent); synchronized (mStateMachines) { HeadsetStateMachine stateMachine = mStateMachines.get(stackEvent.device); if (stackEvent.type == HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) { switch (stackEvent.valueInt) { case HeadsetHalConstants.CONNECTION_STATE_CONNECTED: - case HeadsetHalConstants.CONNECTION_STATE_CONNECTING: { - // Create new state machine if none is found - if (stateMachine == null) { + case HeadsetHalConstants.CONNECTION_STATE_CONNECTING: + { + // Create new state machine if none is found + if (stateMachine == null) { stateMachine = HeadsetObjectsFactory.getInstance() .makeStateMachine( @@ -377,10 +378,10 @@ public class HeadsetService extends ProfileService { mAdapterService, mNativeInterface, mSystemInterface); - mStateMachines.put(stackEvent.device, stateMachine); + mStateMachines.put(stackEvent.device, stateMachine); + } + break; } - break; - } } } if (stateMachine == null) { @@ -391,60 +392,86 @@ public class HeadsetService extends ProfileService { } } - private final BroadcastReceiver mHeadsetReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) { - Log.w(TAG, "mHeadsetReceiver, action is null"); - return; - } - switch (action) { - case Intent.ACTION_BATTERY_CHANGED: { - int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - if (batteryLevel < 0 || scale <= 0) { - Log.e(TAG, "Bad Battery Changed intent: batteryLevel=" + batteryLevel - + ", scale=" + scale); + private final BroadcastReceiver mHeadsetReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) { + Log.w(TAG, "mHeadsetReceiver, action is null"); return; } - int cindBatteryLevel = Math.round(batteryLevel * 5 / ((float) scale)); - mSystemInterface.getHeadsetPhoneState().setCindBatteryCharge(cindBatteryLevel); - break; - } - case AudioManager.ACTION_VOLUME_CHANGED: { - int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1); - if (streamType == AudioManager.STREAM_BLUETOOTH_SCO) { - doForEachConnectedStateMachine(stateMachine -> stateMachine.sendMessage( - HeadsetStateMachine.INTENT_SCO_VOLUME_CHANGED, intent)); - } - break; - } - case BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY: { - int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, - BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); - BluetoothDevice device = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - logD("Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY, device=" + device - + ", type=" + requestType); - if (requestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) { - synchronized (mStateMachines) { - final HeadsetStateMachine stateMachine = mStateMachines.get(device); - if (stateMachine == null) { - Log.wtf(TAG, "Cannot find state machine for " + device); - return; + switch (action) { + case Intent.ACTION_BATTERY_CHANGED: + { + int batteryLevel = + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + if (batteryLevel < 0 || scale <= 0) { + Log.e( + TAG, + "Bad Battery Changed intent: batteryLevel=" + + batteryLevel + + ", scale=" + + scale); + return; + } + int cindBatteryLevel = + Math.round(batteryLevel * 5 / ((float) scale)); + mSystemInterface + .getHeadsetPhoneState() + .setCindBatteryCharge(cindBatteryLevel); + break; } - stateMachine.sendMessage( - HeadsetStateMachine.INTENT_CONNECTION_ACCESS_REPLY, intent); - } + case AudioManager.ACTION_VOLUME_CHANGED: + { + int streamType = + intent.getIntExtra( + AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1); + if (streamType == AudioManager.STREAM_BLUETOOTH_SCO) { + doForEachConnectedStateMachine( + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine + .INTENT_SCO_VOLUME_CHANGED, + intent)); + } + break; + } + case BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY: + { + int requestType = + intent.getIntExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); + BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + logD( + "Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY," + + " device=" + + device + + ", type=" + + requestType); + if (requestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) { + synchronized (mStateMachines) { + final HeadsetStateMachine stateMachine = + mStateMachines.get(device); + if (stateMachine == null) { + Log.wtf(TAG, "Cannot find state machine for " + device); + return; + } + stateMachine.sendMessage( + HeadsetStateMachine.INTENT_CONNECTION_ACCESS_REPLY, + intent); + } + } + break; + } + default: + Log.w(TAG, "Unknown action " + action); } - break; } - default: - Log.w(TAG, "Unknown action " + action); - } - } - }; + }; public void handleBondStateChanged(BluetoothDevice device, int fromState, int toState) { mHandler.post(() -> bondStateChanged(device, toState)); @@ -467,9 +494,7 @@ public class HeadsetService extends ProfileService { } } - /** - * Handlers for incoming service calls - */ + /** Handlers for incoming service calls */ @VisibleForTesting static class BluetoothHeadsetBinder extends IBluetoothHeadset.Stub implements IProfileServiceBinder { @@ -825,14 +850,22 @@ public class HeadsetService extends ProfileService { @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean connect(BluetoothDevice device) { if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - Log.w(TAG, "connect: CONNECTION_POLICY_FORBIDDEN, device=" + device + ", " - + Utils.getUidPidString()); + Log.w( + TAG, + "connect: CONNECTION_POLICY_FORBIDDEN, device=" + + device + + ", " + + Utils.getUidPidString()); return false; } ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device); if (!BluetoothUuid.containsAnyUuid(featureUuids, HEADSET_UUIDS)) { - Log.e(TAG, "connect: Cannot connect to " + device + ": no headset UUID, " - + Utils.getUidPidString()); + Log.e( + TAG, + "connect: Cannot connect to " + + device + + ": no headset UUID, " + + Utils.getUidPidString()); return false; } synchronized (mStateMachines) { @@ -853,8 +886,12 @@ public class HeadsetService extends ProfileService { int connectionState = stateMachine.getConnectionState(); if (connectionState == BluetoothProfile.STATE_CONNECTED || connectionState == BluetoothProfile.STATE_CONNECTING) { - Log.w(TAG, "connect: device " + device - + " is already connected/connecting, connectionState=" + connectionState); + Log.w( + TAG, + "connect: device " + + device + + " is already connected/connecting, connectionState=" + + connectionState); return false; } List connectingConnectedDevices = @@ -897,8 +934,12 @@ public class HeadsetService extends ProfileService { int connectionState = stateMachine.getConnectionState(); if (connectionState != BluetoothProfile.STATE_CONNECTED && connectionState != BluetoothProfile.STATE_CONNECTING) { - Log.w(TAG, "disconnect: device " + device - + " not connected/connecting, connectionState=" + connectionState); + Log.w( + TAG, + "disconnect: device " + + device + + " not connected/connecting, connectionState=" + + connectionState); return false; } stateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, device); @@ -963,15 +1004,14 @@ public class HeadsetService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -979,11 +1019,17 @@ public class HeadsetService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - Log.i(TAG, "setConnectionPolicy: device=" + device - + ", connectionPolicy=" + connectionPolicy + ", " + Utils.getUidPidString()); - - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HEADSET, - connectionPolicy)) { + Log.i( + TAG, + "setConnectionPolicy: device=" + + device + + ", connectionPolicy=" + + connectionPolicy + + ", " + + Utils.getUidPidString()); + + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HEADSET, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -997,17 +1043,15 @@ public class HeadsetService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.HEADSET); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HEADSET); } boolean isNoiseReductionSupported(BluetoothDevice device) { @@ -1025,24 +1069,35 @@ public class HeadsetService extends ProfileService { // TODO(b/79660380): Workaround in case voice recognition was not terminated properly if (mVoiceRecognitionStarted) { boolean status = stopVoiceRecognition(mActiveDevice); - Log.w(TAG, "startVoiceRecognition: voice recognition is still active, just called " - + "stopVoiceRecognition, returned " + status + " on " + mActiveDevice - + ", please try again"); + Log.w( + TAG, + "startVoiceRecognition: voice recognition is still active, just called " + + "stopVoiceRecognition, returned " + + status + + " on " + + mActiveDevice + + ", please try again"); mVoiceRecognitionStarted = false; return false; } if (!isAudioModeIdle()) { - Log.w(TAG, "startVoiceRecognition: audio mode not idle, active device is " - + mActiveDevice); + Log.w( + TAG, + "startVoiceRecognition: audio mode not idle, active device is " + + mActiveDevice); return false; } // Audio should not be on when no audio mode is active if (isAudioOn()) { // Disconnect audio so that API user can try later int status = disconnectAudio(); - Log.w(TAG, "startVoiceRecognition: audio is still active, please wait for audio to" - + " be disconnected, disconnectAudio() returned " + status - + ", active device is " + mActiveDevice); + Log.w( + TAG, + "startVoiceRecognition: audio is still active, please wait for audio to" + + " be disconnected, disconnectAudio() returned " + + status + + ", active device is " + + mActiveDevice); return false; } if (device == null) { @@ -1053,10 +1108,13 @@ public class HeadsetService extends ProfileService { if (mVoiceRecognitionTimeoutEvent != null) { if (!mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice.equals(device)) { // TODO(b/79660380): Workaround when target device != requesting device - Log.w(TAG, "startVoiceRecognition: device " + device - + " is not the same as requesting device " - + mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice - + ", fall back to requesting device"); + Log.w( + TAG, + "startVoiceRecognition: device " + + device + + " is not the same as requesting device " + + mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice + + ", fall back to requesting device"); device = mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice; } mStateMachinesThreadHandler.removeCallbacks(mVoiceRecognitionTimeoutEvent); @@ -1088,8 +1146,8 @@ public class HeadsetService extends ProfileService { } mVoiceRecognitionStarted = true; if (pendingRequestByHeadset) { - stateMachine.sendMessage(HeadsetStateMachine.VOICE_RECOGNITION_RESULT, - 1 /* success */, 0, device); + stateMachine.sendMessage( + HeadsetStateMachine.VOICE_RECOGNITION_RESULT, 1 /* success */, 0, device); } else { stateMachine.sendMessage(HeadsetStateMachine.VOICE_RECOGNITION_START, device); } @@ -1129,8 +1187,13 @@ public class HeadsetService extends ProfileService { Log.i(TAG, "stopVoiceRecognition: device=" + device + ", " + Utils.getUidPidString()); synchronized (mStateMachines) { if (!Objects.equals(mActiveDevice, device)) { - Log.w(TAG, "startVoiceRecognition: requested device " + device - + " is not active, use active device " + mActiveDevice + " instead"); + Log.w( + TAG, + "startVoiceRecognition: requested device " + + device + + " is not active, use active device " + + mActiveDevice + + " instead"); device = mActiveDevice; } final HeadsetStateMachine stateMachine = mStateMachines.get(device); @@ -1254,8 +1317,7 @@ public class HeadsetService extends ProfileService { synchronized (mStateMachines) { final HeadsetStateMachine stateMachine = mStateMachines.get(device); if (stateMachine == null) { - Log.w(TAG, "setSilenceMode: device " + device - + " was never connected/connecting"); + Log.w(TAG, "setSilenceMode: device " + device + " was never connected/connecting"); return false; } stateMachine.setSilenceDevice(silence); @@ -1274,17 +1336,14 @@ public class HeadsetService extends ProfileService { synchronized (mStateMachines) { final HeadsetStateMachine stateMachine = mStateMachines.get(device); if (stateMachine == null) { - Log.e(TAG, "getHfpCallAudioPolicy(), " + device - + " does not have a state machine"); + Log.e(TAG, "getHfpCallAudioPolicy(), " + device + " does not have a state machine"); return null; } return stateMachine.getHfpCallAudioPolicy(); } } - /** - * Remove the active device - */ + /** Remove the active device */ private void removeActiveDevice() { synchronized (mStateMachines) { // As per b/202602952, if we remove the active device due to a disconnection, @@ -1292,7 +1351,8 @@ public class HeadsetService extends ProfileService { // Calling this before any other active related calls has the same effect as // a classic active device switch. BluetoothDevice fallbackDevice = getFallbackDevice(); - if (fallbackDevice != null && mActiveDevice != null + if (fallbackDevice != null + && mActiveDevice != null && getConnectionState(mActiveDevice) != BluetoothProfile.STATE_CONNECTED) { setActiveDevice(fallbackDevice); return; @@ -1300,21 +1360,29 @@ public class HeadsetService extends ProfileService { // Clear the active device if (mVoiceRecognitionStarted) { if (!stopVoiceRecognition(mActiveDevice)) { - Log.w(TAG, "removeActiveDevice: fail to stopVoiceRecognition from " - + mActiveDevice); + Log.w( + TAG, + "removeActiveDevice: fail to stopVoiceRecognition from " + + mActiveDevice); } } if (mVirtualCallStarted) { if (!stopScoUsingVirtualVoiceCall()) { - Log.w(TAG, "removeActiveDevice: fail to stopScoUsingVirtualVoiceCall from " - + mActiveDevice); + Log.w( + TAG, + "removeActiveDevice: fail to stopScoUsingVirtualVoiceCall from " + + mActiveDevice); } } if (getAudioState(mActiveDevice) != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { int disconnectStatus = disconnectAudio(mActiveDevice); if (disconnectStatus != BluetoothStatusCodes.SUCCESS) { - Log.w(TAG, "removeActiveDevice: disconnectAudio failed on " + mActiveDevice - + " with status code " + disconnectStatus); + Log.w( + TAG, + "removeActiveDevice: disconnectAudio failed on " + + mActiveDevice + + " with status code " + + disconnectStatus); } } mActiveDevice = null; @@ -1342,8 +1410,11 @@ public class HeadsetService extends ProfileService { return true; } if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) { - Log.e(TAG, "setActiveDevice: Cannot set " + device - + " as active, device is not connected"); + Log.e( + TAG, + "setActiveDevice: Cannot set " + + device + + " as active, device is not connected"); return false; } if (!mNativeInterface.setActiveDevice(device)) { @@ -1370,8 +1441,12 @@ public class HeadsetService extends ProfileService { if (getAudioState(previousActiveDevice) != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { int disconnectStatus = disconnectAudio(previousActiveDevice); if (disconnectStatus != BluetoothStatusCodes.SUCCESS) { - Log.e(TAG, "setActiveDevice: fail to disconnectAudio from " - + previousActiveDevice + " with status code " + disconnectStatus); + Log.e( + TAG, + "setActiveDevice: fail to disconnectAudio from " + + previousActiveDevice + + " with status code " + + disconnectStatus); if (previousActiveDevice == null) { removeActiveDevice(); } else { @@ -1416,8 +1491,12 @@ public class HeadsetService extends ProfileService { } int connectStatus = connectAudio(mActiveDevice); if (connectStatus != BluetoothStatusCodes.SUCCESS) { - Log.e(TAG, "setActiveDevice: fail to connectAudio to " + mActiveDevice - + " with status code " + connectStatus); + Log.e( + TAG, + "setActiveDevice: fail to connectAudio to " + + mActiveDevice + + " with status code " + + connectStatus); if (previousActiveDevice == null) { removeActiveDevice(); } else { @@ -1486,8 +1565,10 @@ public class HeadsetService extends ProfileService { return BluetoothStatusCodes.SUCCESS; } if (isAudioOn()) { - Log.w(TAG, "connectAudio: audio is not idle, current audio devices are " - + Arrays.toString(getNonIdleAudioDevices().toArray())); + Log.w( + TAG, + "connectAudio: audio is not idle, current audio devices are " + + Arrays.toString(getNonIdleAudioDevices().toArray())); return BluetoothStatusCodes.ERROR_AUDIO_DEVICE_ALREADY_CONNECTED; } stateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, device); @@ -1515,8 +1596,12 @@ public class HeadsetService extends ProfileService { if (disconnectResult == BluetoothStatusCodes.SUCCESS) { return disconnectResult; } else { - Log.e(TAG, "disconnectAudio() from " + device + " failed with status code " - + disconnectResult); + Log.e( + TAG, + "disconnectAudio() from " + + device + + " failed with status code " + + disconnectResult); } } } @@ -1555,24 +1640,35 @@ public class HeadsetService extends ProfileService { // TODO(b/79660380): Workaround in case voice recognition was not terminated properly if (mVoiceRecognitionStarted) { boolean status = stopVoiceRecognition(mActiveDevice); - Log.w(TAG, "startScoUsingVirtualVoiceCall: voice recognition is still active, " - + "just called stopVoiceRecognition, returned " + status + " on " - + mActiveDevice + ", please try again"); + Log.w( + TAG, + "startScoUsingVirtualVoiceCall: voice recognition is still active, " + + "just called stopVoiceRecognition, returned " + + status + + " on " + + mActiveDevice + + ", please try again"); mVoiceRecognitionStarted = false; return false; } if (!isAudioModeIdle()) { - Log.w(TAG, "startScoUsingVirtualVoiceCall: audio mode not idle, active device is " - + mActiveDevice); + Log.w( + TAG, + "startScoUsingVirtualVoiceCall: audio mode not idle, active device is " + + mActiveDevice); return false; } // Audio should not be on when no audio mode is active if (isAudioOn()) { // Disconnect audio so that API user can try later int status = disconnectAudio(); - Log.w(TAG, "startScoUsingVirtualVoiceCall: audio is still active, please wait for " - + "audio to be disconnected, disconnectAudio() returned " + status - + ", active device is " + mActiveDevice); + Log.w( + TAG, + "startScoUsingVirtualVoiceCall: audio is still active, please wait for " + + "audio to be disconnected, disconnectAudio() returned " + + status + + ", active device is " + + mActiveDevice); return false; } if (mActiveDevice == null) { @@ -1620,9 +1716,14 @@ public class HeadsetService extends ProfileService { public void run() { synchronized (mStateMachines) { mDialingOutTimeoutEvent = null; - doForStateMachine(mDialingOutDevice, stateMachine -> stateMachine.sendMessage( - HeadsetStateMachine.DIALING_OUT_RESULT, 0 /* fail */, 0, - mDialingOutDevice)); + doForStateMachine( + mDialingOutDevice, + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine.DIALING_OUT_RESULT, + 0 /* fail */, + 0, + mDialingOutDevice)); } } @@ -1658,8 +1759,10 @@ public class HeadsetService extends ProfileService { Log.e(TAG, "dialOutgoingCall failed to set active device to " + fromDevice); return false; } - Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, - Uri.fromParts(PhoneAccount.SCHEME_TEL, dialNumber, null)); + Intent intent = + new Intent( + Intent.ACTION_CALL_PRIVILEGED, + Uri.fromParts(PhoneAccount.SCHEME_TEL, dialNumber, null)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(fromDevice); @@ -1695,9 +1798,14 @@ public class HeadsetService extends ProfileService { mSystemInterface.getVoiceRecognitionWakeLock().release(); } mVoiceRecognitionTimeoutEvent = null; - doForStateMachine(mVoiceRecognitionDevice, stateMachine -> stateMachine.sendMessage( - HeadsetStateMachine.VOICE_RECOGNITION_RESULT, 0 /* fail */, 0, - mVoiceRecognitionDevice)); + doForStateMachine( + mVoiceRecognitionDevice, + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine.VOICE_RECOGNITION_RESULT, + 0 /* fail */, + 0, + mVoiceRecognitionDevice)); } } @@ -1714,9 +1822,14 @@ public class HeadsetService extends ProfileService { // TODO(b/79660380): Workaround in case voice recognition was not terminated properly if (mVoiceRecognitionStarted) { boolean status = stopVoiceRecognition(mActiveDevice); - Log.w(TAG, "startVoiceRecognitionByHeadset: voice recognition is still active, " - + "just called stopVoiceRecognition, returned " + status + " on " - + mActiveDevice + ", please try again"); + Log.w( + TAG, + "startVoiceRecognitionByHeadset: voice recognition is still active, " + + "just called stopVoiceRecognition, returned " + + status + + " on " + + mActiveDevice + + ", please try again"); mVoiceRecognitionStarted = false; return false; } @@ -1725,28 +1838,41 @@ public class HeadsetService extends ProfileService { return false; } if (!isAudioModeIdle()) { - Log.w(TAG, "startVoiceRecognitionByHeadset: audio mode not idle, active device is " - + mActiveDevice); + Log.w( + TAG, + "startVoiceRecognitionByHeadset: audio mode not idle, active device is " + + mActiveDevice); return false; } // Audio should not be on when no audio mode is active if (isAudioOn()) { // Disconnect audio so that user can try later int status = disconnectAudio(); - Log.w(TAG, "startVoiceRecognitionByHeadset: audio is still active, please wait for" - + " audio to be disconnected, disconnectAudio() returned " + status - + ", active device is " + mActiveDevice); + Log.w( + TAG, + "startVoiceRecognitionByHeadset: audio is still active, please wait for" + + " audio to be disconnected, disconnectAudio() returned " + + status + + ", active device is " + + mActiveDevice); return false; } // Do not start new request until the current one is finished or timeout if (mVoiceRecognitionTimeoutEvent != null) { - Log.w(TAG, "startVoiceRecognitionByHeadset: failed request from " + fromDevice - + ", already pending by " + mVoiceRecognitionTimeoutEvent); + Log.w( + TAG, + "startVoiceRecognitionByHeadset: failed request from " + + fromDevice + + ", already pending by " + + mVoiceRecognitionTimeoutEvent); return false; } if (!setActiveDevice(fromDevice)) { - Log.w(TAG, "startVoiceRecognitionByHeadset: failed to set " + fromDevice - + " as active"); + Log.w( + TAG, + "startVoiceRecognitionByHeadset: failed to set " + + fromDevice + + " as active"); return false; } if (!mSystemInterface.activateVoiceRecognition()) { @@ -1776,13 +1902,19 @@ public class HeadsetService extends ProfileService { synchronized (mStateMachines) { Log.i(TAG, "stopVoiceRecognitionByHeadset: from " + fromDevice); if (!Objects.equals(fromDevice, mActiveDevice)) { - Log.w(TAG, "stopVoiceRecognitionByHeadset: " + fromDevice - + " is not active, active device is " + mActiveDevice); + Log.w( + TAG, + "stopVoiceRecognitionByHeadset: " + + fromDevice + + " is not active, active device is " + + mActiveDevice); return false; } if (!mVoiceRecognitionStarted && mVoiceRecognitionTimeoutEvent == null) { - Log.w(TAG, "stopVoiceRecognitionByHeadset: voice recognition not started, device=" - + fromDevice); + Log.w( + TAG, + "stopVoiceRecognitionByHeadset: voice recognition not started, device=" + + fromDevice); return false; } if (mVoiceRecognitionTimeoutEvent != null) { @@ -1796,8 +1928,12 @@ public class HeadsetService extends ProfileService { if (mVoiceRecognitionStarted) { int disconnectStatus = disconnectAudio(); if (disconnectStatus != BluetoothStatusCodes.SUCCESS) { - Log.w(TAG, "stopVoiceRecognitionByHeadset: failed to disconnect audio from " - + fromDevice + " with status code " + disconnectStatus); + Log.w( + TAG, + "stopVoiceRecognitionByHeadset: failed to disconnect audio from " + + fromDevice + + " with status code " + + disconnectStatus); } mVoiceRecognitionStarted = false; } @@ -1839,10 +1975,14 @@ public class HeadsetService extends ProfileService { // Send result to state machine when dialing starts if (callState == HeadsetHalConstants.CALL_STATE_DIALING) { mStateMachinesThreadHandler.removeCallbacks(mDialingOutTimeoutEvent); - doForStateMachine(mDialingOutTimeoutEvent.mDialingOutDevice, - stateMachine -> stateMachine.sendMessage( - HeadsetStateMachine.DIALING_OUT_RESULT, 1 /* success */, 0, - mDialingOutTimeoutEvent.mDialingOutDevice)); + doForStateMachine( + mDialingOutTimeoutEvent.mDialingOutDevice, + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine.DIALING_OUT_RESULT, + 1 /* success */, + 0, + mDialingOutTimeoutEvent.mDialingOutDevice)); } else if (callState == HeadsetHalConstants.CALL_STATE_ACTIVE || callState == HeadsetHalConstants.CALL_STATE_IDLE) { // Clear the timeout event when the call is connected or disconnected @@ -1871,8 +2011,11 @@ public class HeadsetService extends ProfileService { } }); doForEachConnectedStateMachine( - stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED, - new HeadsetCallState(numActive, numHeld, callState, number, type, name))); + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine.CALL_STATE_CHANGED, + new HeadsetCallState( + numActive, numHeld, callState, number, type, name))); if (Utils.isScoManagedByAudioEnabled()) { if (mActiveDevice == null) { Log.i(TAG, "HeadsetService's active device is null"); @@ -1884,8 +2027,9 @@ public class HeadsetService extends ProfileService { try { task.get(); } catch (Exception e) { - Log.e(TAG, - "Exception when waiting for CALL_STATE_CHANGED message" + e.toString()); + Log.e( + TAG, + "Exception when waiting for CALL_STATE_CHANGED message" + e.toString()); } } } @@ -1908,8 +2052,9 @@ public class HeadsetService extends ProfileService { Log.d(TAG, "phoneStateChanged: CALL_STATE_IDLE, mActiveDevice is Null"); } else { BluetoothSinkAudioPolicy currentPolicy = stateMachine.getHfpCallAudioPolicy(); - if (currentPolicy != null && currentPolicy.getActiveDevicePolicyAfterConnection() - == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { + if (currentPolicy != null + && currentPolicy.getActiveDevicePolicyAfterConnection() + == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { /** * If the active device was set because of the pick up audio policy and the * connecting policy is NOT_ALLOWED, then after the call is terminated, we must @@ -1936,26 +2081,31 @@ public class HeadsetService extends ProfileService { } @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - void clccResponse(int index, int direction, int status, int mode, boolean mpty, - String number, int type) { + void clccResponse( + int index, int direction, int status, int mode, boolean mpty, String number, int type) { enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "Need MODIFY_PHONE_STATE permission"); mPendingClccResponses.add( - stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.SEND_CLCC_RESPONSE, - new HeadsetClccResponse(index, direction, status, mode, mpty, number, - type))); + stateMachine -> + stateMachine.sendMessage( + HeadsetStateMachine.SEND_CLCC_RESPONSE, + new HeadsetClccResponse( + index, direction, status, mode, mpty, number, type))); if (index == CLCC_END_MARK_INDEX) { doForEachConnectedStateMachine(mPendingClccResponses); mPendingClccResponses.clear(); } } - private boolean sendVendorSpecificResultCode(BluetoothDevice device, String command, - String arg) { + private boolean sendVendorSpecificResultCode( + BluetoothDevice device, String command, String arg) { synchronized (mStateMachines) { final HeadsetStateMachine stateMachine = mStateMachines.get(device); if (stateMachine == null) { - Log.w(TAG, "sendVendorSpecificResultCode: device " + device - + " was never connected/connecting"); + Log.w( + TAG, + "sendVendorSpecificResultCode: device " + + device + + " was never connected/connecting"); return false; } int connectionState = stateMachine.getConnectionState(); @@ -1967,7 +2117,8 @@ public class HeadsetService extends ProfileService { Log.w(TAG, "Disallowed unsolicited result code command: " + command); return false; } - stateMachine.sendMessage(HeadsetStateMachine.SEND_VENDOR_SPECIFIC_RESULT_CODE, + stateMachine.sendMessage( + HeadsetStateMachine.SEND_VENDOR_SPECIFIC_RESULT_CODE, new HeadsetVendorSpecificResultCode(device, command, arg)); } return true; @@ -1979,23 +2130,26 @@ public class HeadsetService extends ProfileService { * @return True if inband ringing is enabled. */ public boolean isInbandRingingEnabled() { - boolean isInbandRingingSupported = getResources().getBoolean( - com.android.bluetooth.R.bool.config_bluetooth_hfp_inband_ringing_support); + boolean isInbandRingingSupported = + getResources() + .getBoolean( + com.android.bluetooth.R.bool + .config_bluetooth_hfp_inband_ringing_support); boolean inbandRingtoneAllowedByPolicy = true; List audioConnectableDevices = getConnectedDevices(); if (audioConnectableDevices.size() == 1) { BluetoothDevice connectedDevice = audioConnectableDevices.get(0); - BluetoothSinkAudioPolicy callAudioPolicy = - getHfpCallAudioPolicy(connectedDevice); - if (callAudioPolicy != null && callAudioPolicy.getInBandRingtonePolicy() - == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { + BluetoothSinkAudioPolicy callAudioPolicy = getHfpCallAudioPolicy(connectedDevice); + if (callAudioPolicy != null + && callAudioPolicy.getInBandRingtonePolicy() + == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { inbandRingtoneAllowedByPolicy = false; } } - return isInbandRingingSupported && !SystemProperties.getBoolean( - DISABLE_INBAND_RINGING_PROPERTY, false) + return isInbandRingingSupported + && !SystemProperties.getBoolean(DISABLE_INBAND_RINGING_PROPERTY, false) && !mInbandRingingRuntimeDisable && inbandRingtoneAllowedByPolicy && !isHeadsetClientConnected(); @@ -2019,8 +2173,8 @@ public class HeadsetService extends ProfileService { */ @VisibleForTesting @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onConnectionStateChangedFromStateMachine(BluetoothDevice device, int fromState, - int toState) { + public void onConnectionStateChangedFromStateMachine( + BluetoothDevice device, int fromState, int toState) { if (fromState != BluetoothProfile.STATE_CONNECTED && toState == BluetoothProfile.STATE_CONNECTED) { updateInbandRinging(device, true); @@ -2036,8 +2190,8 @@ public class HeadsetService extends ProfileService { mAdapterService .getActiveDeviceManager() - .profileConnectionStateChanged(BluetoothProfile.HEADSET, device, fromState, - toState); + .profileConnectionStateChanged( + BluetoothProfile.HEADSET, device, fromState, toState); mAdapterService .getSilenceDeviceManager() .hfpConnectionStateChanged(device, fromState, toState); @@ -2052,9 +2206,7 @@ public class HeadsetService extends ProfileService { device, BluetoothProfile.HEADSET, toState, fromState); } - /** - * Called from {@link HeadsetClientStateMachine} to update inband ringing status. - */ + /** Called from {@link HeadsetClientStateMachine} to update inband ringing status. */ public void updateInbandRinging(BluetoothDevice device, boolean connected) { synchronized (mStateMachines) { List audioConnectableDevices = getConnectedDevices(); @@ -2071,14 +2223,21 @@ public class HeadsetService extends ProfileService { final boolean updateAll = inbandRingingRuntimeDisable != mInbandRingingRuntimeDisable; - Log.i(TAG, "updateInbandRinging():" - + " Device=" + device - + " enabled=" + enabled - + " connected=" + connected - + " Update all=" + updateAll); - - StateMachineTask sendBsirTask = stateMachine -> stateMachine - .sendMessage(HeadsetStateMachine.SEND_BSIR, enabled); + Log.i( + TAG, + "updateInbandRinging():" + + " Device=" + + device + + " enabled=" + + enabled + + " connected=" + + connected + + " Update all=" + + updateAll); + + StateMachineTask sendBsirTask = + stateMachine -> + stateMachine.sendMessage(HeadsetStateMachine.SEND_BSIR, enabled); if (updateAll) { doForEachConnectedStateMachine(sendBsirTask); @@ -2097,9 +2256,14 @@ public class HeadsetService extends ProfileService { private boolean isAudioModeIdle() { synchronized (mStateMachines) { if (mVoiceRecognitionStarted || mVirtualCallStarted || !mSystemInterface.isCallIdle()) { - Log.i(TAG, "isAudioModeIdle: not idle, mVoiceRecognitionStarted=" - + mVoiceRecognitionStarted + ", mVirtualCallStarted=" + mVirtualCallStarted - + ", isCallIdle=" + mSystemInterface.isCallIdle()); + Log.i( + TAG, + "isAudioModeIdle: not idle, mVoiceRecognitionStarted=" + + mVoiceRecognitionStarted + + ", mVirtualCallStarted=" + + mVirtualCallStarted + + ", isCallIdle=" + + mSystemInterface.isCallIdle()); return false; } return true; @@ -2127,16 +2291,15 @@ public class HeadsetService extends ProfileService { } private boolean shouldCallAudioBeActive() { - return mSystemInterface.isInCall() || (mSystemInterface.isRinging() - && isInbandRingingEnabled()); + return mSystemInterface.isInCall() + || (mSystemInterface.isRinging() && isInbandRingingEnabled()); } /** * Only persist audio during active device switch when call audio is supposed to be active and * virtual call has not been started. Virtual call is ignored because AudioService and - * applications should reconnect SCO during active device switch and forcing SCO connection - * here will make AudioService think SCO is started externally instead of by one of its SCO - * clients. + * applications should reconnect SCO during active device switch and forcing SCO connection here + * will make AudioService think SCO is started externally instead of by one of its SCO clients. * * @return true if call audio should be active and no virtual call is going on */ @@ -2154,32 +2317,44 @@ public class HeadsetService extends ProfileService { */ @VisibleForTesting @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onAudioStateChangedFromStateMachine(BluetoothDevice device, int fromState, - int toState) { + public void onAudioStateChangedFromStateMachine( + BluetoothDevice device, int fromState, int toState) { synchronized (mStateMachines) { if (toState == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { if (fromState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { - if (mActiveDevice != null && !mActiveDevice.equals(device) + if (mActiveDevice != null + && !mActiveDevice.equals(device) && shouldPersistAudio()) { int connectStatus = connectAudio(mActiveDevice); if (connectStatus != BluetoothStatusCodes.SUCCESS) { - Log.w(TAG, "onAudioStateChangedFromStateMachine, failed to connect" - + " audio to new " + "active device " + mActiveDevice - + ", after " + device + " is disconnected from SCO due to" - + " status code " + connectStatus); + Log.w( + TAG, + "onAudioStateChangedFromStateMachine, failed to connect" + + " audio to new " + + "active device " + + mActiveDevice + + ", after " + + device + + " is disconnected from SCO due to" + + " status code " + + connectStatus); } } } if (mVoiceRecognitionStarted) { if (!stopVoiceRecognitionByHeadset(device)) { - Log.w(TAG, "onAudioStateChangedFromStateMachine: failed to stop voice " - + "recognition"); + Log.w( + TAG, + "onAudioStateChangedFromStateMachine: failed to stop voice " + + "recognition"); } } if (mVirtualCallStarted) { if (!stopScoUsingVirtualVoiceCall()) { - Log.w(TAG, "onAudioStateChangedFromStateMachine: failed to stop virtual " - + "voice call"); + Log.w( + TAG, + "onAudioStateChangedFromStateMachine: failed to stop virtual " + + "voice call"); } } // Resumes LE audio previous active device if HFP handover happened before. @@ -2232,8 +2407,9 @@ public class HeadsetService extends ProfileService { Intent intent = new Intent(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcastAsUser( intent, UserHandle.ALL, @@ -2267,8 +2443,10 @@ public class HeadsetService extends ProfileService { if (!isOutgoingRequest) { A2dpService a2dpService = A2dpService.getA2dpService(); if (a2dpService != null && a2dpService.okToConnect(device, true)) { - Log.d(TAG, "okToAcceptConnection: return false," - + " Fallback connection to allowed A2DP profile"); + Log.d( + TAG, + "okToAcceptConnection: return false," + + " Fallback connection to allowed A2DP profile"); a2dpService.connect(device); return false; } @@ -2279,17 +2457,20 @@ public class HeadsetService extends ProfileService { List connectingConnectedDevices = getDevicesMatchingConnectionStates(CONNECTING_CONNECTED_STATES); if (connectingConnectedDevices.size() >= mMaxHeadsetConnections) { - Log.w(TAG, "Maximum number of connections " + mMaxHeadsetConnections - + " was reached, rejecting connection from " + device); + Log.w( + TAG, + "Maximum number of connections " + + mMaxHeadsetConnections + + " was reached, rejecting connection from " + + device); return false; } return true; } /** - * Checks if SCO should be connected at current system state. Returns - * {@link BluetoothStatusCodes#SUCCESS} if SCO is allowed to be connected or an error code on - * failure. + * Checks if SCO should be connected at current system state. Returns {@link + * BluetoothStatusCodes#SUCCESS} if SCO is allowed to be connected or an error code on failure. * * @param device device for SCO to be connected * @return whether SCO can be connected @@ -2297,8 +2478,12 @@ public class HeadsetService extends ProfileService { public int isScoAcceptable(BluetoothDevice device) { synchronized (mStateMachines) { if (device == null || !device.equals(mActiveDevice)) { - Log.w(TAG, "isScoAcceptable: rejected SCO since " + device - + " is not the current active device " + mActiveDevice); + Log.w( + TAG, + "isScoAcceptable: rejected SCO since " + + device + + " is not the current active device " + + mActiveDevice); return BluetoothStatusCodes.ERROR_NOT_ACTIVE_DEVICE; } if (SystemProperties.getBoolean(REJECT_SCO_IF_HFPC_CONNECTED_PROPERTY, false) @@ -2319,10 +2504,18 @@ public class HeadsetService extends ProfileService { if (shouldCallAudioBeActive()) { return BluetoothStatusCodes.SUCCESS; } - Log.w(TAG, "isScoAcceptable: rejected SCO, inCall=" + mSystemInterface.isInCall() - + ", voiceRecognition=" + mVoiceRecognitionStarted + ", ringing=" - + mSystemInterface.isRinging() + ", inbandRinging=" + isInbandRingingEnabled() - + ", isVirtualCallStarted=" + mVirtualCallStarted); + Log.w( + TAG, + "isScoAcceptable: rejected SCO, inCall=" + + mSystemInterface.isInCall() + + ", voiceRecognition=" + + mVoiceRecognitionStarted + + ", ringing=" + + mSystemInterface.isRinging() + + ", inbandRinging=" + + isInbandRingingEnabled() + + ", isVirtualCallStarted=" + + mVirtualCallStarted); return BluetoothStatusCodes.ERROR_CALL_ACTIVE; } } @@ -2345,15 +2538,12 @@ public class HeadsetService extends ProfileService { } } - - /** - * Retrieves the most recently connected device in the A2DP connected devices list. - */ + /** Retrieves the most recently connected device in the A2DP connected devices list. */ public BluetoothDevice getFallbackDevice() { DatabaseManager dbManager = mAdapterService.getDatabase(); - return dbManager != null ? dbManager - .getMostRecentlyConnectedDevicesInList(getFallbackCandidates(dbManager)) - : null; + return dbManager != null + ? dbManager.getMostRecentlyConnectedDevicesInList(getFallbackCandidates(dbManager)) + : null; } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -2361,14 +2551,14 @@ public class HeadsetService extends ProfileService { List fallbackCandidates = getConnectedDevices(); List uninterestedCandidates = new ArrayList<>(); for (BluetoothDevice device : fallbackCandidates) { - byte[] deviceType = dbManager.getCustomMeta(device, - BluetoothDevice.METADATA_DEVICE_TYPE); + byte[] deviceType = + dbManager.getCustomMeta(device, BluetoothDevice.METADATA_DEVICE_TYPE); BluetoothClass deviceClass = device.getBluetoothClass(); if ((deviceClass != null - && deviceClass.getMajorDeviceClass() - == BluetoothClass.Device.WEARABLE_WRIST_WATCH) + && deviceClass.getMajorDeviceClass() + == BluetoothClass.Device.WEARABLE_WRIST_WATCH) || (deviceType != null - && BluetoothDevice.DEVICE_TYPE_WATCH.equals(new String(deviceType)))) { + && BluetoothDevice.DEVICE_TYPE_WATCH.equals(new String(deviceType)))) { uninterestedCandidates.add(device); } } @@ -2381,23 +2571,27 @@ public class HeadsetService extends ProfileService { @Override public void dump(StringBuilder sb) { boolean isScoOn = mSystemInterface.getAudioManager().isBluetoothScoOn(); - boolean isInbandRingingSupported = getResources().getBoolean( - com.android.bluetooth.R.bool.config_bluetooth_hfp_inband_ringing_support); + boolean isInbandRingingSupported = + getResources() + .getBoolean( + com.android.bluetooth.R.bool + .config_bluetooth_hfp_inband_ringing_support); synchronized (mStateMachines) { super.dump(sb); ProfileService.println(sb, "mMaxHeadsetConnections: " + mMaxHeadsetConnections); - ProfileService.println(sb, "DefaultMaxHeadsetConnections: " - + mAdapterService.getMaxConnectedAudioDevices()); + ProfileService.println( + sb, + "DefaultMaxHeadsetConnections: " + + mAdapterService.getMaxConnectedAudioDevices()); ProfileService.println(sb, "mActiveDevice: " + mActiveDevice); ProfileService.println(sb, "isInbandRingingEnabled: " + isInbandRingingEnabled()); - ProfileService.println(sb, - "isInbandRingingSupported: " + isInbandRingingSupported); - ProfileService.println(sb, - "mInbandRingingRuntimeDisable: " + mInbandRingingRuntimeDisable); + ProfileService.println(sb, "isInbandRingingSupported: " + isInbandRingingSupported); + ProfileService.println( + sb, "mInbandRingingRuntimeDisable: " + mInbandRingingRuntimeDisable); ProfileService.println(sb, "mAudioRouteAllowed: " + mAudioRouteAllowed); ProfileService.println(sb, "mVoiceRecognitionStarted: " + mVoiceRecognitionStarted); - ProfileService.println(sb, - "mVoiceRecognitionTimeoutEvent: " + mVoiceRecognitionTimeoutEvent); + ProfileService.println( + sb, "mVoiceRecognitionTimeoutEvent: " + mVoiceRecognitionTimeoutEvent); ProfileService.println(sb, "mVirtualCallStarted: " + mVirtualCallStarted); ProfileService.println(sb, "mDialingOutTimeoutEvent: " + mDialingOutTimeoutEvent); ProfileService.println(sb, "mForceScoAudio: " + mForceScoAudio); @@ -2405,8 +2599,8 @@ public class HeadsetService extends ProfileService { ProfileService.println(sb, "Telecom.isInCall(): " + mSystemInterface.isInCall()); ProfileService.println(sb, "Telecom.isRinging(): " + mSystemInterface.isRinging()); for (HeadsetStateMachine stateMachine : mStateMachines.values()) { - ProfileService.println(sb, - "==== StateMachine for " + stateMachine.getDevice() + " ===="); + ProfileService.println( + sb, "==== StateMachine for " + stateMachine.getDevice() + " ===="); stateMachine.dump(sb); } } diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java index f33cb2dbeaf..94c1e7f1cd7 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java @@ -20,9 +20,7 @@ import android.bluetooth.BluetoothDevice; import java.util.Objects; -/** - * Callback events from native layer - */ +/** Callback events from native layer */ public class HeadsetStackEvent extends HeadsetMessageObject { public static final int EVENT_TYPE_NONE = 0; public static final int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1; @@ -119,8 +117,13 @@ public class HeadsetStackEvent extends HeadsetMessageObject { * @param valueObject an object value in the event * @param device device of interest */ - public HeadsetStackEvent(int type, int valueInt, int valueInt2, String valueString, - HeadsetMessageObject valueObject, BluetoothDevice device) { + public HeadsetStackEvent( + int type, + int valueInt, + int valueInt2, + String valueString, + HeadsetMessageObject valueObject, + BluetoothDevice device) { this.type = type; this.valueInt = valueInt; this.valueInt2 = valueInt2; diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java index 7985cc0cc70..635164ee478 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java @@ -67,24 +67,10 @@ import java.util.Objects; import java.util.Scanner; /** - * A Bluetooth Handset StateMachine - * (Disconnected) - * | ^ - * CONNECT | | DISCONNECTED - * V | - * (Connecting) (Disconnecting) - * | ^ - * CONNECTED | | DISCONNECT - * V | - * (Connected) - * | ^ - * CONNECT_AUDIO | | AUDIO_DISCONNECTED - * V | - * (AudioConnecting) (AudioDiconnecting) - * | ^ - * AUDIO_CONNECTED | | DISCONNECT_AUDIO - * V | - * (AudioOn) + * A Bluetooth Handset StateMachine (Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting) + * (Disconnecting) | ^ CONNECTED | | DISCONNECT V | (Connected) | ^ CONNECT_AUDIO | | + * AUDIO_DISCONNECTED V | (AudioConnecting) (AudioDiconnecting) | ^ AUDIO_CONNECTED | | + * DISCONNECT_AUDIO V | (AudioOn) */ class HeadsetStateMachine extends StateMachine { private static final String TAG = HeadsetStateMachine.class.getSimpleName(); @@ -144,10 +130,8 @@ class HeadsetStateMachine extends StateMachine { private final DatabaseManager mDatabaseManager; // Runtime states - @VisibleForTesting - int mSpeakerVolume; - @VisibleForTesting - int mMicVolume; + @VisibleForTesting int mSpeakerVolume; + @VisibleForTesting int mMicVolume; private boolean mDeviceSilenced; private HeadsetAgIndicatorEnableState mAgIndicatorEnableState; // The timestamp when the device entered connecting/connected state @@ -158,8 +142,7 @@ class HeadsetStateMachine extends StateMachine { private boolean mHasSwbLc3Enabled = false; private boolean mHasSwbAptXEnabled = false; // AT Phone book keeps a group of states used by AT+CPBR commands - @VisibleForTesting - final AtPhonebook mPhonebook; + @VisibleForTesting final AtPhonebook mPhonebook; // HSP specific private boolean mNeedDialingOutReply; // Audio disconnect timeout retry count @@ -198,9 +181,13 @@ class HeadsetStateMachine extends StateMachine { BluetoothAssignedNumbers.GOOGLE); } - private HeadsetStateMachine(BluetoothDevice device, Looper looper, - HeadsetService headsetService, AdapterService adapterService, - HeadsetNativeInterface nativeInterface, HeadsetSystemInterface systemInterface) { + private HeadsetStateMachine( + BluetoothDevice device, + Looper looper, + HeadsetService headsetService, + AdapterService adapterService, + HeadsetNativeInterface nativeInterface, + HeadsetSystemInterface systemInterface) { super(TAG, requireNonNull(looper)); // Let the logging framework enforce the log level. TAG is set above in the parent @@ -240,12 +227,21 @@ class HeadsetStateMachine extends StateMachine { setInitialState(mDisconnected); } - static HeadsetStateMachine make(BluetoothDevice device, Looper looper, - HeadsetService headsetService, AdapterService adapterService, - HeadsetNativeInterface nativeInterface, HeadsetSystemInterface systemInterface) { + static HeadsetStateMachine make( + BluetoothDevice device, + Looper looper, + HeadsetService headsetService, + AdapterService adapterService, + HeadsetNativeInterface nativeInterface, + HeadsetSystemInterface systemInterface) { HeadsetStateMachine stateMachine = - new HeadsetStateMachine(device, looper, headsetService, adapterService, - nativeInterface, systemInterface); + new HeadsetStateMachine( + device, + looper, + headsetService, + adapterService, + nativeInterface, + systemInterface); stateMachine.start(); Log.i(TAG, "Created state machine " + stateMachine + " for " + device); return stateMachine; @@ -280,15 +276,15 @@ class HeadsetStateMachine extends StateMachine { ProfileService.println(sb, " mNeedDialingOutReply: " + mNeedDialingOutReply); ProfileService.println(sb, " mSpeakerVolume: " + mSpeakerVolume); ProfileService.println(sb, " mMicVolume: " + mMicVolume); - ProfileService.println(sb, - " mConnectingTimestampMs(uptimeMillis): " + mConnectingTimestampMs); + ProfileService.println( + sb, " mConnectingTimestampMs(uptimeMillis): " + mConnectingTimestampMs); ProfileService.println(sb, " mHsClientAudioPolicy: " + mHsClientAudioPolicy.toString()); ProfileService.println(sb, " StateMachine: " + this); // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); @@ -300,9 +296,7 @@ class HeadsetStateMachine extends StateMachine { scanner.close(); } - /** - * Base class for states used in this state machine to share common infrastructures - */ + /** Base class for states used in this state machine to share common infrastructures */ private abstract class HeadsetStateBase extends State { @Override public void enter() { @@ -333,16 +327,16 @@ class HeadsetStateMachine extends StateMachine { return; } // TODO: Add STATE_AUDIO_DISCONNECTING constant to get rid of the 2nd part of this logic - if (getAudioStateInt() != mPrevState.getAudioStateInt() || ( - mPrevState instanceof AudioDisconnecting && this instanceof AudioOn)) { + if (getAudioStateInt() != mPrevState.getAudioStateInt() + || (mPrevState instanceof AudioDisconnecting && this instanceof AudioOn)) { stateLogD("audio state changed: " + mDevice + ": " + mPrevState + " -> " + this); broadcastAudioState(mDevice, mPrevState.getAudioStateInt(), getAudioStateInt()); } if (getConnectionStateInt() != mPrevState.getConnectionStateInt()) { stateLogD( "connection state changed: " + mDevice + ": " + mPrevState + " -> " + this); - broadcastConnectionState(mDevice, mPrevState.getConnectionStateInt(), - getConnectionStateInt()); + broadcastConnectionState( + mDevice, mPrevState.getConnectionStateInt(), getConnectionStateInt()); } } @@ -366,10 +360,12 @@ class HeadsetStateMachine extends StateMachine { void broadcastAudioState(BluetoothDevice device, int fromState, int toState) { stateLogD("broadcastAudioState: " + device + ": " + fromState + "->" + toState); // TODO(b/278520111): add metrics for SWB - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_SCO_CONNECTION_STATE_CHANGED, + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_SCO_CONNECTION_STATE_CHANGED, mAdapterService.obfuscateAddress(device), getConnectionStateFromAudioState(toState), - mHasWbsEnabled ? BluetoothHfpProtoEnums.SCO_CODEC_MSBC + mHasWbsEnabled + ? BluetoothHfpProtoEnums.SCO_CODEC_MSBC : BluetoothHfpProtoEnums.SCO_CODEC_CVSD, mAdapterService.getMetricId(device)); mHeadsetService.onAudioStateChangedFromStateMachine(device, fromState, toState); @@ -388,50 +384,69 @@ class HeadsetStateMachine extends StateMachine { * Verify if the current state transition is legal. This is supposed to be called from * enter() method and crash if the state transition is out of the specification * - * Note: - * This method uses state objects to verify transition because these objects should be final - * and any other instances are invalid + *

Note: This method uses state objects to verify transition because these objects should + * be final and any other instances are invalid */ void enforceValidConnectionStateTransition() { boolean result = false; if (this == mDisconnected) { - result = mPrevState == null || mPrevState == mConnecting - || mPrevState == mDisconnecting - // TODO: edges to be removed after native stack refactoring - // all transitions to disconnected state should go through a pending state - // also, states should not go directly from an active audio state to - // disconnected state - || mPrevState == mConnected || mPrevState == mAudioOn - || mPrevState == mAudioConnecting || mPrevState == mAudioDisconnecting; + result = + mPrevState == null + || mPrevState == mConnecting + || mPrevState == mDisconnecting + // TODO: edges to be removed after native stack refactoring + // all transitions to disconnected state should go through a pending + // state + // also, states should not go directly from an active audio state to + // disconnected state + || mPrevState == mConnected + || mPrevState == mAudioOn + || mPrevState == mAudioConnecting + || mPrevState == mAudioDisconnecting; } else if (this == mConnecting) { result = mPrevState == mDisconnected; } else if (this == mDisconnecting) { - result = mPrevState == mConnected - // TODO: edges to be removed after native stack refactoring - // all transitions to disconnecting state should go through connected state - || mPrevState == mAudioConnecting || mPrevState == mAudioOn - || mPrevState == mAudioDisconnecting; + result = + mPrevState == mConnected + // TODO: edges to be removed after native stack refactoring + // all transitions to disconnecting state should go through + // connected state + || mPrevState == mAudioConnecting + || mPrevState == mAudioOn + || mPrevState == mAudioDisconnecting; } else if (this == mConnected) { - result = mPrevState == mConnecting || mPrevState == mAudioDisconnecting - || mPrevState == mDisconnecting || mPrevState == mAudioConnecting - // TODO: edges to be removed after native stack refactoring - // all transitions to connected state should go through a pending state - || mPrevState == mAudioOn || mPrevState == mDisconnected; + result = + mPrevState == mConnecting + || mPrevState == mAudioDisconnecting + || mPrevState == mDisconnecting + || mPrevState == mAudioConnecting + // TODO: edges to be removed after native stack refactoring + // all transitions to connected state should go through a pending + // state + || mPrevState == mAudioOn + || mPrevState == mDisconnected; } else if (this == mAudioConnecting) { result = mPrevState == mConnected; } else if (this == mAudioDisconnecting) { result = mPrevState == mAudioOn; } else if (this == mAudioOn) { - result = mPrevState == mAudioConnecting || mPrevState == mAudioDisconnecting - // TODO: edges to be removed after native stack refactoring - // all transitions to audio connected state should go through a pending - // state - || mPrevState == mConnected; + result = + mPrevState == mAudioConnecting + || mPrevState == mAudioDisconnecting + // TODO: edges to be removed after native stack refactoring + // all transitions to audio connected state should go through a + // pending + // state + || mPrevState == mConnected; } if (!result) { throw new IllegalStateException( - "Invalid state transition from " + mPrevState + " to " + this - + " for device " + mDevice); + "Invalid state transition from " + + mPrevState + + " to " + + this + + " for device " + + mDevice); } } @@ -478,17 +493,18 @@ class HeadsetStateMachine extends StateMachine { * Get a state value from {@link BluetoothProfile} that represents the connection state of * this headset state * - * @return a value in {@link BluetoothProfile#STATE_DISCONNECTED}, - * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or - * {@link BluetoothProfile#STATE_DISCONNECTING} + * @return a value in {@link BluetoothProfile#STATE_DISCONNECTED}, {@link + * BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or + * {@link BluetoothProfile#STATE_DISCONNECTING} */ abstract int getConnectionStateInt(); /** * Get an audio state value from {@link BluetoothHeadset} - * @return a value in {@link BluetoothHeadset#STATE_AUDIO_DISCONNECTED}, - * {@link BluetoothHeadset#STATE_AUDIO_CONNECTING}, or - * {@link BluetoothHeadset#STATE_AUDIO_CONNECTED} + * + * @return a value in {@link BluetoothHeadset#STATE_AUDIO_DISCONNECTED}, {@link + * BluetoothHeadset#STATE_AUDIO_CONNECTING}, or {@link + * BluetoothHeadset#STATE_AUDIO_CONNECTED} */ abstract int getAudioStateInt(); @@ -603,8 +619,11 @@ class HeadsetStateMachine extends StateMachine { HeadsetStackEvent event = (HeadsetStackEvent) message.obj; stateLogD("STACK_EVENT: " + event); if (!mDevice.equals(event.device)) { - stateLogE("Event device does not match currentDevice[" + mDevice - + "], event: " + event); + stateLogE( + "Event device does not match currentDevice[" + + mDevice + + "], event: " + + event); break; } switch (event.type) { @@ -630,22 +649,26 @@ class HeadsetStateMachine extends StateMachine { case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED: stateLogW("ignore DISCONNECTED event"); break; - // Both events result in Connecting state as SLC establishment is still required + // Both events result in Connecting state as SLC establishment is still required case HeadsetHalConstants.CONNECTION_STATE_CONNECTED: case HeadsetHalConstants.CONNECTION_STATE_CONNECTING: if (mHeadsetService.okToAcceptConnection(mDevice, false)) { stateLogI("accept incoming connection"); transitionTo(mConnecting); } else { - stateLogI("rejected incoming HF, connectionPolicy=" - + mHeadsetService.getConnectionPolicy(mDevice) + " bondState=" - + mAdapterService.getBondState(mDevice)); + stateLogI( + "rejected incoming HF, connectionPolicy=" + + mHeadsetService.getConnectionPolicy(mDevice) + + " bondState=" + + mAdapterService.getBondState(mDevice)); // Reject the connection and stay in Disconnected state itself if (!mNativeInterface.disconnectHfp(mDevice)) { stateLogE("failed to disconnect"); } // Indicate rejection to other components. - broadcastConnectionState(mDevice, BluetoothProfile.STATE_DISCONNECTED, + broadcastConnectionState( + mDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED); BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED, @@ -718,17 +741,18 @@ class HeadsetStateMachine extends StateMachine { case DISCONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - // We timed out trying to connect, transition to Disconnected state - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogE("Unknown device timeout " + device); + case CONNECT_TIMEOUT: + { + // We timed out trying to connect, transition to Disconnected state + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogE("Unknown device timeout " + device); + break; + } + stateLogW("CONNECT_TIMEOUT"); + transitionTo(mDisconnected); break; } - stateLogW("CONNECT_TIMEOUT"); - transitionTo(mDisconnected); - break; - } case CALL_STATE_CHANGED: HeadsetCallState callState = (HeadsetCallState) message.obj; setAptxVoice(callState); @@ -740,8 +764,11 @@ class HeadsetStateMachine extends StateMachine { HeadsetStackEvent event = (HeadsetStackEvent) message.obj; stateLogD("STACK_EVENT: " + event); if (!mDevice.equals(event.device)) { - stateLogE("Event device does not match currentDevice[" + mDevice - + "], event: " + event); + stateLogE( + "Event device does not match currentDevice[" + + mDevice + + "], event: " + + event); break; } switch (event.type) { @@ -760,10 +787,13 @@ class HeadsetStateMachine extends StateMachine { case HeadsetStackEvent.EVENT_TYPE_BIND: processAtBind(event.valueString, event.device); break; - // Unexpected AT commands, we only handle them for comparability reasons + // Unexpected AT commands, we only handle them for comparability reasons case HeadsetStackEvent.EVENT_TYPE_VR_STATE_CHANGED: - stateLogW("Unexpected VR event, device=" + event.device + ", state=" - + event.valueInt); + stateLogW( + "Unexpected VR event, device=" + + event.device + + ", state=" + + event.valueInt); processVrEvent(event.valueInt); break; case HeadsetStackEvent.EVENT_TYPE_DIAL_CALL: @@ -771,8 +801,11 @@ class HeadsetStateMachine extends StateMachine { processDialCall(event.valueString); break; case HeadsetStackEvent.EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST: - stateLogW("Unexpected subscriber number event for" + event.device - + ", state=" + event.valueInt); + stateLogW( + "Unexpected subscriber number event for" + + event.device + + ", state=" + + event.valueInt); processSubscriberNumberRequest(event.device); break; case HeadsetStackEvent.EVENT_TYPE_AT_COPS: @@ -784,8 +817,11 @@ class HeadsetStateMachine extends StateMachine { processAtClcc(event.device); break; case HeadsetStackEvent.EVENT_TYPE_UNKNOWN_AT: - stateLogW("Unexpected unknown AT event for" + event.device + ", cmd=" - + event.valueString); + stateLogW( + "Unexpected unknown AT event for" + + event.device + + ", cmd=" + + event.valueString); processUnknownAt(event.valueString, event.device); break; case HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED: @@ -793,8 +829,13 @@ class HeadsetStateMachine extends StateMachine { processKeyPressed(event.device); break; case HeadsetStackEvent.EVENT_TYPE_BIEV: - stateLogW("Unexpected BIEV event for " + event.device + ", indId=" - + event.valueInt + ", indVal=" + event.valueInt2); + stateLogW( + "Unexpected BIEV event for " + + event.device + + ", indId=" + + event.valueInt + + ", indVal=" + + event.valueInt2); processAtBiev(event.valueInt, event.valueInt2, event.device); break; case HeadsetStackEvent.EVENT_TYPE_VOLUME_CHANGED: @@ -881,22 +922,26 @@ class HeadsetStateMachine extends StateMachine { case DISCONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogE("Unknown device timeout " + device); + case CONNECT_TIMEOUT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogE("Unknown device timeout " + device); + break; + } + stateLogE("timeout"); + transitionTo(mDisconnected); break; } - stateLogE("timeout"); - transitionTo(mDisconnected); - break; - } case STACK_EVENT: HeadsetStackEvent event = (HeadsetStackEvent) message.obj; stateLogD("STACK_EVENT: " + event); if (!mDevice.equals(event.device)) { - stateLogE("Event device does not match currentDevice[" + mDevice - + "], event: " + event); + stateLogE( + "Event device does not match currentDevice[" + + mDevice + + "], event: " + + event); break; } switch (event.type) { @@ -941,9 +986,7 @@ class HeadsetStateMachine extends StateMachine { } } - /** - * Base class for Connected, AudioConnecting, AudioOn, AudioDisconnecting states - */ + /** Base class for Connected, AudioConnecting, AudioOn, AudioDisconnecting states */ private abstract class ConnectedBase extends HeadsetStateBase { @Override int getConnectionStateInt() { @@ -967,32 +1010,38 @@ class HeadsetStateMachine extends StateMachine { case CONNECT_TIMEOUT: throw new IllegalStateException( "Illegal message in generic handler: " + message); - case VOICE_RECOGNITION_START: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("VOICE_RECOGNITION_START failed " + device - + " is not currentDevice"); - break; - } - if (!mNativeInterface.startVoiceRecognition(mDevice)) { - stateLogW("Failed to start voice recognition"); - break; - } - break; - } - case VOICE_RECOGNITION_STOP: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("VOICE_RECOGNITION_STOP failed " + device - + " is not currentDevice"); + case VOICE_RECOGNITION_START: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW( + "VOICE_RECOGNITION_START failed " + + device + + " is not currentDevice"); + break; + } + if (!mNativeInterface.startVoiceRecognition(mDevice)) { + stateLogW("Failed to start voice recognition"); + break; + } break; } - if (!mNativeInterface.stopVoiceRecognition(mDevice)) { - stateLogW("Failed to stop voice recognition"); + case VOICE_RECOGNITION_STOP: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW( + "VOICE_RECOGNITION_STOP failed " + + device + + " is not currentDevice"); + break; + } + if (!mNativeInterface.stopVoiceRecognition(mDevice)) { + stateLogW("Failed to stop voice recognition"); + break; + } break; } - break; - } case CALL_STATE_CHANGED: HeadsetCallState callState = (HeadsetCallState) message.obj; setAptxVoice(callState); @@ -1004,8 +1053,10 @@ class HeadsetStateMachine extends StateMachine { break; case DEVICE_STATE_CHANGED: if (mDeviceSilenced) { - stateLogW("DEVICE_STATE_CHANGED: " + mDevice - + " is silenced, skip notify state changed."); + stateLogW( + "DEVICE_STATE_CHANGED: " + + mDevice + + " is silenced, skip notify state changed."); break; } mNativeInterface.notifyDeviceStatus(mDevice, (HeadsetDeviceState) message.obj); @@ -1013,15 +1064,17 @@ class HeadsetStateMachine extends StateMachine { case SEND_CLCC_RESPONSE: processSendClccResponse((HeadsetClccResponse) message.obj); break; - case CLCC_RSP_TIMEOUT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("CLCC_RSP_TIMEOUT failed " + device + " is not currentDevice"); - break; + case CLCC_RSP_TIMEOUT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW( + "CLCC_RSP_TIMEOUT failed " + device + " is not currentDevice"); + break; + } + mNativeInterface.clccResponse(device, 0, 0, 0, 0, false, "", 0); } - mNativeInterface.clccResponse(device, 0, 0, 0, 0, false, "", 0); - } - break; + break; case SEND_VENDOR_SPECIFIC_RESULT_CODE: processSendVendorSpecificResultCode( (HeadsetVendorSpecificResultCode) message.obj); @@ -1029,32 +1082,45 @@ class HeadsetStateMachine extends StateMachine { case SEND_BSIR: mNativeInterface.sendBsir(mDevice, message.arg1 == 1); break; - case VOICE_RECOGNITION_RESULT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("VOICE_RECOGNITION_RESULT failed " + device - + " is not currentDevice"); - break; - } - mNativeInterface.atResponseCode(mDevice, - message.arg1 == 1 ? HeadsetHalConstants.AT_RESPONSE_OK - : HeadsetHalConstants.AT_RESPONSE_ERROR, 0); - break; - } - case DIALING_OUT_RESULT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("DIALING_OUT_RESULT failed " + device + " is not currentDevice"); + case VOICE_RECOGNITION_RESULT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW( + "VOICE_RECOGNITION_RESULT failed " + + device + + " is not currentDevice"); + break; + } + mNativeInterface.atResponseCode( + mDevice, + message.arg1 == 1 + ? HeadsetHalConstants.AT_RESPONSE_OK + : HeadsetHalConstants.AT_RESPONSE_ERROR, + 0); break; } - if (mNeedDialingOutReply) { - mNeedDialingOutReply = false; - mNativeInterface.atResponseCode(mDevice, - message.arg1 == 1 ? HeadsetHalConstants.AT_RESPONSE_OK - : HeadsetHalConstants.AT_RESPONSE_ERROR, 0); + case DIALING_OUT_RESULT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW( + "DIALING_OUT_RESULT failed " + + device + + " is not currentDevice"); + break; + } + if (mNeedDialingOutReply) { + mNeedDialingOutReply = false; + mNativeInterface.atResponseCode( + mDevice, + message.arg1 == 1 + ? HeadsetHalConstants.AT_RESPONSE_OK + : HeadsetHalConstants.AT_RESPONSE_ERROR, + 0); + } } - } - break; + break; case INTENT_CONNECTION_ACCESS_REPLY: handleAccessPermissionResult((Intent) message.obj); break; @@ -1062,8 +1128,11 @@ class HeadsetStateMachine extends StateMachine { HeadsetStackEvent event = (HeadsetStackEvent) message.obj; stateLogD("STACK_EVENT: " + event); if (!mDevice.equals(event.device)) { - stateLogE("Event device does not match currentDevice[" + mDevice - + "], event: " + event); + stateLogE( + "Event device does not match currentDevice[" + + mDevice + + "], event: " + + event); break; } switch (event.type) { @@ -1208,28 +1277,33 @@ class HeadsetStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { switch (message.what) { - case CONNECT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - stateLogW("CONNECT, ignored, device=" + device + ", currentDevice" + mDevice); - break; - } - case DISCONNECT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - stateLogD("DISCONNECT from device=" + device); - if (!mDevice.equals(device)) { - stateLogW("DISCONNECT, device " + device + " not connected"); + case CONNECT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + stateLogW( + "CONNECT, ignored, device=" + device + ", currentDevice" + mDevice); break; } - if (!mNativeInterface.disconnectHfp(device)) { - // broadcast immediately as no state transition is involved - stateLogE("DISCONNECT from " + device + " failed"); - broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTED); - break; + case DISCONNECT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + stateLogD("DISCONNECT from device=" + device); + if (!mDevice.equals(device)) { + stateLogW("DISCONNECT, device " + device + " not connected"); + break; + } + if (!mNativeInterface.disconnectHfp(device)) { + // broadcast immediately as no state transition is involved + stateLogE("DISCONNECT from " + device + " failed"); + broadcastConnectionState( + device, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTED); + break; + } + transitionTo(mDisconnecting); } - transitionTo(mDisconnecting); - } - break; + break; case CONNECT_AUDIO: stateLogD("CONNECT_AUDIO, device=" + mDevice); mSystemInterface.getAudioManager().setA2dpSuspended(true); @@ -1259,7 +1333,9 @@ class HeadsetStateMachine extends StateMachine { } stateLogE("Failed to connect SCO audio for " + mDevice); // No state change involved, fire broadcast immediately - broadcastAudioState(mDevice, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + broadcastAudioState( + mDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_DISCONNECTED); break; } @@ -1286,7 +1362,9 @@ class HeadsetStateMachine extends StateMachine { stateLogE("processAudioEvent: failed to disconnect audio"); } // Indicate rejection to other components. - broadcastAudioState(mDevice, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + broadcastAudioState( + mDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_DISCONNECTED); break; } @@ -1300,7 +1378,9 @@ class HeadsetStateMachine extends StateMachine { stateLogE("processAudioEvent: failed to disconnect pending audio"); } // Indicate rejection to other components. - broadcastAudioState(mDevice, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, + broadcastAudioState( + mDevice, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_DISCONNECTED); break; } @@ -1353,16 +1433,17 @@ class HeadsetStateMachine extends StateMachine { case DISCONNECT_AUDIO: deferMessage(message); break; - case CONNECT_TIMEOUT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("CONNECT_TIMEOUT for unknown device " + device); + case CONNECT_TIMEOUT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW("CONNECT_TIMEOUT for unknown device " + device); + break; + } + stateLogW("CONNECT_TIMEOUT"); + transitionTo(mConnected); break; } - stateLogW("CONNECT_TIMEOUT"); - transitionTo(mConnected); - break; - } default: return super.processMessage(message); } @@ -1447,8 +1528,10 @@ class HeadsetStateMachine extends StateMachine { setAudioParameters(); - mSystemInterface.getAudioManager().setAudioServerStateCallback( - mHeadsetService.getMainExecutor(), mAudioServerStateCallback); + mSystemInterface + .getAudioManager() + .setAudioServerStateCallback( + mHeadsetService.getMainExecutor(), mAudioServerStateCallback); broadcastStateTransitions(); } @@ -1463,54 +1546,64 @@ class HeadsetStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { switch (message.what) { - case CONNECT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - stateLogW("CONNECT, ignored, device=" + device + ", currentDevice" + mDevice); - break; - } - case DISCONNECT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - stateLogD("DISCONNECT, device=" + device); - if (!mDevice.equals(device)) { - stateLogW("DISCONNECT, device " + device + " not connected"); + case CONNECT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + stateLogW( + "CONNECT, ignored, device=" + device + ", currentDevice" + mDevice); break; } - // Disconnect BT SCO first - if (!mNativeInterface.disconnectAudio(mDevice)) { - stateLogW("DISCONNECT failed, device=" + mDevice); - // if disconnect BT SCO failed, transition to mConnected state to force - // disconnect device - } - deferMessage(obtainMessage(DISCONNECT, mDevice)); - transitionTo(mAudioDisconnecting); - break; - } - case CONNECT_AUDIO: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("CONNECT_AUDIO device is not connected " + device); + case DISCONNECT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + stateLogD("DISCONNECT, device=" + device); + if (!mDevice.equals(device)) { + stateLogW("DISCONNECT, device " + device + " not connected"); + break; + } + // Disconnect BT SCO first + if (!mNativeInterface.disconnectAudio(mDevice)) { + stateLogW("DISCONNECT failed, device=" + mDevice); + // if disconnect BT SCO failed, transition to mConnected state to force + // disconnect device + } + deferMessage(obtainMessage(DISCONNECT, mDevice)); + transitionTo(mAudioDisconnecting); break; } - stateLogW("CONNECT_AUDIO device audio is already connected " + device); - break; - } - case DISCONNECT_AUDIO: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("DISCONNECT_AUDIO, failed, device=" + device + ", currentDevice=" - + mDevice); + case CONNECT_AUDIO: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW("CONNECT_AUDIO device is not connected " + device); + break; + } + stateLogW("CONNECT_AUDIO device audio is already connected " + device); break; } - if (mNativeInterface.disconnectAudio(mDevice)) { - stateLogD("DISCONNECT_AUDIO, device=" + mDevice); - transitionTo(mAudioDisconnecting); - } else { - stateLogW("DISCONNECT_AUDIO failed, device=" + mDevice); - broadcastAudioState(mDevice, BluetoothHeadset.STATE_AUDIO_CONNECTED, - BluetoothHeadset.STATE_AUDIO_CONNECTED); + case DISCONNECT_AUDIO: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW( + "DISCONNECT_AUDIO, failed, device=" + + device + + ", currentDevice=" + + mDevice); + break; + } + if (mNativeInterface.disconnectAudio(mDevice)) { + stateLogD("DISCONNECT_AUDIO, device=" + mDevice); + transitionTo(mAudioDisconnecting); + } else { + stateLogW("DISCONNECT_AUDIO failed, device=" + mDevice); + broadcastAudioState( + mDevice, + BluetoothHeadset.STATE_AUDIO_CONNECTED, + BluetoothHeadset.STATE_AUDIO_CONNECTED); + } + break; } - break; - } case INTENT_SCO_VOLUME_CHANGED: processIntentScoVolume((Intent) message.obj, mDevice); break; @@ -1518,8 +1611,11 @@ class HeadsetStateMachine extends StateMachine { HeadsetStackEvent event = (HeadsetStackEvent) message.obj; stateLogD("STACK_EVENT: " + event); if (!mDevice.equals(event.device)) { - stateLogE("Event device does not match currentDevice[" + mDevice - + "], event: " + event); + stateLogE( + "Event device does not match currentDevice[" + + mDevice + + "], event: " + + event); break; } switch (event.type) { @@ -1566,8 +1662,8 @@ class HeadsetStateMachine extends StateMachine { + volumeValue); if (mSpeakerVolume != volumeValue) { mSpeakerVolume = volumeValue; - mNativeInterface.setVolume(device, HeadsetHalConstants.VOLUME_TYPE_SPK, - mSpeakerVolume); + mNativeInterface.setVolume( + device, HeadsetHalConstants.VOLUME_TYPE_SPK, mSpeakerVolume); } } } @@ -1595,26 +1691,28 @@ class HeadsetStateMachine extends StateMachine { case DISCONNECT_AUDIO: deferMessage(message); break; - case CONNECT_TIMEOUT: { - BluetoothDevice device = (BluetoothDevice) message.obj; - if (!mDevice.equals(device)) { - stateLogW("CONNECT_TIMEOUT for unknown device " + device); + case CONNECT_TIMEOUT: + { + BluetoothDevice device = (BluetoothDevice) message.obj; + if (!mDevice.equals(device)) { + stateLogW("CONNECT_TIMEOUT for unknown device " + device); + break; + } + if (mAudioDisconnectRetry == MAX_RETRY_DISCONNECT_AUDIO) { + stateLogW("CONNECT_TIMEOUT: Disconnecting device"); + // Restoring state to Connected with message DISCONNECT + deferMessage(obtainMessage(DISCONNECT, mDevice)); + transitionTo(mConnected); + } else { + mAudioDisconnectRetry += 1; + stateLogW( + "CONNECT_TIMEOUT: retrying " + + (MAX_RETRY_DISCONNECT_AUDIO - mAudioDisconnectRetry) + + " more time(s)"); + transitionTo(mAudioOn); + } break; } - if (mAudioDisconnectRetry == MAX_RETRY_DISCONNECT_AUDIO) { - stateLogW("CONNECT_TIMEOUT: Disconnecting device"); - // Restoring state to Connected with message DISCONNECT - deferMessage(obtainMessage(DISCONNECT, mDevice)); - transitionTo(mConnected); - } else { - mAudioDisconnectRetry += 1; - stateLogW("CONNECT_TIMEOUT: retrying " - + (MAX_RETRY_DISCONNECT_AUDIO - mAudioDisconnectRetry) - + " more time(s)"); - transitionTo(mAudioOn); - } - break; - } default: return super.processMessage(message); } @@ -1666,9 +1764,9 @@ class HeadsetStateMachine extends StateMachine { /** * Get the current connection state of this state machine * - * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, - * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or - * {@link BluetoothProfile#STATE_DISCONNECTING} + * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, {@link + * BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or {@link + * BluetoothProfile#STATE_DISCONNECTING} */ @VisibleForTesting public synchronized int getConnectionState() { @@ -1681,9 +1779,9 @@ class HeadsetStateMachine extends StateMachine { /** * Get the current audio state of this state machine * - * @return current audio state, one of {@link BluetoothHeadset#STATE_AUDIO_DISCONNECTED}, - * {@link BluetoothHeadset#STATE_AUDIO_CONNECTING}, or - * {@link BluetoothHeadset#STATE_AUDIO_CONNECTED} + * @return current audio state, one of {@link BluetoothHeadset#STATE_AUDIO_DISCONNECTED}, {@link + * BluetoothHeadset#STATE_AUDIO_CONNECTING}, or {@link + * BluetoothHeadset#STATE_AUDIO_CONNECTED} */ public synchronized int getAudioState() { if (mCurrentState == null) { @@ -1708,8 +1806,9 @@ class HeadsetStateMachine extends StateMachine { return false; } if (silence) { - mSystemInterface.getHeadsetPhoneState().listenForPhoneState(mDevice, - PhoneStateListener.LISTEN_NONE); + mSystemInterface + .getHeadsetPhoneState() + .listenForPhoneState(mDevice, PhoneStateListener.LISTEN_NONE); } else { updateAgIndicatorEnableState(mAgIndicatorEnableState); } @@ -1721,8 +1820,12 @@ class HeadsetStateMachine extends StateMachine { * Put the AT command, company ID, arguments, and device in an Intent and broadcast it. */ @VisibleForTesting - void broadcastVendorSpecificEventIntent(String command, int companyId, int commandType, - Object[] arguments, BluetoothDevice device) { + void broadcastVendorSpecificEventIntent( + String command, + int companyId, + int commandType, + Object[] arguments, + BluetoothDevice device) { log("broadcastVendorSpecificEventIntent(" + command + ")"); mAdapterService .getRemoteDevices() @@ -1735,8 +1838,10 @@ class HeadsetStateMachine extends StateMachine { // assert: all elements of args are Serializable intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS, arguments); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." - + Integer.toString(companyId)); + intent.addCategory( + BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + + "." + + Integer.toString(companyId)); mHeadsetService.sendBroadcastAsUser( intent, UserHandle.ALL, @@ -1880,10 +1985,13 @@ class HeadsetStateMachine extends StateMachine { if (volumeType == HeadsetHalConstants.VOLUME_TYPE_SPK) { mSpeakerVolume = volume; int flag = (mCurrentState == mAudioOn) ? AudioManager.FLAG_SHOW_UI : 0; - int currentVol = mSystemInterface.getAudioManager().getStreamVolume( - AudioManager.STREAM_BLUETOOTH_SCO); + int currentVol = + mSystemInterface + .getAudioManager() + .getStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO); if (volume != currentVol) { - mSystemInterface.getAudioManager() + mSystemInterface + .getAudioManager() .setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, volume, flag); } } else if (volumeType == HeadsetHalConstants.VOLUME_TYPE_MIC) { @@ -1981,7 +2089,8 @@ class HeadsetStateMachine extends StateMachine { void processSubscriberNumberRequest(BluetoothDevice device) { String number = mSystemInterface.getSubscriberNumber(); if (number != null) { - mNativeInterface.atResponseString(device, + mNativeInterface.atResponseString( + device, "+CNUM: ,\"" + number + "\"," + PhoneNumberUtils.toaFromString(number) + ",,4"); } else { Log.e(TAG, "getSubscriberNumber returns null, no subscriber number can reply"); @@ -1998,8 +2107,8 @@ class HeadsetStateMachine extends StateMachine { int service = phoneState.getCindService(), signal = phoneState.getCindSignal(); /* Handsfree carkits expect that +CIND is properly responded to - Hence we ensure that a proper response is sent - for the virtual call too.*/ + Hence we ensure that a proper response is sent + for the virtual call too.*/ if (mHeadsetService.isVirtualCallStarted()) { call = 1; callSetup = 0; @@ -2120,10 +2229,7 @@ class HeadsetStateMachine extends StateMachine { } } - /** - * Find a character ch, ignoring quoted sections. - * Return input.length() if not found. - */ + /** Find a character ch, ignoring quoted sections. Return input.length() if not found. */ @VisibleForTesting static int findChar(char ch, String input, int fromIndex) { for (int i = fromIndex; i < input.length(); i++) { @@ -2141,9 +2247,8 @@ class HeadsetStateMachine extends StateMachine { } /** - * Break an argument string into individual arguments (comma delimited). - * Integer arguments are turned into Integer objects. Otherwise a String - * object is used. + * Break an argument string into individual arguments (comma delimited). Integer arguments are + * turned into Integer objects. Otherwise a String object is used. */ @VisibleForTesting static Object[] generateArgs(String input) { @@ -2227,8 +2332,8 @@ class HeadsetStateMachine extends StateMachine { if (command.equals(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XAPL)) { processAtXapl(args, device); } - broadcastVendorSpecificEventIntent(command, companyId, BluetoothHeadset.AT_CMD_TYPE_SET, - args, device); + broadcastVendorSpecificEventIntent( + command, companyId, BluetoothHeadset.AT_CMD_TYPE_SET, args, device); mNativeInterface.atResponseCode(device, HeadsetHalConstants.AT_RESPONSE_OK, 0); } @@ -2271,12 +2376,11 @@ class HeadsetStateMachine extends StateMachine { if (type.equals(BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID)) { Log.d(TAG, "Processing command: " + atString); if (processAndroidAtSinkAudioPolicy(args, device)) { - mNativeInterface.atResponseCode(device, - HeadsetHalConstants.AT_RESPONSE_OK, 0); + mNativeInterface.atResponseCode(device, HeadsetHalConstants.AT_RESPONSE_OK, 0); } else { Log.w(TAG, "Invalid SinkAudioPolicy parameters!"); - mNativeInterface.atResponseCode(device, - HeadsetHalConstants.AT_RESPONSE_ERROR, 0); + mNativeInterface.atResponseCode( + device, HeadsetHalConstants.AT_RESPONSE_ERROR, 0); } return true; } else { @@ -2294,9 +2398,12 @@ class HeadsetStateMachine extends StateMachine { replying with +ANDROID: (, , ...) currently we only support one type of feature: SINKAUDIOPOLICY */ - mNativeInterface.atResponseString(device, + mNativeInterface.atResponseString( + device, BluetoothHeadset.VENDOR_RESULT_CODE_COMMAND_ANDROID - + ": (" + BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID + ")"); + + ": (" + + BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID + + ")"); } /** @@ -2309,19 +2416,26 @@ class HeadsetStateMachine extends StateMachine { @VisibleForTesting boolean processAndroidAtSinkAudioPolicy(Object[] args, BluetoothDevice device) { if (args.length != 4) { - Log.e(TAG, "processAndroidAtSinkAudioPolicy() args length must be 4: " - + String.valueOf(args.length)); + Log.e( + TAG, + "processAndroidAtSinkAudioPolicy() args length must be 4: " + + String.valueOf(args.length)); return false; } - if (!(args[1] instanceof Integer) || !(args[2] instanceof Integer) + if (!(args[1] instanceof Integer) + || !(args[2] instanceof Integer) || !(args[3] instanceof Integer)) { Log.e(TAG, "processAndroidAtSinkAudioPolicy() argument types not matched"); return false; } if (!mDevice.equals(device)) { - Log.e(TAG, "processAndroidAtSinkAudioPolicy(): argument device " + device - + " doesn't match mDevice " + mDevice); + Log.e( + TAG, + "processAndroidAtSinkAudioPolicy(): argument device " + + device + + " doesn't match mDevice " + + mDevice); return false; } @@ -2329,11 +2443,12 @@ class HeadsetStateMachine extends StateMachine { int connectingTimePolicy = (Integer) args[2]; int inbandPolicy = (Integer) args[3]; - setHfpCallAudioPolicy(new BluetoothSinkAudioPolicy.Builder() - .setCallEstablishPolicy(callEstablishPolicy) - .setActiveDevicePolicyAfterConnection(connectingTimePolicy) - .setInBandRingtonePolicy(inbandPolicy) - .build()); + setHfpCallAudioPolicy( + new BluetoothSinkAudioPolicy.Builder() + .setCallEstablishPolicy(callEstablishPolicy) + .setActiveDevicePolicyAfterConnection(connectingTimePolicy) + .setInBandRingtonePolicy(inbandPolicy) + .build()); return true; } @@ -2347,10 +2462,7 @@ class HeadsetStateMachine extends StateMachine { mDatabaseManager.setAudioPolicyMetadata(mDevice, policies); } - /** - * get the audio policy of the client device - * - */ + /** get the audio policy of the client device */ public BluetoothSinkAudioPolicy getHfpCallAudioPolicy() { return mHsClientAudioPolicy; } @@ -2380,13 +2492,20 @@ class HeadsetStateMachine extends StateMachine { String productId = deviceInfo[1]; String version = deviceInfo[2]; String[] macAddress = device.getAddress().split(":"); - BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_DEVICE_INFO_REPORTED, - mAdapterService.obfuscateAddress(device), BluetoothProtoEnums.DEVICE_INFO_INTERNAL, - BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XAPL, vendorId, productId, version, - null, mAdapterService.getMetricId(device), + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_DEVICE_INFO_REPORTED, + mAdapterService.obfuscateAddress(device), + BluetoothProtoEnums.DEVICE_INFO_INTERNAL, + BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XAPL, + vendorId, + productId, + version, + null, + mAdapterService.getMetricId(device), device.getAddressType(), Integer.parseInt(macAddress[0], 16), - Integer.parseInt(macAddress[1], 16), Integer.parseInt(macAddress[2], 16)); + Integer.parseInt(macAddress[1], 16), + Integer.parseInt(macAddress[2], 16)); // feature = 2 indicates that we support battery level reporting only mNativeInterface.atResponseString(device, "+XAPL=iPhone," + String.valueOf(2)); } @@ -2552,8 +2671,15 @@ class HeadsetStateMachine extends StateMachine { if (clcc.mIndex == 0) { removeMessages(CLCC_RSP_TIMEOUT); } - mNativeInterface.clccResponse(mDevice, clcc.mIndex, clcc.mDirection, clcc.mStatus, - clcc.mMode, clcc.mMpty, clcc.mNumber, clcc.mType); + mNativeInterface.clccResponse( + mDevice, + clcc.mIndex, + clcc.mDirection, + clcc.mStatus, + clcc.mMode, + clcc.mMpty, + clcc.mNumber, + clcc.mType); } @VisibleForTesting @@ -2575,10 +2701,11 @@ class HeadsetStateMachine extends StateMachine { private void updateAgIndicatorEnableState( HeadsetAgIndicatorEnableState agIndicatorEnableState) { - if (!mDeviceSilenced - && Objects.equals(mAgIndicatorEnableState, agIndicatorEnableState)) { - Log.i(TAG, "updateAgIndicatorEnableState, no change in indicator state " - + mAgIndicatorEnableState); + if (!mDeviceSilenced && Objects.equals(mAgIndicatorEnableState, agIndicatorEnableState)) { + Log.i( + TAG, + "updateAgIndicatorEnableState, no change in indicator state " + + mAgIndicatorEnableState); return; } mAgIndicatorEnableState = agIndicatorEnableState; @@ -2630,8 +2757,9 @@ class HeadsetStateMachine extends StateMachine { // REASON: mCheckingAccessPermission is true, otherwise resetAtState // has set mCheckingAccessPermission to false if (intent.getAction().equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) { - if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, - BluetoothDevice.CONNECTION_ACCESS_NO) + if (intent.getIntExtra( + BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, + BluetoothDevice.CONNECTION_ACCESS_NO) == BluetoothDevice.CONNECTION_ACCESS_YES) { if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED); diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java b/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java index ceaa43727d0..e7eaaf992ef 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java @@ -69,9 +69,7 @@ class HeadsetSystemInterface { return BluetoothInCallService.getInstance(); } - /** - * Stop this system interface - */ + /** Stop this system interface */ public synchronized void stop() { mHeadsetPhoneState.cleanup(); } @@ -124,8 +122,9 @@ class HeadsetSystemInterface { if (bluetoothInCallService != null) { BluetoothSinkAudioPolicy callAudioPolicy = mHeadsetService.getHfpCallAudioPolicy(device); - if (callAudioPolicy == null || callAudioPolicy.getCallEstablishPolicy() - != BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { + if (callAudioPolicy == null + || callAudioPolicy.getCallEstablishPolicy() + != BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { mHeadsetService.setActiveDevice(device); } bluetoothInCallService.answerCall(); @@ -277,15 +276,13 @@ class HeadsetSystemInterface { Log.e(TAG, "getSubscriberNumber() failed: mBluetoothInCallService is null"); Log.i(TAG, "Try to get phone number without mBluetoothInCallService."); return getNumberWithoutInCallService(); - } return bluetoothInCallService.getSubscriberNumber(); } - /** - * Ask the Telecomm service to list current list of calls through CLCC response - * {@link BluetoothHeadset#clccResponse(int, int, int, int, boolean, String, int)} + * Ask the Telecomm service to list current list of calls through CLCC response {@link + * BluetoothHeadset#clccResponse(int, int, int, int, boolean, String, int)} * * @return */ @@ -322,9 +319,11 @@ class HeadsetSystemInterface { */ @VisibleForTesting public boolean isInCall() { - return ((mHeadsetPhoneState.getNumActiveCall() > 0) || (mHeadsetPhoneState.getNumHeldCall() - > 0) || ((mHeadsetPhoneState.getCallState() != HeadsetHalConstants.CALL_STATE_IDLE) - && (mHeadsetPhoneState.getCallState() != HeadsetHalConstants.CALL_STATE_INCOMING))); + return ((mHeadsetPhoneState.getNumActiveCall() > 0) + || (mHeadsetPhoneState.getNumHeldCall() > 0) + || ((mHeadsetPhoneState.getCallState() != HeadsetHalConstants.CALL_STATE_IDLE) + && (mHeadsetPhoneState.getCallState() + != HeadsetHalConstants.CALL_STATE_INCOMING))); } /** @@ -350,10 +349,10 @@ class HeadsetSystemInterface { /** * Activate voice recognition on Android system * - * @return true if activation succeeds, caller should wait for - * {@link BluetoothHeadset#startVoiceRecognition(BluetoothDevice)} callback that will then - * trigger {@link HeadsetService#startVoiceRecognition(BluetoothDevice)}, false if failed to - * activate + * @return true if activation succeeds, caller should wait for {@link + * BluetoothHeadset#startVoiceRecognition(BluetoothDevice)} callback that will then trigger + * {@link HeadsetService#startVoiceRecognition(BluetoothDevice)}, false if failed to + * activate */ @VisibleForTesting public boolean activateVoiceRecognition() { @@ -371,15 +370,13 @@ class HeadsetSystemInterface { /** * Deactivate voice recognition on Android system * - * @return true if activation succeeds, caller should wait for - * {@link BluetoothHeadset#stopVoiceRecognition(BluetoothDevice)} callback that will then - * trigger {@link HeadsetService#stopVoiceRecognition(BluetoothDevice)}, false if failed to - * activate + * @return true if activation succeeds, caller should wait for {@link + * BluetoothHeadset#stopVoiceRecognition(BluetoothDevice)} callback that will then trigger + * {@link HeadsetService#stopVoiceRecognition(BluetoothDevice)}, false if failed to activate */ @VisibleForTesting public boolean deactivateVoiceRecognition() { // TODO: need a method to deactivate voice recognition on Android return true; } - } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java index c562d180e4c..93acf382c2d 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java @@ -58,8 +58,7 @@ import java.util.Set; import java.util.UUID; /** - * Provides Bluetooth Headset Client (HF Role) profile, as a service in the - * Bluetooth application. + * Provides Bluetooth Headset Client (HF Role) profile, as a service in the Bluetooth application. */ public class HeadsetClientService extends ProfileService { private static final String TAG = HeadsetClientService.class.getSimpleName(); @@ -105,9 +104,10 @@ public class HeadsetClientService extends ProfileService { throw new IllegalStateException("start() called twice"); } - mDatabaseManager = Objects.requireNonNull( - AdapterService.getAdapterService().getDatabase(), - "DatabaseManager cannot be null when HeadsetClientService starts"); + mDatabaseManager = + Objects.requireNonNull( + AdapterService.getAdapterService().getDatabase(), + "DatabaseManager cannot be null when HeadsetClientService starts"); // Setup the JNI service mNativeInterface = NativeInterface.getInstance(); @@ -172,7 +172,8 @@ public class HeadsetClientService extends ProfileService { synchronized (mStateMachineMap) { for (Iterator> it = - mStateMachineMap.entrySet().iterator(); it.hasNext(); ) { + mStateMachineMap.entrySet().iterator(); + it.hasNext(); ) { HeadsetClientStateMachine sm = mStateMachineMap.get((BluetoothDevice) it.next().getKey()); sm.doQuit(); @@ -189,60 +190,72 @@ public class HeadsetClientService extends ProfileService { } } - private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - // We handle the volume changes for Voice calls here since HFP audio volume control does - // not go through audio manager (audio mixer). see - // ({@link HeadsetClientStateMachine#SET_SPEAKER_VOLUME} in - // {@link HeadsetClientStateMachine} for details. - if (action.equals(AudioManager.ACTION_VOLUME_CHANGED)) { - Log.d(TAG, "Volume changed for stream: " + intent.getIntExtra( - AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1)); - int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1); - if (streamType == AudioManager.STREAM_VOICE_CALL) { - int streamValue = - intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1); - int hfVol = HeadsetClientStateMachine.amToHfVol(streamValue); - Log.d(TAG, - "Setting volume to audio manager: " + streamValue + " hands free: " - + hfVol); - mAudioManager.setHfpVolume(hfVol); - synchronized (mStateMachineMap) { - for (HeadsetClientStateMachine sm : mStateMachineMap.values()) { - if (sm != null) { - sm.sendMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, - streamValue); + private final BroadcastReceiver mBroadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + // We handle the volume changes for Voice calls here since HFP audio volume + // control does + // not go through audio manager (audio mixer). see + // ({@link HeadsetClientStateMachine#SET_SPEAKER_VOLUME} in + // {@link HeadsetClientStateMachine} for details. + if (action.equals(AudioManager.ACTION_VOLUME_CHANGED)) { + Log.d( + TAG, + "Volume changed for stream: " + + intent.getIntExtra( + AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1)); + int streamType = + intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1); + if (streamType == AudioManager.STREAM_VOICE_CALL) { + int streamValue = + intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1); + int hfVol = HeadsetClientStateMachine.amToHfVol(streamValue); + Log.d( + TAG, + "Setting volume to audio manager: " + + streamValue + + " hands free: " + + hfVol); + mAudioManager.setHfpVolume(hfVol); + synchronized (mStateMachineMap) { + for (HeadsetClientStateMachine sm : mStateMachineMap.values()) { + if (sm != null) { + sm.sendMessage( + HeadsetClientStateMachine.SET_SPEAKER_VOLUME, + streamValue); + } + } } } - } - } - } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { - int batteryIndicatorID = 2; - int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); - - if (batteryLevel == mLastBatteryLevel) { - return; - } - mLastBatteryLevel = batteryLevel; - - Log.d(TAG, - "Send battery level update BIEV(2," + batteryLevel + ") command"); + } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { + int batteryIndicatorID = 2; + int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); - synchronized (mStateMachineMap) { - for (HeadsetClientStateMachine sm : mStateMachineMap.values()) { - if (sm != null) { - sm.sendMessage(HeadsetClientStateMachine.SEND_BIEV, - batteryIndicatorID, - batteryLevel); + if (batteryLevel == mLastBatteryLevel) { + return; + } + mLastBatteryLevel = batteryLevel; + + Log.d( + TAG, + "Send battery level update BIEV(2," + batteryLevel + ") command"); + + synchronized (mStateMachineMap) { + for (HeadsetClientStateMachine sm : mStateMachineMap.values()) { + if (sm != null) { + sm.sendMessage( + HeadsetClientStateMachine.SEND_BIEV, + batteryIndicatorID, + batteryLevel); + } + } } } } - } - } - }; + }; /** * Convert {@code HfpClientCall} to legacy {@code BluetoothHeadsetClientCall} still used by some @@ -250,14 +263,18 @@ public class HeadsetClientService extends ProfileService { */ static BluetoothHeadsetClientCall toLegacyCall(HfpClientCall call) { if (call == null) return null; - return new BluetoothHeadsetClientCall(call.getDevice(), call.getId(), call.getUUID(), - call.getState(), call.getNumber(), call.isMultiParty(), call.isOutgoing(), + return new BluetoothHeadsetClientCall( + call.getDevice(), + call.getId(), + call.getUUID(), + call.getState(), + call.getNumber(), + call.isMultiParty(), + call.isOutgoing(), call.isInBandRing()); } - /** - * Handlers for incoming service calls - */ + /** Handlers for incoming service calls */ @VisibleForTesting static class BluetoothHeadsetClientBinder extends IBluetoothHeadsetClient.Stub implements IProfileServiceBinder { @@ -283,7 +300,7 @@ public class HeadsetClientService extends ProfileService { return null; } return mService; - } + } @Override public boolean connect(BluetoothDevice device, AttributionSource source) { @@ -597,8 +614,11 @@ public class HeadsetClientService extends ProfileService { public boolean connect(BluetoothDevice device) { Log.d(TAG, "connect " + device); if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - Log.w(TAG, "Connection not allowed: <" + device.getAddress() - + "> is CONNECTION_POLICY_FORBIDDEN"); + Log.w( + TAG, + "Connection not allowed: <" + + device.getAddress() + + "> is CONNECTION_POLICY_FORBIDDEN"); return false; } HeadsetClientStateMachine sm = getStateMachine(device, true); @@ -669,10 +689,10 @@ public class HeadsetClientService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { HeadsetClientStateMachine sm = getStateMachine(device); @@ -684,15 +704,14 @@ public class HeadsetClientService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -701,8 +720,8 @@ public class HeadsetClientService extends ProfileService { public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HEADSET_CLIENT, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HEADSET_CLIENT, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -716,17 +735,15 @@ public class HeadsetClientService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.HEADSET_CLIENT); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HEADSET_CLIENT); } boolean startVoiceRecognition(BluetoothDevice device) { @@ -760,8 +777,8 @@ public class HeadsetClientService extends ProfileService { /** * Gets audio state of the connection with {@code device}. * - *

Can be one of {@link STATE_AUDIO_CONNECTED}, {@link STATE_AUDIO_CONNECTING}, or - * {@link STATE_AUDIO_DISCONNECTED}. + *

Can be one of {@link STATE_AUDIO_CONNECTED}, {@link STATE_AUDIO_CONNECTING}, or {@link + * STATE_AUDIO_DISCONNECTED}. */ public int getAudioState(BluetoothDevice device) { HeadsetClientStateMachine sm = getStateMachine(device); @@ -775,8 +792,14 @@ public class HeadsetClientService extends ProfileService { public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); - Log.i(TAG, "setAudioRouteAllowed: device=" + device + ", allowed=" + allowed + ", " - + Utils.getUidPidString()); + Log.i( + TAG, + "setAudioRouteAllowed: device=" + + device + + ", allowed=" + + allowed + + ", " + + Utils.getUidPidString()); HeadsetClientStateMachine sm = mStateMachineMap.get(device); if (sm != null) { sm.setAudioRouteAllowed(allowed); @@ -801,8 +824,14 @@ public class HeadsetClientService extends ProfileService { */ public void setAudioPolicy(BluetoothDevice device, BluetoothSinkAudioPolicy policies) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); - Log.i(TAG, "setAudioPolicy: device=" + device + ", " + policies.toString() + ", " - + Utils.getUidPidString()); + Log.i( + TAG, + "setAudioPolicy: device=" + + device + + ", " + + policies.toString() + + ", " + + Utils.getUidPidString()); HeadsetClientStateMachine sm = getStateMachine(device); if (sm != null) { sm.setAudioPolicy(policies); @@ -891,14 +920,17 @@ public class HeadsetClientService extends ProfileService { public boolean acceptCall(BluetoothDevice device, int flag) { /* Phonecalls from a single device are supported, hang up any calls on the other phone */ synchronized (mStateMachineMap) { - for (Map.Entry entry : mStateMachineMap - .entrySet()) { + for (Map.Entry entry : + mStateMachineMap.entrySet()) { if (entry.getValue() == null || entry.getKey().equals(device)) { continue; } int connectionState = entry.getValue().getConnectionState(entry.getKey()); - Log.d(TAG, - "Accepting a call on device " + device + ". Possibly disconnecting on " + Log.d( + TAG, + "Accepting a call on device " + + device + + ". Possibly disconnecting on " + entry.getValue()); if (connectionState == BluetoothProfile.STATE_CONNECTED) { entry.getValue() @@ -993,17 +1025,23 @@ public class HeadsetClientService extends ProfileService { } // Some platform does not support three way calling (ex: watch) - final boolean support_three_way_calling = SystemProperties - .getBoolean("bluetooth.headset_client.three_way_calling.enabled", true); + final boolean support_three_way_calling = + SystemProperties.getBoolean( + "bluetooth.headset_client.three_way_calling.enabled", true); if (!support_three_way_calling && !getCurrentCalls(device).isEmpty()) { Log.e(TAG, String.format("dial(%s): Line is busy, reject dialing", device)); return null; } - HfpClientCall call = new HfpClientCall(device, - HeadsetClientStateMachine.HF_ORIGINATED_CALL_ID, - HfpClientCall.CALL_STATE_DIALING, number, false /* multiparty */, - true /* outgoing */, sm.getInBandRing()); + HfpClientCall call = + new HfpClientCall( + device, + HeadsetClientStateMachine.HF_ORIGINATED_CALL_ID, + HfpClientCall.CALL_STATE_DIALING, + number, + false /* multiparty */, + true /* outgoing */, + sm.getInBandRing()); Message msg = sm.obtainMessage(HeadsetClientStateMachine.DIAL_NUMBER); msg.obj = call; sm.sendMessage(msg); @@ -1076,8 +1114,9 @@ public class HeadsetClientService extends ProfileService { return false; } - Message msg = sm.obtainMessage(HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, - vendorId, 0, atCommand); + Message msg = + sm.obtainMessage( + HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); sm.sendMessage(msg); return true; } @@ -1124,11 +1163,11 @@ public class HeadsetClientService extends ProfileService { // Handle messages from native (JNI) to java public void messageFromNative(StackEvent stackEvent) { - Objects.requireNonNull(stackEvent.device, - "Device should never be null, event: " + stackEvent); + Objects.requireNonNull( + stackEvent.device, "Device should never be null, event: " + stackEvent); - HeadsetClientStateMachine sm = getStateMachine(stackEvent.device, - isConnectionEvent(stackEvent)); + HeadsetClientStateMachine sm = + getStateMachine(stackEvent.device, isConnectionEvent(stackEvent)); if (sm == null) { throw new IllegalStateException( "State machine not found for stack event: " + stackEvent); @@ -1140,7 +1179,7 @@ public class HeadsetClientService extends ProfileService { if (stackEvent.type == StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) { if ((stackEvent.valueInt == HeadsetClientHalConstants.CONNECTION_STATE_CONNECTING) || (stackEvent.valueInt - == HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED)) { + == HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED)) { return true; } } @@ -1151,8 +1190,8 @@ public class HeadsetClientService extends ProfileService { return getStateMachine(device, false); } - private HeadsetClientStateMachine getStateMachine(BluetoothDevice device, - boolean isConnectionEvent) { + private HeadsetClientStateMachine getStateMachine( + BluetoothDevice device, boolean isConnectionEvent) { if (device == null) { Log.e(TAG, "getStateMachine failed: Device cannot be null"); return null; @@ -1186,8 +1225,10 @@ public class HeadsetClientService extends ProfileService { // Preconditions: {@code setHeadsetClientService(this)} is the last thing {@code start} // does, and {@code setHeadsetClientService(null)} is (one of) the first thing // {@code stop does}. - Log.e(TAG, "Cannot allocate SM if service has begun stopping or has not completed" - + " startup."); + Log.e( + TAG, + "Cannot allocate SM if service has begun stopping or has not completed" + + " startup."); return null; } @@ -1202,8 +1243,10 @@ public class HeadsetClientService extends ProfileService { // BluetoothAddresses. If it so happens instead of blowing up we can at least put a // limit on how long the attack would survive if (mStateMachineMap.keySet().size() > MAX_STATE_MACHINES_POSSIBLE) { - Log.e(TAG, "Max state machines reached, possible DOS attack " - + MAX_STATE_MACHINES_POSSIBLE); + Log.e( + TAG, + "Max state machines reached, possible DOS attack " + + MAX_STATE_MACHINES_POSSIBLE); return null; } @@ -1218,13 +1261,18 @@ public class HeadsetClientService extends ProfileService { // Check if any of the state machines have routed the SCO audio stream. boolean isScoRouted() { synchronized (mStateMachineMap) { - for (Map.Entry entry : mStateMachineMap - .entrySet()) { + for (Map.Entry entry : + mStateMachineMap.entrySet()) { if (entry.getValue() != null) { int audioState = entry.getValue().getAudioState(entry.getKey()); if (audioState == HeadsetClientHalConstants.AUDIO_STATE_CONNECTED) { - Log.d(TAG, "Device " + entry.getKey() + " audio state " + audioState - + " Connected"); + Log.d( + TAG, + "Device " + + entry.getKey() + + " audio state " + + audioState + + " Connected"); return true; } } @@ -1276,9 +1324,8 @@ public class HeadsetClientService extends ProfileService { synchronized (mStateMachineMap) { for (HeadsetClientStateMachine sm : mStateMachineMap.values()) { if (sm != null) { - sm.sendMessage(HeadsetClientStateMachine.SEND_BIEV, - batteryIndicatorID, - batteryLevel); + sm.sendMessage( + HeadsetClientStateMachine.SEND_BIEV, batteryIndicatorID, batteryLevel); } } } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceInterface.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceInterface.java index 043f87ec207..cade6848d71 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceInterface.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceInterface.java @@ -26,7 +26,7 @@ import java.util.Set; /** * Interface for talking to the HeadsetClientService * - * Deals with service lifecycle and returns consistent error values + *

Deals with service lifecycle and returns consistent error values */ public class HeadsetClientServiceInterface { private static final String TAG = "HeadsetClientServiceInterface"; @@ -36,8 +36,7 @@ public class HeadsetClientServiceInterface { public static final int CALL_ACCEPT_HOLD = 1; public static final int CALL_ACCEPT_TERMINATE = 2; - public HeadsetClientServiceInterface() { - } + public HeadsetClientServiceInterface() {} private boolean isServiceAvailable(HeadsetClientService service) { if (service == null) { diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java index 26425272062..30d9fcb38ac 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java @@ -15,22 +15,10 @@ */ /** - * Bluetooth Headset Client StateMachine - * (Disconnected) - * | ^ ^ - * CONNECT | | | DISCONNECTED - * V | | - * (Connecting) | - * | | - * CONNECTED | | DISCONNECT - * V | - * (Connected) - * | ^ - * CONNECT_AUDIO | | DISCONNECT_AUDIO - * V | - * (AudioOn) + * Bluetooth Headset Client StateMachine (Disconnected) | ^ ^ CONNECT | | | DISCONNECTED V | | + * (Connecting) | | | CONNECTED | | DISCONNECT V | (Connected) | ^ CONNECT_AUDIO | | + * DISCONNECT_AUDIO V | (AudioOn) */ - package com.android.bluetooth.hfpclient; import static android.Manifest.permission.BLUETOOTH_CONNECT; @@ -118,21 +106,16 @@ public class HeadsetClientStateMachine extends StateMachine { public static final int SEND_ANDROID_AT_COMMAND = 23; // internal actions - @VisibleForTesting - static final int QUERY_CURRENT_CALLS = 50; - @VisibleForTesting - static final int QUERY_OPERATOR_NAME = 51; - @VisibleForTesting - static final int SUBSCRIBER_INFO = 52; - @VisibleForTesting - static final int CONNECTING_TIMEOUT = 53; + @VisibleForTesting static final int QUERY_CURRENT_CALLS = 50; + @VisibleForTesting static final int QUERY_OPERATOR_NAME = 51; + @VisibleForTesting static final int SUBSCRIBER_INFO = 52; + @VisibleForTesting static final int CONNECTING_TIMEOUT = 53; // special action to handle terminating specific call from multiparty call static final int TERMINATE_SPECIFIC_CALL = 53; // Timeouts. - @VisibleForTesting - static final int CONNECTING_TIMEOUT_MS = 10000; // 10s + @VisibleForTesting static final int CONNECTING_TIMEOUT_MS = 10000; // 10s private static final int ROUTING_DELAY_MS = 250; @VisibleForTesting static final int MAX_HFP_SCO_VOICE_CALL_VOLUME = 15; // HFP 1.5 spec. @@ -156,8 +139,7 @@ public class HeadsetClientStateMachine extends StateMachine { // Set of calls that represent the accurate state of calls that exists on AG and the calls that // are currently in process of being notified to the AG from HF. - @VisibleForTesting - final Hashtable mCalls = new Hashtable<>(); + @VisibleForTesting final Hashtable mCalls = new Hashtable<>(); // Set of calls received from AG via the AT+CLCC command. We use this map to update the mCalls // which is eventually used to inform the telephony stack of any changes to call on HF. private final Hashtable mCallsUpdate = new Hashtable<>(); @@ -169,18 +151,15 @@ public class HeadsetClientStateMachine extends StateMachine { private boolean mInBandRing; private String mOperatorName; - @VisibleForTesting - String mSubscriberInfo; + @VisibleForTesting String mSubscriberInfo; private static int sMaxAmVcVol; private static int sMinAmVcVol; // queue of send actions (pair action, action_data) - @VisibleForTesting - Queue> mQueuedActions; + @VisibleForTesting Queue> mQueuedActions; - @VisibleForTesting - int mAudioState; + @VisibleForTesting int mAudioState; // Indicates whether audio can be routed to the device private boolean mAudioRouteAllowed; @@ -200,14 +179,11 @@ public class HeadsetClientStateMachine extends StateMachine { private final BluetoothAdapter mAdapter; // currently connected device - @VisibleForTesting - BluetoothDevice mCurrentDevice = null; + @VisibleForTesting BluetoothDevice mCurrentDevice = null; // general peer features and call handling features - @VisibleForTesting - int mPeerFeatures; - @VisibleForTesting - int mChldFeatures; + @VisibleForTesting int mPeerFeatures; + @VisibleForTesting int mChldFeatures; // This is returned when requesting focus from AudioManager private AudioFocusRequest mAudioFocusRequest; @@ -228,10 +204,15 @@ public class HeadsetClientStateMachine extends StateMachine { public void dump(StringBuilder sb) { if (mCurrentDevice != null) { - ProfileService.println(sb, - "==== StateMachine for " + mCurrentDevice + " ===="); - ProfileService.println(sb, " mCurrentDevice: " + mCurrentDevice + "(" - + Utils.getName(mCurrentDevice) + ") " + this.toString()); + ProfileService.println(sb, "==== StateMachine for " + mCurrentDevice + " ===="); + ProfileService.println( + sb, + " mCurrentDevice: " + + mCurrentDevice + + "(" + + Utils.getName(mCurrentDevice) + + ") " + + this.toString()); } ProfileService.println(sb, " mAudioState: " + mAudioState); ProfileService.println(sb, " mAudioWbs: " + mAudioWbs); @@ -264,7 +245,7 @@ public class HeadsetClientStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); @@ -405,19 +386,20 @@ public class HeadsetClientStateMachine extends StateMachine { if (device == null) { return; } - NetworkServiceState networkServiceState = new NetworkServiceState( - device, - mIndicatorNetworkState == HeadsetClientHalConstants.NETWORK_STATE_AVAILABLE, - mOperatorName, - mIndicatorNetworkSignal, - mIndicatorNetworkType == HeadsetClientHalConstants.SERVICE_TYPE_ROAMING); + NetworkServiceState networkServiceState = + new NetworkServiceState( + device, + mIndicatorNetworkState == HeadsetClientHalConstants.NETWORK_STATE_AVAILABLE, + mOperatorName, + mIndicatorNetworkSignal, + mIndicatorNetworkType == HeadsetClientHalConstants.SERVICE_TYPE_ROAMING); - Intent intent = - new Intent(BluetoothHeadsetClient.ACTION_NETWORK_SERVICE_STATE_CHANGED); + Intent intent = new Intent(BluetoothHeadsetClient.ACTION_NETWORK_SERVICE_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_SERVICE_STATE, networkServiceState); - mService.sendBroadcastMultiplePermissions(intent, + mService.sendBroadcastMultiplePermissions( + intent, new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}, Utils.getTempBroadcastOptions()); } @@ -477,9 +459,17 @@ public class HeadsetClientStateMachine extends StateMachine { callRetainedIds.addAll(currCallIdSet); callRetainedIds.retainAll(newCallIdSet); - debug("currCallIdSet " + mCalls.keySet() + " newCallIdSet " + newCallIdSet - + " callAddedIds " + callAddedIds + " callRemovedIds " + callRemovedIds - + " callRetainedIds " + callRetainedIds); + debug( + "currCallIdSet " + + mCalls.keySet() + + " newCallIdSet " + + newCallIdSet + + " callAddedIds " + + callAddedIds + + " callRemovedIds " + + callRemovedIds + + " callRetainedIds " + + callRetainedIds); // First thing is to try to associate the outgoing HF with a valid call. Integer hfOriginatedAssoc = -1; @@ -515,9 +505,17 @@ public class HeadsetClientStateMachine extends StateMachine { } } - debug("ADJUST: currCallIdSet " + mCalls.keySet() + " newCallIdSet " + newCallIdSet - + " callAddedIds " + callAddedIds + " callRemovedIds " + callRemovedIds - + " callRetainedIds " + callRetainedIds); + debug( + "ADJUST: currCallIdSet " + + mCalls.keySet() + + " newCallIdSet " + + newCallIdSet + + " callAddedIds " + + callAddedIds + + " callRemovedIds " + + callRemovedIds + + " callRetainedIds " + + callRetainedIds); // Terminate & remove the calls that are done. for (Integer idx : callRemovedIds) { @@ -558,11 +556,11 @@ public class HeadsetClientStateMachine extends StateMachine { // a valid call on the phone. The polling would at most continue until // OUTGOING_TIMEOUT_MILLI. This handles the potential scenario where the phone creates // and terminates a call before the first QUERY_CURRENT_CALLS completes. - if (mClccPollDuringCall - || (mCalls.containsKey(HF_ORIGINATED_CALL_ID))) { - sendMessageDelayed(QUERY_CURRENT_CALLS, - mService.getResources().getInteger( - R.integer.hfp_clcc_poll_interval_during_call)); + if (mClccPollDuringCall || (mCalls.containsKey(HF_ORIGINATED_CALL_ID))) { + sendMessageDelayed( + QUERY_CURRENT_CALLS, + mService.getResources() + .getInteger(R.integer.hfp_clcc_poll_interval_during_call)); } else { if (getCall(HfpClientCall.CALL_STATE_INCOMING) != null) { debug("Still have incoming call; polling"); @@ -576,12 +574,13 @@ public class HeadsetClientStateMachine extends StateMachine { mCallsUpdate.clear(); } - private void queryCallsUpdate(int id, int state, String number, boolean multiParty, - boolean outgoing) { + private void queryCallsUpdate( + int id, int state, String number, boolean multiParty, boolean outgoing) { debug("queryCallsUpdate: " + id); - mCallsUpdate.put(id, - new HfpClientCall(mCurrentDevice, id, state, number, multiParty, - outgoing, mInBandRing)); + mCallsUpdate.put( + id, + new HfpClientCall( + mCurrentDevice, id, state, number, multiParty, outgoing, mInBandRing)); } private void acceptCall(int flag) { @@ -589,11 +588,13 @@ public class HeadsetClientStateMachine extends StateMachine { debug("acceptCall: (" + flag + ")"); - HfpClientCall c = getCall(HfpClientCall.CALL_STATE_INCOMING, - HfpClientCall.CALL_STATE_WAITING); + HfpClientCall c = + getCall(HfpClientCall.CALL_STATE_INCOMING, HfpClientCall.CALL_STATE_WAITING); if (c == null) { - c = getCall(HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, - HfpClientCall.CALL_STATE_HELD); + c = + getCall( + HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, + HfpClientCall.CALL_STATE_HELD); if (c == null) { return; @@ -672,10 +673,12 @@ public class HeadsetClientStateMachine extends StateMachine { debug("rejectCall"); - HfpClientCall c = getCall(HfpClientCall.CALL_STATE_INCOMING, - HfpClientCall.CALL_STATE_WAITING, - HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, - HfpClientCall.CALL_STATE_HELD); + HfpClientCall c = + getCall( + HfpClientCall.CALL_STATE_INCOMING, + HfpClientCall.CALL_STATE_WAITING, + HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, + HfpClientCall.CALL_STATE_HELD); if (c == null) { debug("No call to reject, returning."); return; @@ -736,9 +739,11 @@ public class HeadsetClientStateMachine extends StateMachine { int action = HeadsetClientHalConstants.CALL_ACTION_CHUP; - HfpClientCall c = getCall(HfpClientCall.CALL_STATE_DIALING, - HfpClientCall.CALL_STATE_ALERTING, - HfpClientCall.CALL_STATE_ACTIVE); + HfpClientCall c = + getCall( + HfpClientCall.CALL_STATE_DIALING, + HfpClientCall.CALL_STATE_ALERTING, + HfpClientCall.CALL_STATE_ACTIVE); if (c == null) { // If the call being terminated is currently held, switch the action to CHLD_0 c = getCall(HfpClientCall.CALL_STATE_HELD); @@ -759,13 +764,12 @@ public class HeadsetClientStateMachine extends StateMachine { HfpClientCall c = mCalls.get(idx); - if (c == null || c.getState() != HfpClientCall.CALL_STATE_ACTIVE - || !c.isMultiParty()) { + if (c == null || c.getState() != HfpClientCall.CALL_STATE_ACTIVE || !c.isMultiParty()) { return; } - if (mNativeInterface.handleCallAction(mCurrentDevice, - HeadsetClientHalConstants.CALL_ACTION_CHLD_2X, idx)) { + if (mNativeInterface.handleCallAction( + mCurrentDevice, HeadsetClientHalConstants.CALL_ACTION_CHLD_2X, idx)) { addQueuedAction(ENTER_PRIVATE_MODE, c); } else { error("ERROR: Couldn't enter private " + " id:" + idx); @@ -781,8 +785,8 @@ public class HeadsetClientStateMachine extends StateMachine { return; } - if (mNativeInterface.handleCallAction(mCurrentDevice, - HeadsetClientHalConstants.CALL_ACTION_CHLD_4, -1)) { + if (mNativeInterface.handleCallAction( + mCurrentDevice, HeadsetClientHalConstants.CALL_ACTION_CHLD_4, -1)) { addQueuedAction(EXPLICIT_CALL_TRANSFER); } else { error("ERROR: Couldn't transfer call"); @@ -815,8 +819,8 @@ public class HeadsetClientStateMachine extends StateMachine { } if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL) == HeadsetClientHalConstants.CHLD_FEAT_REL) { - b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL, - true); + b.putBoolean( + BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL, true); } if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) == HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) { @@ -874,8 +878,11 @@ public class HeadsetClientStateMachine extends StateMachine { return (bitfield & mask) == mask; } - HeadsetClientStateMachine(HeadsetClientService context, HeadsetService headsetService, - Looper looper, NativeInterface nativeInterface) { + HeadsetClientStateMachine( + HeadsetClientService context, + HeadsetService headsetService, + Looper looper, + NativeInterface nativeInterface) { super(TAG, looper); mService = requireNonNull(context); mNativeInterface = nativeInterface; @@ -890,23 +897,29 @@ public class HeadsetClientStateMachine extends StateMachine { mAudioSWB = false; mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; - mAudioRouteAllowed = context.getResources().getBoolean( - R.bool.headset_client_initial_audio_route_allowed); + mAudioRouteAllowed = + context.getResources() + .getBoolean(R.bool.headset_client_initial_audio_route_allowed); - mAudioRouteAllowed = SystemProperties.getBoolean( - "bluetooth.headset_client.initial_audio_route.enabled", mAudioRouteAllowed); + mAudioRouteAllowed = + SystemProperties.getBoolean( + "bluetooth.headset_client.initial_audio_route.enabled", mAudioRouteAllowed); - mClccPollDuringCall = SystemProperties.getBoolean( - "bluetooth.hfp.clcc_poll_during_call.enabled", - mService.getResources().getBoolean(R.bool.hfp_clcc_poll_during_call)); + mClccPollDuringCall = + SystemProperties.getBoolean( + "bluetooth.hfp.clcc_poll_during_call.enabled", + mService.getResources().getBoolean(R.bool.hfp_clcc_poll_during_call)); mHsClientAudioPolicy = new BluetoothSinkAudioPolicy.Builder().build(); - mConnectingTimePolicyProperty = getAudioPolicySystemProp( - "bluetooth.headset_client.audio_policy.connecting_time.config"); - mInBandRingtonePolicyProperty = getAudioPolicySystemProp( - "bluetooth.headset_client.audio_policy.in_band_ringtone.config"); - mForceSetAudioPolicyProperty = SystemProperties.getBoolean( - "bluetooth.headset_client.audio_policy.force_enabled", false); + mConnectingTimePolicyProperty = + getAudioPolicySystemProp( + "bluetooth.headset_client.audio_policy.connecting_time.config"); + mInBandRingtonePolicyProperty = + getAudioPolicySystemProp( + "bluetooth.headset_client.audio_policy.in_band_ringtone.config"); + mForceSetAudioPolicyProperty = + SystemProperties.getBoolean( + "bluetooth.headset_client.audio_policy.force_enabled", false); mIndicatorNetworkState = HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE; mIndicatorNetworkType = HeadsetClientHalConstants.SERVICE_TYPE_HOME; @@ -937,12 +950,16 @@ public class HeadsetClientStateMachine extends StateMachine { setInitialState(mDisconnected); } - static HeadsetClientStateMachine make(HeadsetClientService context, - HeadsetService headsetService, - Looper looper, NativeInterface nativeInterface) { + static HeadsetClientStateMachine make( + HeadsetClientService context, + HeadsetService headsetService, + Looper looper, + NativeInterface nativeInterface) { Log.d(TAG, "make"); - HeadsetClientStateMachine hfcsm = new HeadsetClientStateMachine(context, headsetService, - looper, nativeInterface); + HeadsetClientStateMachine hfcsm = + new HeadsetClientStateMachine( + context, headsetService, + looper, nativeInterface); hfcsm.start(); return hfcsm; } @@ -963,7 +980,8 @@ public class HeadsetClientStateMachine extends StateMachine { private AudioFocusRequest requestAudioFocus() { AudioAttributes streamAttributes = - new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) + new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) .build(); AudioFocusRequest focusRequest = @@ -971,8 +989,10 @@ public class HeadsetClientStateMachine extends StateMachine { .setAudioAttributes(streamAttributes) .build(); int focusRequestStatus = mAudioManager.requestAudioFocus(focusRequest); - String s = (focusRequestStatus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) - ? "AudioFocus granted" : "AudioFocus NOT granted"; + String s = + (focusRequestStatus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) + ? "AudioFocus granted" + : "AudioFocus NOT granted"; debug("AudioManager requestAudioFocus returned: " + s); return focusRequest; } @@ -998,8 +1018,12 @@ public class HeadsetClientStateMachine extends StateMachine { int hfRange = MAX_HFP_SCO_VOICE_CALL_VOLUME - MIN_HFP_SCO_VOICE_CALL_VOLUME; int amVol = 0; if (Flags.headsetClientAmHfVolumeSymmetric()) { - amVol = (int) Math.round((hfVol - MIN_HFP_SCO_VOICE_CALL_VOLUME) - * ((double) amRange / hfRange)) + sMinAmVcVol; + amVol = + (int) + Math.round( + (hfVol - MIN_HFP_SCO_VOICE_CALL_VOLUME) + * ((double) amRange / hfRange)) + + sMinAmVcVol; } else { int amOffset = (amRange * (hfVol - MIN_HFP_SCO_VOICE_CALL_VOLUME)) / hfRange; amVol = sMinAmVcVol + amOffset; @@ -1013,7 +1037,8 @@ public class HeadsetClientStateMachine extends StateMachine { int hfRange = MAX_HFP_SCO_VOICE_CALL_VOLUME - MIN_HFP_SCO_VOICE_CALL_VOLUME; int hfVol = 0; if (Flags.headsetClientAmHfVolumeSymmetric()) { - hfVol = (int) Math.round((amVol - sMinAmVcVol) * ((double) hfRange / amRange)) + hfVol = + (int) Math.round((amVol - sMinAmVcVol) * ((double) hfRange / amRange)) + MIN_HFP_SCO_VOICE_CALL_VOLUME; } else { int hfOffset = (hfRange * (amVol - sMinAmVcVol)) / amRange; @@ -1054,14 +1079,21 @@ public class HeadsetClientStateMachine extends StateMachine { removeMessages(QUERY_CURRENT_CALLS); if (mPrevState == mConnecting) { - broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_DISCONNECTED, + broadcastConnectionState( + mCurrentDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); } else if (mPrevState == mConnected || mPrevState == mAudioOn) { - broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_DISCONNECTED, + broadcastConnectionState( + mCurrentDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); } else if (mPrevState != null) { // null is the default state before Disconnected - error("Disconnected: Illegal state transition from " + mPrevState.getName() - + " to Disconnected, mCurrentDevice=" + mCurrentDevice); + error( + "Disconnected: Illegal state transition from " + + mPrevState.getName() + + " to Disconnected, mCurrentDevice=" + + mCurrentDevice); } if (mHeadsetService != null && mCurrentDevice != null) { mHeadsetService.updateInbandRinging(mCurrentDevice, false); @@ -1083,7 +1115,9 @@ public class HeadsetClientStateMachine extends StateMachine { BluetoothDevice device = (BluetoothDevice) message.obj; if (!mNativeInterface.connect(device)) { // No state transition is involved, fire broadcast immediately - broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED, + broadcastConnectionState( + device, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED); break; } @@ -1098,8 +1132,11 @@ public class HeadsetClientStateMachine extends StateMachine { debug("Stack event type: " + event.type); switch (event.type) { case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: - debug("Disconnected: Connection " + event.device - + " state changed:" + event.valueInt); + debug( + "Disconnected: Connection " + + event.device + + " state changed:" + + event.valueInt); processConnectionEvent(event.valueInt, event.device); break; default: @@ -1123,15 +1160,19 @@ public class HeadsetClientStateMachine extends StateMachine { mCurrentDevice = device; transitionTo(mConnecting); } else { - info("Incoming AG rejected. connectionPolicy=" - + mService.getConnectionPolicy(device) + " bondState=" - + device.getBondState()); + info( + "Incoming AG rejected. connectionPolicy=" + + mService.getConnectionPolicy(device) + + " bondState=" + + device.getBondState()); // reject the connection and stay in Disconnected state // itself mNativeInterface.disconnect(device); // the other profile connection should be initiated // No state transition is involved, fire broadcast immediately - broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED, + broadcastConnectionState( + device, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED); } break; @@ -1160,12 +1201,16 @@ public class HeadsetClientStateMachine extends StateMachine { // the only transition is when connection attempt is initiated. sendMessageDelayed(CONNECTING_TIMEOUT, CONNECTING_TIMEOUT_MS); if (mPrevState == mDisconnected) { - broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTING, + broadcastConnectionState( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); } else { String prevStateName = mPrevState == null ? "null" : mPrevState.getName(); - error("Connecting: Illegal state transition from " + prevStateName - + " to Connecting"); + error( + "Connecting: Illegal state transition from " + + prevStateName + + " to Connecting"); } } @@ -1184,10 +1229,13 @@ public class HeadsetClientStateMachine extends StateMachine { debug("Connecting: event type: " + event.type); switch (event.type) { case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: - debug("Connecting: Connection " + event.device + " state changed:" - + event.valueInt); - processConnectionEvent(event.valueInt, event.valueInt2, event.valueInt3, - event.device); + debug( + "Connecting: Connection " + + event.device + + " state changed:" + + event.valueInt); + processConnectionEvent( + event.valueInt, event.valueInt2, event.valueInt3, event.device); break; case StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED: case StackEvent.EVENT_TYPE_NETWORK_STATE: @@ -1205,8 +1253,11 @@ public class HeadsetClientStateMachine extends StateMachine { deferMessage(message); break; case StackEvent.EVENT_TYPE_CMD_RESULT: - debug("Connecting: CMD_RESULT valueInt:" + event.valueInt - + " mQueuedActions.size=" + mQueuedActions.size()); + debug( + "Connecting: CMD_RESULT valueInt:" + + event.valueInt + + " mQueuedActions.size=" + + mQueuedActions.size()); if (!mQueuedActions.isEmpty()) { debug("queuedAction:" + mQueuedActions.peek().first); } @@ -1235,8 +1286,11 @@ public class HeadsetClientStateMachine extends StateMachine { && processAndroidSlcCommand(event.valueString, event.device)) { transitionTo(mConnected); } else { - error("Unknown event :" + event.valueString - + " for device " + event.device); + error( + "Unknown event :" + + event.valueString + + " for device " + + event.device); } break; @@ -1262,8 +1316,8 @@ public class HeadsetClientStateMachine extends StateMachine { } // in Connecting state - private void processConnectionEvent(int state, int peerFeat, int chldFeat, - BluetoothDevice device) { + private void processConnectionEvent( + int state, int peerFeat, int chldFeat, BluetoothDevice device) { switch (state) { case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED: transitionTo(mDisconnected); @@ -1282,11 +1336,14 @@ public class HeadsetClientStateMachine extends StateMachine { } // Send AT+NREC to remote if supported by audio - if (HeadsetClientHalConstants.HANDSFREECLIENT_NREC_SUPPORTED && ( - (mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECNR) + if (HeadsetClientHalConstants.HANDSFREECLIENT_NREC_SUPPORTED + && ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECNR) == HeadsetClientHalConstants.PEER_FEAT_ECNR)) { - if (mNativeInterface.sendATCmd(mCurrentDevice, - HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_NREC, 1, 0, + if (mNativeInterface.sendATCmd( + mCurrentDevice, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_NREC, + 1, + 0, null)) { addQueuedAction(DISABLE_NREC); } else { @@ -1299,8 +1356,11 @@ public class HeadsetClientStateMachine extends StateMachine { obtainMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, amVol, 0)); // Mic is either in ON state (full volume) or OFF state. There is no way in // Android to change the MIC volume. - deferMessage(obtainMessage(HeadsetClientStateMachine.SET_MIC_VOLUME, - mAudioManager.isMicrophoneMute() ? 0 : 15, 0)); + deferMessage( + obtainMessage( + HeadsetClientStateMachine.SET_MIC_VOLUME, + mAudioManager.isMicrophoneMute() ? 0 : 15, + 0)); // query subscriber info deferMessage(obtainMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO)); @@ -1314,10 +1374,13 @@ public class HeadsetClientStateMachine extends StateMachine { if (!mCurrentDevice.equals(device)) { warn("incoming connection event, device: " + device); // No state transition is involved, fire broadcast immediately - broadcastConnectionState(mCurrentDevice, + broadcastConnectionState( + mCurrentDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); - broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING, + broadcastConnectionState( + device, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); mCurrentDevice = device; @@ -1353,7 +1416,9 @@ public class HeadsetClientStateMachine extends StateMachine { mCommandedSpeakerVolume = -1; if (mPrevState == mConnecting) { - broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED, + broadcastConnectionState( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); if (mHeadsetService != null) { mHeadsetService.updateInbandRinging(mCurrentDevice, true); @@ -1362,8 +1427,10 @@ public class HeadsetClientStateMachine extends StateMachine { BluetoothMetricsProto.ProfileId.HEADSET_CLIENT); } else if (mPrevState != mAudioOn) { String prevStateName = mPrevState == null ? "null" : mPrevState.getName(); - error("Connected: Illegal state transition from " + prevStateName - + " to Connected"); + error( + "Connected: Illegal state transition from " + + prevStateName + + " to Connected"); } mService.updateBatteryLevel(); } @@ -1399,7 +1466,8 @@ public class HeadsetClientStateMachine extends StateMachine { if (!mNativeInterface.connectAudio(mCurrentDevice)) { error("ERROR: Couldn't connect Audio for device"); // No state transition is involved, fire broadcast immediately - broadcastAudioState(mCurrentDevice, + broadcastAudioState( + mCurrentDevice, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED); } else { // We have successfully sent a connect request! @@ -1433,28 +1501,31 @@ public class HeadsetClientStateMachine extends StateMachine { } break; - case SEND_VENDOR_AT_COMMAND: { - int vendorId = message.arg1; - String atCommand = (String) (message.obj); - mVendorProcessor.sendCommand(vendorId, atCommand, mCurrentDevice); - break; - } + case SEND_VENDOR_AT_COMMAND: + { + int vendorId = message.arg1; + String atCommand = (String) (message.obj); + mVendorProcessor.sendCommand(vendorId, atCommand, mCurrentDevice); + break; + } - case SEND_BIEV: { - if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_HF_IND) - == HeadsetClientHalConstants.PEER_FEAT_HF_IND) { - int indicatorID = message.arg1; - int value = message.arg2; - mNativeInterface.sendATCmd(mCurrentDevice, - HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_BIEV, - indicatorID, - value, - null); + case SEND_BIEV: + { + if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_HF_IND) + == HeadsetClientHalConstants.PEER_FEAT_HF_IND) { + int indicatorID = message.arg1; + int value = message.arg2; + mNativeInterface.sendATCmd( + mCurrentDevice, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_BIEV, + indicatorID, + value, + null); + } + break; } - break; - } - // Called only for Mute/Un-mute - Mic volume change is not allowed. + // Called only for Mute/Un-mute - Mic volume change is not allowed. case SET_MIC_VOLUME: break; case SET_SPEAKER_VOLUME: @@ -1465,8 +1536,8 @@ public class HeadsetClientStateMachine extends StateMachine { debug("Volume" + amVol + ":" + mCommandedSpeakerVolume); // Volume was changed by a 3rd party mCommandedSpeakerVolume = -1; - if (mNativeInterface.setVolume(mCurrentDevice, - HeadsetClientHalConstants.VOLUME_TYPE_SPK, hfVol)) { + if (mNativeInterface.setVolume( + mCurrentDevice, HeadsetClientHalConstants.VOLUME_TYPE_SPK, hfVol)) { addQueuedAction(SET_SPEAKER_VOLUME); } } @@ -1481,8 +1552,7 @@ public class HeadsetClientStateMachine extends StateMachine { // Start looping on calling current calls. sendMessage(QUERY_CURRENT_CALLS); } else { - Log.e(TAG, - "ERROR: Cannot dial with a given number:" + c.toString()); + Log.e(TAG, "ERROR: Cannot dial with a given number:" + c.toString()); // Set the call to terminated remove. c.setState(HfpClientCall.CALL_STATE_TERMINATED); sendCallChangedIntent(c); @@ -1508,8 +1578,7 @@ public class HeadsetClientStateMachine extends StateMachine { explicitCallTransfer(); break; case SEND_DTMF: - if (mNativeInterface.sendDtmf(mCurrentDevice, - (byte) message.arg1)) { + if (mNativeInterface.sendDtmf(mCurrentDevice, (byte) message.arg1)) { addQueuedAction(SEND_DTMF); } else { error("ERROR: Couldn't send DTMF"); @@ -1526,14 +1595,13 @@ public class HeadsetClientStateMachine extends StateMachine { removeMessages(QUERY_CURRENT_CALLS); debug("mClccPollDuringCall=" + mClccPollDuringCall); // If there are ongoing calls periodically check their status. - if (mCalls.size() > 1 - && mClccPollDuringCall) { - sendMessageDelayed(QUERY_CURRENT_CALLS, - mService.getResources().getInteger( - R.integer.hfp_clcc_poll_interval_during_call)); + if (mCalls.size() > 1 && mClccPollDuringCall) { + sendMessageDelayed( + QUERY_CURRENT_CALLS, + mService.getResources() + .getInteger(R.integer.hfp_clcc_poll_interval_during_call)); } else if (mCalls.size() > 0) { - sendMessageDelayed(QUERY_CURRENT_CALLS, - QUERY_CURRENT_CALLS_WAIT_MILLIS); + sendMessageDelayed(QUERY_CURRENT_CALLS, QUERY_CURRENT_CALLS_WAIT_MILLIS); } queryCallsStart(); break; @@ -1544,13 +1612,19 @@ public class HeadsetClientStateMachine extends StateMachine { switch (event.type) { case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: - debug("Connected: Connection state changed: " + event.device - + ": " + event.valueInt); + debug( + "Connected: Connection state changed: " + + event.device + + ": " + + event.valueInt); processConnectionEvent(event.valueInt, event.device); break; case StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED: - debug("Connected: Audio state changed: " + event.device + ": " - + event.valueInt); + debug( + "Connected: Audio state changed: " + + event.device + + ": " + + event.valueInt); processAudioEvent(event.valueInt, event.device); break; case StackEvent.EVENT_TYPE_NETWORK_STATE: @@ -1558,14 +1632,14 @@ public class HeadsetClientStateMachine extends StateMachine { mIndicatorNetworkState = event.valueInt; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); - intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS, - event.valueInt); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_NETWORK_STATUS, event.valueInt); if (mIndicatorNetworkState == HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE) { mOperatorName = null; - intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, - mOperatorName); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, mOperatorName); } intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); @@ -1588,8 +1662,8 @@ public class HeadsetClientStateMachine extends StateMachine { mIndicatorNetworkType = event.valueInt; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); - intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING, - event.valueInt); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING, event.valueInt); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast( intent, @@ -1601,7 +1675,8 @@ public class HeadsetClientStateMachine extends StateMachine { mIndicatorNetworkSignal = event.valueInt; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); - intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, + intent.putExtra( + BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, event.valueInt); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast( @@ -1615,8 +1690,8 @@ public class HeadsetClientStateMachine extends StateMachine { mService.handleBatteryLevelChanged(event.device, event.valueInt); intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); - intent.putExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, - event.valueInt); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, event.valueInt); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast( intent, @@ -1627,8 +1702,8 @@ public class HeadsetClientStateMachine extends StateMachine { mOperatorName = event.valueString; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); - intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, - event.valueString); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, event.valueString); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast( intent, @@ -1639,8 +1714,8 @@ public class HeadsetClientStateMachine extends StateMachine { case StackEvent.EVENT_TYPE_VR_STATE_CHANGED: int oldState = mVoiceRecognitionActive; mVoiceRecognitionActive = event.valueInt; - broadcastVoiceRecognitionStateChanged(event.device, oldState, - mVoiceRecognitionActive); + broadcastVoiceRecognitionStateChanged( + event.device, oldState, mVoiceRecognitionActive); break; case StackEvent.EVENT_TYPE_CALL: case StackEvent.EVENT_TYPE_CALLSETUP: @@ -1651,7 +1726,10 @@ public class HeadsetClientStateMachine extends StateMachine { sendMessage(QUERY_CURRENT_CALLS); break; case StackEvent.EVENT_TYPE_CURRENT_CALLS: - queryCallsUpdate(event.valueInt, event.valueInt3, event.valueString, + queryCallsUpdate( + event.valueInt, + event.valueInt3, + event.valueString, event.valueInt4 == HeadsetClientHalConstants.CALL_MPTY_TYPE_MULTI, event.valueInt2 @@ -1661,9 +1739,11 @@ public class HeadsetClientStateMachine extends StateMachine { if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_SPK) { mCommandedSpeakerVolume = hfToAmVol(event.valueInt2); debug("AM volume set to " + mCommandedSpeakerVolume); - boolean show_volume = SystemProperties - .getBoolean("bluetooth.hfp_volume_control.enabled", true); - mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, + boolean show_volume = + SystemProperties.getBoolean( + "bluetooth.hfp_volume_control.enabled", true); + mAudioManager.setStreamVolume( + AudioManager.STREAM_VOICE_CALL, +mCommandedSpeakerVolume, show_volume ? AudioManager.FLAG_SHOW_UI : 0); } else if (event.valueInt @@ -1679,8 +1759,11 @@ public class HeadsetClientStateMachine extends StateMachine { break; } - debug("Connected: command result: " + event.valueInt - + " queuedAction: " + queuedAction.first); + debug( + "Connected: command result: " + + event.valueInt + + " queuedAction: " + + queuedAction.first); switch (queuedAction.first) { case QUERY_CURRENT_CALLS: @@ -1691,8 +1774,8 @@ public class HeadsetClientStateMachine extends StateMachine { oldState = mVoiceRecognitionActive; mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STARTED; - broadcastVoiceRecognitionStateChanged(event.device, - oldState, mVoiceRecognitionActive); + broadcastVoiceRecognitionStateChanged( + event.device, oldState, mVoiceRecognitionActive); } break; case VOICE_RECOGNITION_STOP: @@ -1700,8 +1783,8 @@ public class HeadsetClientStateMachine extends StateMachine { oldState = mVoiceRecognitionActive; mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; - broadcastVoiceRecognitionStateChanged(event.device, - oldState, mVoiceRecognitionActive); + broadcastVoiceRecognitionStateChanged( + event.device, oldState, mVoiceRecognitionActive); } break; case SEND_ANDROID_AT_COMMAND: @@ -1715,8 +1798,8 @@ public class HeadsetClientStateMachine extends StateMachine { case StackEvent.EVENT_TYPE_SUBSCRIBER_INFO: mSubscriberInfo = event.valueString; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); - intent.putExtra(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO, - mSubscriberInfo); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO, mSubscriberInfo); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast( intent, @@ -1726,8 +1809,8 @@ public class HeadsetClientStateMachine extends StateMachine { case StackEvent.EVENT_TYPE_IN_BAND_RINGTONE: intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); mInBandRing = event.valueInt == IN_BAND_RING_ENABLED; - intent.putExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, - event.valueInt); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_IN_BAND_RING, event.valueInt); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast( intent, @@ -1742,8 +1825,11 @@ public class HeadsetClientStateMachine extends StateMachine { break; case StackEvent.EVENT_TYPE_UNKNOWN_EVENT: if (!mVendorProcessor.processEvent(event.valueString, event.device)) { - error("Unknown event :" + event.valueString - + " for device " + event.device); + error( + "Unknown event :" + + event.valueString + + " for device " + + event.device); } break; default: @@ -1758,8 +1844,8 @@ public class HeadsetClientStateMachine extends StateMachine { return HANDLED; } - private void broadcastVoiceRecognitionStateChanged(BluetoothDevice device, int oldState, - int newState) { + private void broadcastVoiceRecognitionStateChanged( + BluetoothDevice device, int oldState, int newState) { if (oldState == newState) { return; } @@ -1856,15 +1942,15 @@ public class HeadsetClientStateMachine extends StateMachine { case HeadsetClientHalConstants.AUDIO_STATE_CONNECTING: // No state transition is involved, fire broadcast immediately - broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_CONNECTING, - mAudioState); + broadcastAudioState( + device, BluetoothHeadsetClient.STATE_AUDIO_CONNECTING, mAudioState); mAudioState = BluetoothHeadsetClient.STATE_AUDIO_CONNECTING; break; case HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED: // No state transition is involved, fire broadcast immediately - broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, - mAudioState); + broadcastAudioState( + device, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, mAudioState); mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; break; @@ -1885,7 +1971,9 @@ public class HeadsetClientStateMachine extends StateMachine { @Override public void enter() { debug("Enter AudioOn: " + getCurrentMessage().what); - broadcastAudioState(mCurrentDevice, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED, + broadcastAudioState( + mCurrentDevice, + BluetoothHeadsetClient.STATE_AUDIO_CONNECTED, BluetoothHeadsetClient.STATE_AUDIO_CONNECTING); } @@ -1929,13 +2017,19 @@ public class HeadsetClientStateMachine extends StateMachine { debug("AudioOn: event type: " + event.type); switch (event.type) { case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: - debug("AudioOn connection state changed" + event.device + ": " - + event.valueInt); + debug( + "AudioOn connection state changed" + + event.device + + ": " + + event.valueInt); processConnectionEvent(event.valueInt, event.device); break; case StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED: - debug("AudioOn audio state changed" + event.device + ": " - + event.valueInt); + debug( + "AudioOn audio state changed" + + event.device + + ": " + + event.valueInt); processAudioEvent(event.valueInt, event.device); break; default: @@ -1953,8 +2047,8 @@ public class HeadsetClientStateMachine extends StateMachine { switch (state) { case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED: if (mCurrentDevice.equals(device)) { - processAudioEvent(HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED, - device); + processAudioEvent( + HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED, device); transitionTo(mDisconnected); } else { error("Disconnected from unknown device: " + device); @@ -1996,7 +2090,9 @@ public class HeadsetClientStateMachine extends StateMachine { public void exit() { debug("Exit AudioOn: " + getCurrentMessage().what); mPrevState = this; - broadcastAudioState(mCurrentDevice, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, + broadcastAudioState( + mCurrentDevice, + BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED); } } @@ -2059,7 +2155,8 @@ public class HeadsetClientStateMachine extends StateMachine { int indexUpperBucket = atString.indexOf("("); int indexLowerBucket = atString.indexOf(")"); - if (indexUpperBucket < 0 || indexLowerBucket < 0 + if (indexUpperBucket < 0 + || indexLowerBucket < 0 || indexUpperBucket >= indexLowerBucket) { break; } @@ -2080,8 +2177,10 @@ public class HeadsetClientStateMachine extends StateMachine { String featureId = args[0]; if (featureId.equals(BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID)) { - info("processAndroidAtFeature:" - + BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID + " supported"); + info( + "processAndroidAtFeature:" + + BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID + + " supported"); setAudioPolicyRemoteSupported(true); // Send default policies to the remote if it supports @@ -2131,8 +2230,8 @@ public class HeadsetClientStateMachine extends StateMachine { // add individual CHLD support extras if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) == HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) { - intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL, - true); + intent.putExtra( + BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL, true); } if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL) == HeadsetClientHalConstants.CHLD_FEAT_REL) { @@ -2153,7 +2252,8 @@ public class HeadsetClientStateMachine extends StateMachine { } } - mService.sendBroadcastMultiplePermissions(intent, + mService.sendBroadcastMultiplePermissions( + intent, new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}, Utils.getTempBroadcastOptions()); @@ -2194,8 +2294,8 @@ public class HeadsetClientStateMachine extends StateMachine { // it is likely that our SDP has not completed and peer is initiating // the // connection. Allow this connection, provided the device is bonded - if ((BluetoothProfile.CONNECTION_POLICY_FORBIDDEN < connectionPolicy) || ( - (BluetoothProfile.CONNECTION_POLICY_UNKNOWN == connectionPolicy) + if ((BluetoothProfile.CONNECTION_POLICY_FORBIDDEN < connectionPolicy) + || ((BluetoothProfile.CONNECTION_POLICY_UNKNOWN == connectionPolicy) && (device.getBondState() != BluetoothDevice.BOND_NONE))) { ret = true; } @@ -2274,13 +2374,13 @@ public class HeadsetClientStateMachine extends StateMachine { Log.e(TAG, "[" + mCurrentDevice + "]: " + message); } - public void setAudioRouteAllowed(boolean allowed) { mAudioRouteAllowed = allowed; - int establishPolicy = allowed - ? BluetoothSinkAudioPolicy.POLICY_ALLOWED : - BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED; + int establishPolicy = + allowed + ? BluetoothSinkAudioPolicy.POLICY_ALLOWED + : BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED; /* * Backward compatibility for mAudioRouteAllowed @@ -2304,8 +2404,10 @@ public class HeadsetClientStateMachine extends StateMachine { .setInBandRingtonePolicy(getInBandRingtonePolicyProperty()) .build()); } else { - setAudioPolicy(new BluetoothSinkAudioPolicy.Builder(mHsClientAudioPolicy) - .setCallEstablishPolicy(establishPolicy).build()); + setAudioPolicy( + new BluetoothSinkAudioPolicy.Builder(mHsClientAudioPolicy) + .setCallEstablishPolicy(establishPolicy) + .build()); } } @@ -2323,8 +2425,8 @@ public class HeadsetClientStateMachine extends StateMachine { } /** - * sets the {@link BluetoothSinkAudioPolicy} object device and send to the remote - * device using Android specific AT commands. + * sets the {@link BluetoothSinkAudioPolicy} object device and send to the remote device using + * Android specific AT commands. * * @param policies to be set policies */ @@ -2337,8 +2439,8 @@ public class HeadsetClientStateMachine extends StateMachine { return; } - if (!mNativeInterface.sendAndroidAt(mCurrentDevice, - "+ANDROID=" + createMaskString(policies))) { + if (!mNativeInterface.sendAndroidAt( + mCurrentDevice, "+ANDROID=" + createMaskString(policies))) { error("ERROR: Couldn't send call audio policies"); return; } @@ -2377,9 +2479,7 @@ public class HeadsetClientStateMachine extends StateMachine { return mAudioPolicyRemoteSupported; } - /** - * handles the value of {@link BluetoothSinkAudioPolicy} from system property - */ + /** handles the value of {@link BluetoothSinkAudioPolicy} from system property */ private int getAudioPolicySystemProp(String propKey) { int mProp = SystemProperties.getInt(propKey, BluetoothSinkAudioPolicy.POLICY_UNCONFIGURED); if (mProp < BluetoothSinkAudioPolicy.POLICY_UNCONFIGURED diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineFactory.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineFactory.java index b21f537677b..823b0f9a416 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineFactory.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineFactory.java @@ -22,13 +22,10 @@ import com.android.bluetooth.hfp.HeadsetService; // Factory so that StateMachine objected can be mocked public class HeadsetClientStateMachineFactory { - /** - * Factory method to create state machine for headset client - * - */ - public HeadsetClientStateMachine make(HeadsetClientService context, HandlerThread t, - NativeInterface nativeInterface) { - return HeadsetClientStateMachine.make(context, HeadsetService.getHeadsetService(), - t.getLooper(), nativeInterface); + /** Factory method to create state machine for headset client */ + public HeadsetClientStateMachine make( + HeadsetClientService context, HandlerThread t, NativeInterface nativeInterface) { + return HeadsetClientStateMachine.make( + context, HeadsetService.getHeadsetService(), t.getLooper(), nativeInterface); } } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientCall.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientCall.java index 58da4253ca6..de802b63a4b 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientCall.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientCall.java @@ -26,44 +26,37 @@ import java.util.UUID; /** * This class represents a single call, its state and properties. * - * HfpClientCall is Parcelable so it can be passed through the TelecomManager Connection Service + *

HfpClientCall is Parcelable so it can be passed through the TelecomManager Connection Service * framework. */ public final class HfpClientCall implements Parcelable { /* Call state */ - /** - * Call is active. - */ + /** Call is active. */ public static final int CALL_STATE_ACTIVE = 0; - /** - * Call is in held state. - */ + + /** Call is in held state. */ public static final int CALL_STATE_HELD = 1; - /** - * Outgoing call that is being dialed right now. - */ + + /** Outgoing call that is being dialed right now. */ public static final int CALL_STATE_DIALING = 2; - /** - * Outgoing call that remote party has already been alerted about. - */ + + /** Outgoing call that remote party has already been alerted about. */ public static final int CALL_STATE_ALERTING = 3; - /** - * Incoming call that can be accepted or rejected. - */ + + /** Incoming call that can be accepted or rejected. */ public static final int CALL_STATE_INCOMING = 4; - /** - * Waiting call state when there is already an active call. - */ + + /** Waiting call state when there is already an active call. */ public static final int CALL_STATE_WAITING = 5; + /** - * Call that has been held by response and hold - * (see Bluetooth specification for further references). + * Call that has been held by response and hold (see Bluetooth specification for further + * references). */ public static final int CALL_STATE_HELD_BY_RESPONSE_AND_HOLD = 6; - /** - * Call that has been already terminated and should not be referenced as a valid call. - */ + + /** Call that has been already terminated and should not be referenced as a valid call. */ public static final int CALL_STATE_TERMINATED = 7; private final BluetoothDevice mDevice; @@ -76,16 +69,27 @@ public final class HfpClientCall implements Parcelable { private final long mCreationElapsedMilli; private final boolean mInBandRing; - /** - * Creates HfpClientCall instance. - */ - public HfpClientCall(BluetoothDevice device, int id, int state, String number, - boolean multiParty, boolean outgoing, boolean inBandRing) { + /** Creates HfpClientCall instance. */ + public HfpClientCall( + BluetoothDevice device, + int id, + int state, + String number, + boolean multiParty, + boolean outgoing, + boolean inBandRing) { this(device, id, UUID.randomUUID(), state, number, multiParty, outgoing, inBandRing); } - private HfpClientCall(BluetoothDevice device, int id, UUID uuid, int state, - String number, boolean multiParty, boolean outgoing, boolean inBandRing) { + private HfpClientCall( + BluetoothDevice device, + int id, + UUID uuid, + int state, + String number, + boolean multiParty, + boolean outgoing, + boolean inBandRing) { mDevice = device; mId = id; mUUID = uuid; @@ -100,7 +104,7 @@ public final class HfpClientCall implements Parcelable { /** * Sets call's state. * - *

Note: This is an internal function and shouldn't be exposed

+ *

Note: This is an internal function and shouldn't be exposed * * @param state new call state. */ @@ -111,7 +115,7 @@ public final class HfpClientCall implements Parcelable { /** * Sets call's number. * - *

Note: This is an internal function and shouldn't be exposed

+ *

Note: This is an internal function and shouldn't be exposed * * @param number String representing phone number. */ @@ -122,7 +126,7 @@ public final class HfpClientCall implements Parcelable { /** * Sets this call as multi party call. * - *

Note: This is an internal function and shouldn't be exposed

+ *

Note: This is an internal function and shouldn't be exposed * * @param multiParty if true sets this call as a part of multi party conference. */ @@ -213,6 +217,7 @@ public final class HfpClientCall implements Parcelable { /** * Generate a log string for this call + * * @return log string */ @Override @@ -265,16 +270,19 @@ public final class HfpClientCall implements Parcelable { return builder.toString(); } - /** - * {@link Parcelable.Creator} interface implementation. - */ + /** {@link Parcelable.Creator} interface implementation. */ public static final @android.annotation.NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public HfpClientCall createFromParcel(Parcel in) { - return new HfpClientCall((BluetoothDevice) in.readParcelable(null), - in.readInt(), UUID.fromString(in.readString()), in.readInt(), - in.readString(), in.readInt() == 1, in.readInt() == 1, + return new HfpClientCall( + (BluetoothDevice) in.readParcelable(null), + in.readInt(), + UUID.fromString(in.readString()), + in.readInt(), + in.readString(), + in.readInt() == 1, + in.readInt() == 1, in.readInt() == 1); } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConference.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConference.java index 70c3b14a519..7d49d2254f2 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConference.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConference.java @@ -27,15 +27,18 @@ public class HfpClientConference extends Conference { private final BluetoothDevice mDevice; private final HeadsetClientServiceInterface mServiceInterface; - public HfpClientConference(BluetoothDevice device, PhoneAccountHandle handle, + public HfpClientConference( + BluetoothDevice device, + PhoneAccountHandle handle, HeadsetClientServiceInterface serviceInterface) { super(handle); mDevice = device; mServiceInterface = serviceInterface; boolean manage = mServiceInterface.hasHfpClientEcc(device); setConnectionCapabilities( - Connection.CAPABILITY_SUPPORT_HOLD | Connection.CAPABILITY_HOLD | (manage - ? Connection.CAPABILITY_MANAGE_CONFERENCE : 0)); + Connection.CAPABILITY_SUPPORT_HOLD + | Connection.CAPABILITY_HOLD + | (manage ? Connection.CAPABILITY_MANAGE_CONFERENCE : 0)); setActive(); } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java index 78855e12efe..66d323a04c0 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java @@ -32,7 +32,7 @@ public class HfpClientConnection extends Connection { private static final String EVENT_SCO_CONNECT = "com.android.bluetooth.hfpclient.SCO_CONNECT"; private static final String EVENT_SCO_DISCONNECT = - "com.android.bluetooth.hfpclient.SCO_DISCONNECT"; + "com.android.bluetooth.hfpclient.SCO_DISCONNECT"; private final BluetoothDevice mDevice; private HfpClientCall mCurrentCall; @@ -47,8 +47,11 @@ public class HfpClientConnection extends Connection { // Constructor to be used when there's an existing call (such as that created on the AG or // when connection happens and we see calls for the first time). - public HfpClientConnection(BluetoothDevice device, HfpClientCall call, - HfpClientConnectionService connServ, HeadsetClientServiceInterface serviceInterface) { + public HfpClientConnection( + BluetoothDevice device, + HfpClientCall call, + HfpClientConnectionService connServ, + HeadsetClientServiceInterface serviceInterface) { mDevice = device; mConnServ = connServ; mServiceInterface = serviceInterface; @@ -60,8 +63,11 @@ public class HfpClientConnection extends Connection { // Constructor to be used when a call is intiated on the HF. The call handle is obtained by // using the dial() command. - public HfpClientConnection(BluetoothDevice device, Uri number, - HfpClientConnectionService connServ, HeadsetClientServiceInterface serviceInterface) { + public HfpClientConnection( + BluetoothDevice device, + Uri number, + HfpClientConnectionService connServ, + HeadsetClientServiceInterface serviceInterface) { mDevice = device; mConnServ = connServ; mServiceInterface = serviceInterface; @@ -82,9 +88,12 @@ public class HfpClientConnection extends Connection { Uri number = Uri.fromParts(PhoneAccount.SCHEME_TEL, mCurrentCall.getNumber(), null); setAddress(number, TelecomManager.PRESENTATION_ALLOWED); setConnectionCapabilities( - CAPABILITY_SUPPORT_HOLD | CAPABILITY_MUTE | CAPABILITY_SEPARATE_FROM_CONFERENCE - | CAPABILITY_DISCONNECT_FROM_CONFERENCE | ( - getState() == STATE_ACTIVE || getState() == STATE_HOLDING ? CAPABILITY_HOLD + CAPABILITY_SUPPORT_HOLD + | CAPABILITY_MUTE + | CAPABILITY_SEPARATE_FROM_CONFERENCE + | CAPABILITY_DISCONNECT_FROM_CONFERENCE + | (getState() == STATE_ACTIVE || getState() == STATE_HOLDING + ? CAPABILITY_HOLD : 0)); } @@ -105,7 +114,9 @@ public class HfpClientConnection extends Connection { } public boolean inConference() { - return mAdded && mCurrentCall != null && mCurrentCall.isMultiParty() + return mAdded + && mCurrentCall != null + && mCurrentCall.isMultiParty() && getState() != Connection.STATE_DISCONNECTED; } @@ -275,8 +286,13 @@ public class HfpClientConnection extends Connection { @Override public String toString() { - return "HfpClientConnection{" + getAddress() + "," + stateToString(getState()) + "," - + mCurrentCall + "}"; + return "HfpClientConnection{" + + getAddress() + + "," + + stateToString(getState()) + + "," + + mCurrentCall + + "}"; } private void debug(String message) { diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java index 5f079ccd11c..51b25336540 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java @@ -52,9 +52,9 @@ public class HfpClientConnectionService extends ConnectionService { private final Map mDeviceBlocks = new HashMap<>(); - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // SINGLETON MANAGEMENT // - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// private static final Object INSTANCE_LOCK = new Object(); private static HfpClientConnectionService sHfpClientConnectionService; @@ -79,15 +79,13 @@ public class HfpClientConnectionService extends ConnectionService { } } - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // MESSAGES FROM HEADSET CLIENT SERVICE // - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// - /** - * Send a device connection state changed event to this service - */ - public static void onConnectionStateChanged(BluetoothDevice device, int newState, - int oldState) { + /** Send a device connection state changed event to this service */ + public static void onConnectionStateChanged( + BluetoothDevice device, int newState, int oldState) { HfpClientConnectionService service = getInstance(); if (service == null) { Log.e(TAG, "onConnectionStateChanged: HFP Client Connection Service not started"); @@ -96,9 +94,7 @@ public class HfpClientConnectionService extends ConnectionService { service.onConnectionStateChangedInternal(device, newState, oldState); } - /** - * Send a device call state changed event to this service - */ + /** Send a device call state changed event to this service */ public static void onCallChanged(BluetoothDevice device, HfpClientCall call) { HfpClientConnectionService service = getInstance(); if (service == null) { @@ -108,9 +104,7 @@ public class HfpClientConnectionService extends ConnectionService { service.onCallChangedInternal(device, call); } - /** - * Send a device audio state changed event to this service - */ + /** Send a device audio state changed event to this service */ public static void onAudioStateChanged(BluetoothDevice device, int newState, int oldState) { HfpClientConnectionService service = getInstance(); if (service == null) { @@ -120,12 +114,12 @@ public class HfpClientConnectionService extends ConnectionService { service.onAudioStateChangedInternal(device, newState, oldState); } - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // HANDLE MESSAGES FROM HEADSET CLIENT SERVICE // - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// - private void onConnectionStateChangedInternal(BluetoothDevice device, int newState, - int oldState) { + private void onConnectionStateChangedInternal( + BluetoothDevice device, int newState, int oldState) { if (newState == BluetoothProfile.STATE_CONNECTED) { Log.d(TAG, "Established connection with " + device); @@ -185,9 +179,9 @@ public class HfpClientConnectionService extends ConnectionService { block.onAudioStateChange(newState, oldState); } - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // SERVICE SETUP AND TEAR DOWN // - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// @Override public void onCreate() { @@ -219,7 +213,8 @@ public class HfpClientConnectionService extends ConnectionService { private synchronized void disconnectAll() { for (Iterator> it = - mDeviceBlocks.entrySet().iterator(); it.hasNext(); ) { + mDeviceBlocks.entrySet().iterator(); + it.hasNext(); ) { it.next().getValue().cleanup(); it.remove(); } @@ -231,8 +226,8 @@ public class HfpClientConnectionService extends ConnectionService { // In order to make sure that the service is sticky (recovers from errors when HFP // connection is still active) and to stop it we need a special intent since stopService // only recreates it. - if (intent != null && intent.getBooleanExtra(HeadsetClientService.HFP_CLIENT_STOP_TAG, - false)) { + if (intent != null + && intent.getBooleanExtra(HeadsetClientService.HFP_CLIENT_STOP_TAG, false)) { // Stop the service. stopSelf(); return 0; @@ -240,16 +235,15 @@ public class HfpClientConnectionService extends ConnectionService { return START_STICKY; } - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // TELECOM CONNECTION SERVICE FUNCTIONS // - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // This method is called whenever there is a new incoming call (or right after BT connection). @Override - public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerAccount, - ConnectionRequest request) { - Log.d(TAG, - "onCreateIncomingConnection " + connectionManagerAccount + " req: " + request); + public Connection onCreateIncomingConnection( + PhoneAccountHandle connectionManagerAccount, ConnectionRequest request) { + Log.d(TAG, "onCreateIncomingConnection " + connectionManagerAccount + " req: " + request); HfpClientDeviceBlock block = findBlockForHandle(connectionManagerAccount); if (block == null) { @@ -267,8 +261,8 @@ public class HfpClientConnectionService extends ConnectionService { // This method is called *only if* Dialer UI is used to place an outgoing call. @Override - public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerAccount, - ConnectionRequest request) { + public Connection onCreateOutgoingConnection( + PhoneAccountHandle connectionManagerAccount, ConnectionRequest request) { Log.d(TAG, "onCreateOutgoingConnection " + connectionManagerAccount); HfpClientDeviceBlock block = findBlockForHandle(connectionManagerAccount); if (block == null) { @@ -283,8 +277,8 @@ public class HfpClientConnectionService extends ConnectionService { // 1. Outgoing call created from the AG. // 2. Call transfer from AG -> HF (on connection when existed call present). @Override - public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerAccount, - ConnectionRequest request) { + public Connection onCreateUnknownConnection( + PhoneAccountHandle connectionManagerAccount, ConnectionRequest request) { Log.d(TAG, "onCreateUnknownConnection " + connectionManagerAccount); HfpClientDeviceBlock block = findBlockForHandle(connectionManagerAccount); if (block == null) { @@ -308,9 +302,17 @@ public class HfpClientConnectionService extends ConnectionService { BluetoothDevice bd2 = ((HfpClientConnection) connection2).getDevice(); // We can only conference two connections on same device if (!Objects.equals(bd1, bd2)) { - Log.e(TAG, - "Cannot conference calls from two different devices " + "bd1 " + bd1 + " bd2 " - + bd2 + " conn1 " + connection1 + "connection2 " + connection2); + Log.e( + TAG, + "Cannot conference calls from two different devices " + + "bd1 " + + bd1 + + " bd2 " + + bd2 + + " conn1 " + + connection1 + + "connection2 " + + connection2); return; } @@ -318,9 +320,9 @@ public class HfpClientConnectionService extends ConnectionService { block.onConference(connection1, connection2); } - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// // DEVICE MANAGEMENT // - //--------------------------------------------------------------------------------------------// + // --------------------------------------------------------------------------------------------// private BluetoothDevice getDevice(PhoneAccountHandle handle) { BluetoothAdapter adapter = getSystemService(BluetoothManager.class).getAdapter(); @@ -360,19 +362,23 @@ public class HfpClientConnectionService extends ConnectionService { PhoneAccount createAccount(BluetoothDevice device) { Uri addr = Uri.fromParts(HfpClientConnectionService.HFP_SCHEME, device.getAddress(), null); PhoneAccountHandle handle = - new PhoneAccountHandle(new ComponentName(this, HfpClientConnectionService.class), + new PhoneAccountHandle( + new ComponentName(this, HfpClientConnectionService.class), device.getAddress()); int capabilities = PhoneAccount.CAPABILITY_CALL_PROVIDER; - if (getApplicationContext().getResources().getBoolean( - com.android.bluetooth.R.bool - .hfp_client_connection_service_support_emergency_call)) { + if (getApplicationContext() + .getResources() + .getBoolean( + com.android.bluetooth.R.bool + .hfp_client_connection_service_support_emergency_call)) { // Need to have an emergency call capability to place emergency call capabilities |= PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS; } PhoneAccount account = - new PhoneAccount.Builder(handle, "HFP " + device.toString()).setAddress(addr) + new PhoneAccount.Builder(handle, "HFP " + device.toString()) + .setAddress(addr) .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL)) .setCapabilities(capabilities) .build(); @@ -384,9 +390,7 @@ public class HfpClientConnectionService extends ConnectionService { return mDeviceBlocks; } - /** - * Dump the state of the HfpClientConnectionService and internal objects - */ + /** Dump the state of the HfpClientConnectionService and internal objects */ public static void dump(StringBuilder sb) { HfpClientConnectionService instance = getInstance(); sb.append(" HfpClientConnectionService:\n"); diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java index eba4f0cb8e8..96e9df29931 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java @@ -51,7 +51,9 @@ public class HfpClientDeviceBlock { private Bundle mScoState; private final HeadsetClientServiceInterface mServiceInterface; - HfpClientDeviceBlock(BluetoothDevice device, HfpClientConnectionService connServ, + HfpClientDeviceBlock( + BluetoothDevice device, + HfpClientConnectionService connServ, HeadsetClientServiceInterface serviceInterface) { mDevice = device; mConnServ = connServ; @@ -67,7 +69,6 @@ public class HfpClientDeviceBlock { mScoState = getScoStateFromDevice(device); debug("SCO state = " + mScoState); - List calls = mServiceInterface.getCurrentCalls(mDevice); debug("Got calls " + calls); if (calls == null) { @@ -140,8 +141,9 @@ public class HfpClientDeviceBlock { synchronized void onConference(Connection connection1, Connection connection2) { if (mConference == null) { - mConference = new HfpClientConference(mDevice, mPhoneAccount.getAccountHandle(), - mServiceInterface); + mConference = + new HfpClientConference( + mDevice, mPhoneAccount.getAccountHandle(), mServiceInterface); mConference.setExtras(mScoState); } @@ -196,14 +198,14 @@ public class HfpClientDeviceBlock { || call.getState() == HfpClientCall.CALL_STATE_HELD) { // This is an outgoing call. Even if it is an active call we do not have a way of // putting that parcelable in a seaprate field. - b.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); + b.putParcelable( + TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); mTelecomManager.addNewUnknownCall(mPhoneAccount.getAccountHandle(), b); } else if (call.getState() == HfpClientCall.CALL_STATE_INCOMING || call.getState() == HfpClientCall.CALL_STATE_WAITING) { // This is an incoming call. - b.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, - new ParcelUuid(call.getUUID())); + b.putParcelable( + TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, new ParcelUuid(call.getUUID())); b.putBoolean(TelecomManager.EXTRA_CALL_HAS_IN_BAND_RINGTONE, call.isInBandRing()); mTelecomManager.addNewIncomingCall(mPhoneAccount.getAccountHandle(), b); } @@ -235,18 +237,17 @@ public class HfpClientDeviceBlock { } } - private boolean isDisconnectingToActive(HfpClientConnection prevConn, - HfpClientCall newCall) { + private boolean isDisconnectingToActive(HfpClientConnection prevConn, HfpClientCall newCall) { debug("prevConn " + prevConn.isClosing() + " new call " + newCall.getState()); - if (prevConn.isClosing() && prevConn.getCall().getState() != newCall.getState() + if (prevConn.isClosing() + && prevConn.getCall().getState() != newCall.getState() && newCall.getState() != HfpClientCall.CALL_STATE_TERMINATED) { return true; } return false; } - private synchronized HfpClientConnection buildConnection(HfpClientCall call, - Uri number) { + private synchronized HfpClientConnection buildConnection(HfpClientCall call, Uri number) { if (call == null && number == null) { error("Both call and number cannot be null."); return null; @@ -254,9 +255,10 @@ public class HfpClientDeviceBlock { debug("Creating connection on " + mDevice + " for " + call + "/" + number); - HfpClientConnection connection = (call != null - ? new HfpClientConnection(mDevice, call, mConnServ, mServiceInterface) - : new HfpClientConnection(mDevice, number, mConnServ, mServiceInterface)); + HfpClientConnection connection = + (call != null + ? new HfpClientConnection(mDevice, call, mConnServ, mServiceInterface) + : new HfpClientConnection(mDevice, number, mConnServ, mServiceInterface)); connection.setExtras(mScoState); debug("Connection extras = " + connection.getExtras().toString()); @@ -291,8 +293,9 @@ public class HfpClientDeviceBlock { if (((HfpClientConnection) otherConn).inConference()) { // If this is the first connection with conference, create the conference first. if (mConference == null) { - mConference = new HfpClientConference(mDevice, mPhoneAccount.getAccountHandle(), - mServiceInterface); + mConference = + new HfpClientConference( + mDevice, mPhoneAccount.getAccountHandle(), mServiceInterface); mConference.setExtras(mScoState); } if (mConference.addConnection(otherConn)) { @@ -338,7 +341,7 @@ public class HfpClientDeviceBlock { sb.append(" account=" + mPhoneAccount); sb.append(" connections=["); boolean first = true; - for (HfpClientConnection connection : mConnections.values()) { + for (HfpClientConnection connection : mConnections.values()) { if (!first) { sb.append(", "); } @@ -351,9 +354,7 @@ public class HfpClientDeviceBlock { return sb.toString(); } - /** - * Factory class for {@link HfpClientDeviceBlock} - */ + /** Factory class for {@link HfpClientDeviceBlock} */ public static class Factory { private static Factory sInstance = new Factory(); @@ -362,21 +363,20 @@ public class HfpClientDeviceBlock { sInstance = instance; } - /** - * Returns an instance of {@link HfpClientDeviceBlock} - */ - public static HfpClientDeviceBlock build(BluetoothDevice device, + /** Returns an instance of {@link HfpClientDeviceBlock} */ + public static HfpClientDeviceBlock build( + BluetoothDevice device, HfpClientConnectionService connServ, HeadsetClientServiceInterface serviceInterface) { return sInstance.buildInternal(device, connServ, serviceInterface); } - protected HfpClientDeviceBlock buildInternal(BluetoothDevice device, + protected HfpClientDeviceBlock buildInternal( + BluetoothDevice device, HfpClientConnectionService connServ, HeadsetClientServiceInterface serviceInterface) { return new HfpClientDeviceBlock(device, connServ, serviceInterface); } - } // Per-Device logging diff --git a/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java b/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java index d51acc1b8b4..3044077b7d2 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java +++ b/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java @@ -32,9 +32,9 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; /** - * Defines native calls that are used by state machine/service to either send or receive - * messages to/from the native stack. This file is registered for the native methods in - * corresponding CPP file. + * Defines native calls that are used by state machine/service to either send or receive messages + * to/from the native stack. This file is registered for the native methods in corresponding CPP + * file. */ public class NativeInterface { private static final String TAG = NativeInterface.class.getSimpleName(); @@ -47,8 +47,10 @@ public class NativeInterface { private static final Object INSTANCE_LOCK = new Object(); private NativeInterface() { - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when NativeInterface init"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when NativeInterface init"); } /** @@ -74,17 +76,13 @@ public class NativeInterface { } // Native wrappers to help unit testing - /** - * Initialize native stack - */ + /** Initialize native stack */ @VisibleForTesting public void initialize() { initializeNative(); } - /** - * Close and clean up native stack - */ + /** Close and clean up native stack */ @VisibleForTesting public void cleanup() { cleanupNative(); @@ -159,9 +157,8 @@ public class NativeInterface { * Set volume to the specified paired device * * @param device target device - * @param volumeType type of volume as in - * HeadsetClientHalConstants.VOLUME_TYPE_xxxx - * @param volume volume level + * @param volumeType type of volume as in HeadsetClientHalConstants.VOLUME_TYPE_xxxx + * @param volume volume level * @return True on success, False on failure */ @VisibleForTesting @@ -173,7 +170,7 @@ public class NativeInterface { * dial number from the specified paired device * * @param device target device - * @param number phone number to be dialed + * @param number phone number to be dialed * @return True on success, False on failure */ @VisibleForTesting @@ -185,7 +182,7 @@ public class NativeInterface { * Memory dialing from the specified paired device * * @param device target device - * @param location memory location + * @param location memory location * @return True on success, False on failure */ @VisibleForTesting @@ -235,7 +232,7 @@ public class NativeInterface { * @return True on success, False on failure */ @VisibleForTesting - public boolean retrieveSubscriberInfo(BluetoothDevice device) { + public boolean retrieveSubscriberInfo(BluetoothDevice device) { return retrieveSubscriberInfoNative(getByteAddress(device)); } @@ -330,8 +327,8 @@ public class NativeInterface { private static native boolean requestLastVoiceTagNumberNative(byte[] address); - private static native boolean sendATCmdNative(byte[] address, int atCmd, int val1, int val2, - String arg); + private static native boolean sendATCmdNative( + byte[] address, int atCmd, int val1, int val2, String arg); private static native boolean sendAndroidAtNative(byte[] address, String cmd); @@ -377,8 +374,10 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, "onAudioStateChanged: Ignoring message because service not available: " - + event); + Log.w( + TAG, + "onAudioStateChanged: Ignoring message because service not available: " + + event); } } @@ -393,7 +392,8 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, + Log.w( + TAG, "onVrStateChanged: Ignoring message because service not available: " + event); } } @@ -409,7 +409,8 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, + Log.w( + TAG, "onNetworkStateChanged: Ignoring message because service not available: " + event); } @@ -425,7 +426,8 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, + Log.w( + TAG, "onNetworkRoaming: Ignoring message because service not available: " + event); } } @@ -468,7 +470,8 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, + Log.w( + TAG, "onCurrentOperator: Ignoring message because service not available: " + event); } } @@ -490,11 +493,8 @@ public class NativeInterface { /** * CIEV (Call indicators) notifying if call(s) are getting set up. * - * Values include: - * 0 - No current call is in setup - * 1 - Incoming call process ongoing - * 2 - Outgoing call process ongoing - * 3 - Remote party being alerted for outgoing call + *

Values include: 0 - No current call is in setup 1 - Incoming call process ongoing 2 - + * Outgoing call process ongoing 3 - Remote party being alerted for outgoing call */ @VisibleForTesting void onCallSetup(int callsetup, byte[] address) { @@ -514,11 +514,8 @@ public class NativeInterface { /** * CIEV (Call indicators) notifying call held states. * - * Values include: - * 0 - No calls held - * 1 - Call is placed on hold or active/held calls wapped (The AG has both an ACTIVE and HELD - * call) - * 2 - Call on hold, no active call + *

Values include: 0 - No calls held 1 - Call is placed on hold or active/held calls wapped + * (The AG has both an ACTIVE and HELD call) 2 - Call on hold, no active call */ @VisibleForTesting void onCallHeld(int callheld, byte[] address) { @@ -577,8 +574,7 @@ public class NativeInterface { } @VisibleForTesting - void onCurrentCalls(int index, int dir, int state, int mparty, String number, - byte[] address) { + void onCurrentCalls(int index, int dir, int state, int mparty, String number, byte[] address) { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CURRENT_CALLS); event.valueInt = index; event.valueInt2 = dir; @@ -636,7 +632,8 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, + Log.w( + TAG, "onSubscriberInfo: Ignoring message because service not available: " + event); } } @@ -651,8 +648,7 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, - "onInBandRing: Ignoring message because service not available: " + event); + Log.w(TAG, "onInBandRing: Ignoring message because service not available: " + event); } } @@ -670,7 +666,8 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, + Log.w( + TAG, "onRingIndication: Ignoring message because service not available: " + event); } } @@ -685,9 +682,7 @@ public class NativeInterface { if (service != null) { service.messageFromNative(event); } else { - Log.w(TAG, - "onUnknowEvent: Ignoring message because service not available: " + event); + Log.w(TAG, "onUnknowEvent: Ignoring message because service not available: " + event); } } - } diff --git a/android/app/src/com/android/bluetooth/hfpclient/StackEvent.java b/android/app/src/com/android/bluetooth/hfpclient/StackEvent.java index 0bac26dd58d..973f0e0c753 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/StackEvent.java +++ b/android/app/src/com/android/bluetooth/hfpclient/StackEvent.java @@ -131,4 +131,3 @@ public class StackEvent { } } } - diff --git a/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java b/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java index d850d007e0e..11e56b0c466 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java +++ b/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java @@ -43,35 +43,23 @@ class VendorCommandResponseProcessor { // Keys are AT commands (without payload), and values are the company IDs. private static final Map SUPPORTED_VENDOR_AT_COMMANDS; + static { SUPPORTED_VENDOR_AT_COMMANDS = new HashMap<>(); - SUPPORTED_VENDOR_AT_COMMANDS.put( - "+XAPL=", - BluetoothAssignedNumbers.APPLE); - SUPPORTED_VENDOR_AT_COMMANDS.put( - "+IPHONEACCEV=", - BluetoothAssignedNumbers.APPLE); - SUPPORTED_VENDOR_AT_COMMANDS.put( - "+APLSIRI?", - BluetoothAssignedNumbers.APPLE); - SUPPORTED_VENDOR_AT_COMMANDS.put( - "+APLEFM", - BluetoothAssignedNumbers.APPLE); + SUPPORTED_VENDOR_AT_COMMANDS.put("+XAPL=", BluetoothAssignedNumbers.APPLE); + SUPPORTED_VENDOR_AT_COMMANDS.put("+IPHONEACCEV=", BluetoothAssignedNumbers.APPLE); + SUPPORTED_VENDOR_AT_COMMANDS.put("+APLSIRI?", BluetoothAssignedNumbers.APPLE); + SUPPORTED_VENDOR_AT_COMMANDS.put("+APLEFM", BluetoothAssignedNumbers.APPLE); } // Keys are AT events (without payload), and values are the company IDs. private static final Map SUPPORTED_VENDOR_EVENTS; + static { SUPPORTED_VENDOR_EVENTS = new HashMap<>(); - SUPPORTED_VENDOR_EVENTS.put( - "+APLSIRI:", - BluetoothAssignedNumbers.APPLE); - SUPPORTED_VENDOR_EVENTS.put( - "+XAPL=", - BluetoothAssignedNumbers.APPLE); - SUPPORTED_VENDOR_EVENTS.put( - "+ANDROID:", - BluetoothAssignedNumbers.GOOGLE); + SUPPORTED_VENDOR_EVENTS.put("+APLSIRI:", BluetoothAssignedNumbers.APPLE); + SUPPORTED_VENDOR_EVENTS.put("+XAPL=", BluetoothAssignedNumbers.APPLE); + SUPPORTED_VENDOR_EVENTS.put("+ANDROID:", BluetoothAssignedNumbers.GOOGLE); } VendorCommandResponseProcessor(HeadsetClientService context, NativeInterface nativeInterface) { @@ -89,8 +77,7 @@ class VendorCommandResponseProcessor { // We simplify and say no ; allowed as well. int indexOfSemicolon = atCommand.indexOf(';'); if (indexOfSemicolon > 0) { - Log.e(TAG, "Do not support ; and more than one command:" - + atCommand); + Log.e(TAG, "Do not support ; and more than one command:" + atCommand); return false; } @@ -110,15 +97,16 @@ class VendorCommandResponseProcessor { commandWord = commandWord.replaceAll("\\s+", ""); if (!Objects.equals(SUPPORTED_VENDOR_AT_COMMANDS.get(commandWord), vendorId)) { - Log.e(TAG, "Invalid command " + atCommand + ", " + vendorId + ". Cand=" - + commandWord); + Log.e(TAG, "Invalid command " + atCommand + ", " + vendorId + ". Cand=" + commandWord); return false; } - if (!mNativeInterface.sendATCmd(device, - HeadsetClientHalConstants - .HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, - 0, 0, atCommand)) { + if (!mNativeInterface.sendATCmd( + device, + HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD, + 0, + 0, + atCommand)) { Log.e(TAG, "Failed to send vendor specific at command"); return false; } @@ -167,17 +155,25 @@ class VendorCommandResponseProcessor { return false; } else { broadcastVendorSpecificEventIntent(vendorId, eventCode, atString, device); - Log.d(TAG, "process vendor event " + vendorId + ", " + eventCode + ", " - + atString + " for device" + device); + Log.d( + TAG, + "process vendor event " + + vendorId + + ", " + + eventCode + + ", " + + atString + + " for device" + + device); } return true; } - private void broadcastVendorSpecificEventIntent(int vendorId, String vendorEventCode, - String vendorResponse, BluetoothDevice device) { + private void broadcastVendorSpecificEventIntent( + int vendorId, String vendorEventCode, String vendorResponse, BluetoothDevice device) { Log.d(TAG, "broadcastVendorSpecificEventIntent(" + vendorResponse + ")"); - Intent intent = new Intent(BluetoothHeadsetClient - .ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT); + Intent intent = + new Intent(BluetoothHeadsetClient.ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT); intent.putExtra(BluetoothHeadsetClient.EXTRA_VENDOR_ID, vendorId); intent.putExtra(BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_CODE, vendorEventCode); intent.putExtra(BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_FULL_ARGS, vendorResponse); diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java b/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java index d7e1ec5e09f..81a43d245d4 100644 --- a/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java +++ b/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java @@ -34,9 +34,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; -/** - * HID Device Native Interface to/from JNI. - */ +/** HID Device Native Interface to/from JNI. */ public class HidDeviceNativeInterface { private static final String TAG = "HidDeviceNativeInterface"; private BluetoothAdapter mAdapter; @@ -53,13 +51,13 @@ public class HidDeviceNativeInterface { if (mAdapter == null) { Log.wtf(TAG, "No Bluetooth Adapter Available"); } - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when HidDeviceNativeInterface init"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when HidDeviceNativeInterface init"); } - /** - * Get the singleton instance. - */ + /** Get the singleton instance. */ public static HidDeviceNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -77,16 +75,12 @@ public class HidDeviceNativeInterface { } } - /** - * Initializes the native interface. - */ + /** Initializes the native interface. */ public void init() { initNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ public void cleanup() { cleanupNative(); } @@ -103,8 +97,14 @@ public class HidDeviceNativeInterface { * @param outQos outgoing QoS settings * @return the result of the native call */ - public boolean registerApp(String name, String description, String provider, - byte subclass, byte[] descriptors, int[] inQos, int[] outQos) { + public boolean registerApp( + String name, + String description, + String provider, + byte subclass, + byte[] descriptors, + int[] inQos, + int[] outQos) { return registerAppNative(name, description, provider, subclass, descriptors, inQos, outQos); } @@ -184,8 +184,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onApplicationStateChangedFromNative(getDevice(address), registered); } else { - Log.wtf(TAG, "FATAL: onApplicationStateChanged() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onApplicationStateChanged() " + + "is called from the stack while service is not available."); } } @@ -195,8 +197,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onConnectStateChangedFromNative(getDevice(address), state); } else { - Log.wtf(TAG, "FATAL: onConnectStateChanged() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onConnectStateChanged() " + + "is called from the stack while service is not available."); } } @@ -206,8 +210,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onGetReportFromNative(type, id, bufferSize); } else { - Log.wtf(TAG, "FATAL: onGetReport() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onGetReport() " + + "is called from the stack while service is not available."); } } @@ -217,8 +223,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onSetReportFromNative(reportType, reportId, data); } else { - Log.wtf(TAG, "FATAL: onSetReport() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onSetReport() " + + "is called from the stack while service is not available."); } } @@ -228,8 +236,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onSetProtocolFromNative(protocol); } else { - Log.wtf(TAG, "FATAL: onSetProtocol() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onSetProtocol() " + + "is called from the stack while service is not available."); } } @@ -239,8 +249,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onInterruptDataFromNative(reportId, data); } else { - Log.wtf(TAG, "FATAL: onInterruptData() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onInterruptData() " + + "is called from the stack while service is not available."); } } @@ -250,8 +262,10 @@ public class HidDeviceNativeInterface { if (service != null) { service.onVirtualCableUnplugFromNative(); } else { - Log.wtf(TAG, "FATAL: onVirtualCableUnplug() " - + "is called from the stack while service is not available."); + Log.wtf( + TAG, + "FATAL: onVirtualCableUnplug() " + + "is called from the stack while service is not available."); } } @@ -274,8 +288,14 @@ public class HidDeviceNativeInterface { private native void cleanupNative(); - private native boolean registerAppNative(String name, String description, String provider, - byte subclass, byte[] descriptors, int[] inQos, int[] outQos); + private native boolean registerAppNative( + String name, + String description, + String provider, + byte subclass, + byte[] descriptors, + int[] inQos, + int[] outQos); private native boolean unregisterAppNative(); diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java index d2e922a04f9..9a23b493733 100644 --- a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java +++ b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java @@ -104,80 +104,83 @@ public class HidDeviceService extends ProfileService { Log.d(TAG, "handleMessage(): msg.what=" + msg.what); switch (msg.what) { - case MESSAGE_APPLICATION_STATE_CHANGED: { - BluetoothDevice device = msg.obj != null ? (BluetoothDevice) msg.obj : null; - boolean success = (msg.arg1 != 0); - - if (success) { - Log.d(TAG, "App registered, set device to: " + device); - mHidDevice = device; - } else { - mHidDevice = null; - } - - try { - if (mCallback != null) { - mCallback.onAppStatusChanged(device, success); + case MESSAGE_APPLICATION_STATE_CHANGED: + { + BluetoothDevice device = msg.obj != null ? (BluetoothDevice) msg.obj : null; + boolean success = (msg.arg1 != 0); + + if (success) { + Log.d(TAG, "App registered, set device to: " + device); + mHidDevice = device; } else { - break; + mHidDevice = null; } - } catch (RemoteException e) { - Log.e(TAG, "e=" + e.toString()); - e.printStackTrace(); - } - if (success) { - mDeathRcpt = new BluetoothHidDeviceDeathRecipient(HidDeviceService.this); - if (mCallback != null) { - IBinder binder = mCallback.asBinder(); - try { - binder.linkToDeath(mDeathRcpt, 0); - Log.i(TAG, "IBinder.linkToDeath() ok"); - } catch (RemoteException e) { - e.printStackTrace(); + try { + if (mCallback != null) { + mCallback.onAppStatusChanged(device, success); + } else { + break; } + } catch (RemoteException e) { + Log.e(TAG, "e=" + e.toString()); + e.printStackTrace(); } - } else if (mDeathRcpt != null) { - if (mCallback != null) { - IBinder binder = mCallback.asBinder(); - try { - binder.unlinkToDeath(mDeathRcpt, 0); - Log.i(TAG, "IBinder.unlinkToDeath() ok"); - } catch (NoSuchElementException e) { - e.printStackTrace(); + + if (success) { + mDeathRcpt = + new BluetoothHidDeviceDeathRecipient(HidDeviceService.this); + if (mCallback != null) { + IBinder binder = mCallback.asBinder(); + try { + binder.linkToDeath(mDeathRcpt, 0); + Log.i(TAG, "IBinder.linkToDeath() ok"); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } else if (mDeathRcpt != null) { + if (mCallback != null) { + IBinder binder = mCallback.asBinder(); + try { + binder.unlinkToDeath(mDeathRcpt, 0); + Log.i(TAG, "IBinder.unlinkToDeath() ok"); + } catch (NoSuchElementException e) { + e.printStackTrace(); + } + mDeathRcpt.cleanup(); + mDeathRcpt = null; } - mDeathRcpt.cleanup(); - mDeathRcpt = null; } - } - if (!success) { - mCallback = null; - } + if (!success) { + mCallback = null; + } - break; - } + break; + } - case MESSAGE_CONNECT_STATE_CHANGED: { - BluetoothDevice device = (BluetoothDevice) msg.obj; - int halState = msg.arg1; - int state = convertHalState(halState); + case MESSAGE_CONNECT_STATE_CHANGED: + { + BluetoothDevice device = (BluetoothDevice) msg.obj; + int halState = msg.arg1; + int state = convertHalState(halState); - if (state != BluetoothHidDevice.STATE_DISCONNECTED) { - mHidDevice = device; - } + if (state != BluetoothHidDevice.STATE_DISCONNECTED) { + mHidDevice = device; + } - setAndBroadcastConnectionState(device, state); + setAndBroadcastConnectionState(device, state); - try { - if (mCallback != null) { - mCallback.onConnectionStateChanged(device, state); + try { + if (mCallback != null) { + mCallback.onConnectionStateChanged(device, state); + } + } catch (RemoteException e) { + e.printStackTrace(); } - } catch (RemoteException e) { - e.printStackTrace(); + break; } - break; - } case MESSAGE_GET_REPORT: byte type = (byte) msg.arg1; @@ -193,20 +196,21 @@ public class HidDeviceService extends ProfileService { } break; - case MESSAGE_SET_REPORT: { - byte reportType = (byte) msg.arg1; - byte reportId = (byte) msg.arg2; - byte[] data = ((ByteBuffer) msg.obj).array(); + case MESSAGE_SET_REPORT: + { + byte reportType = (byte) msg.arg1; + byte reportId = (byte) msg.arg2; + byte[] data = ((ByteBuffer) msg.obj).array(); - try { - if (mCallback != null) { - mCallback.onSetReport(mHidDevice, reportType, reportId, data); + try { + if (mCallback != null) { + mCallback.onSetReport(mHidDevice, reportType, reportId, data); + } + } catch (RemoteException e) { + e.printStackTrace(); } - } catch (RemoteException e) { - e.printStackTrace(); + break; } - break; - } case MESSAGE_SET_PROTOCOL: byte protocol = (byte) msg.arg1; @@ -509,8 +513,10 @@ public class HidDeviceService extends ProfileService { return true; } - synchronized boolean registerApp(BluetoothHidDeviceAppSdpSettings sdp, - BluetoothHidDeviceAppQosSettings inQos, BluetoothHidDeviceAppQosSettings outQos, + synchronized boolean registerApp( + BluetoothHidDeviceAppSdpSettings sdp, + BluetoothHidDeviceAppQosSettings inQos, + BluetoothHidDeviceAppQosSettings outQos, IBluetoothHidDeviceCallback callback) { if (mUserUid != 0) { Log.w(TAG, "registerApp(): failed because another app is registered"); @@ -576,22 +582,23 @@ public class HidDeviceService extends ProfileService { synchronized boolean sendReport(BluetoothDevice device, int id, byte[] data) { Log.d(TAG, "sendReport(): device=" + device + " id=" + id); - return checkDevice(device) && checkCallingUid() + return checkDevice(device) + && checkCallingUid() && mHidDeviceNativeInterface.sendReport(id, data); } synchronized boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) { Log.d(TAG, "replyReport(): device=" + device + " type=" + type + " id=" + id); - return checkDevice(device) && checkCallingUid() + return checkDevice(device) + && checkCallingUid() && mHidDeviceNativeInterface.replyReport(type, id, data); } synchronized boolean unplug(BluetoothDevice device) { Log.d(TAG, "unplug(): device=" + device); - return checkDevice(device) && checkCallingUid() - && mHidDeviceNativeInterface.unplug(); + return checkDevice(device) && checkCallingUid() && mHidDeviceNativeInterface.unplug(); } /** @@ -625,14 +632,13 @@ public class HidDeviceService extends ProfileService { /** * Connects Hid Device if connectionPolicy is {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} - * and disconnects Hid device if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}. + * and disconnects Hid device if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}. * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy determines whether hid device should be connected or disconnected @@ -644,8 +650,8 @@ public class HidDeviceService extends ProfileService { BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HID_DEVICE, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HID_DEVICE, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { @@ -657,10 +663,9 @@ public class HidDeviceService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device @@ -672,14 +677,14 @@ public class HidDeviceService extends ProfileService { } enforceCallingOrSelfPermission( BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.HID_DEVICE); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HID_DEVICE); } synchronized boolean reportError(BluetoothDevice device, byte error) { Log.d(TAG, "reportError(): device=" + device + " error=" + error); - return checkDevice(device) && checkCallingUid() + return checkDevice(device) + && checkCallingUid() && mHidDeviceNativeInterface.reportError(error); } @@ -695,16 +700,18 @@ public class HidDeviceService extends ProfileService { public void start() { Log.d(TAG, "start()"); - mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), - "DatabaseManager cannot be null when HidDeviceService starts"); + mDatabaseManager = + Objects.requireNonNull( + AdapterService.getAdapterService().getDatabase(), + "DatabaseManager cannot be null when HidDeviceService starts"); mHandler = new HidDeviceServiceHandler(Looper.getMainLooper()); mHidDeviceNativeInterface = HidDeviceNativeInterface.getInstance(); mHidDeviceNativeInterface.init(); mNativeAvailable = true; mActivityManager = getSystemService(ActivityManager.class); - mActivityManager.addOnUidImportanceListener(mUidImportanceListener, - FOREGROUND_IMPORTANCE_CUTOFF); + mActivityManager.addOnUidImportanceListener( + mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF); setHidDeviceService(this); } @@ -727,6 +734,7 @@ public class HidDeviceService extends ProfileService { /** * Get the HID Device Service instance + * * @return HID Device Service instance */ public static synchronized HidDeviceService getHidDeviceService() { @@ -751,9 +759,9 @@ public class HidDeviceService extends ProfileService { * Gets the connections state for the hid device profile for the passed in device * * @param device is the device whose conenction state we want to verify - * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, - * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or - * {@link BluetoothProfile#STATE_DISCONNECTING} + * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, {@link + * BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or {@link + * BluetoothProfile#STATE_DISCONNECTING} */ public int getConnectionState(BluetoothDevice device) { if (mHidDevice != null && mHidDevice.equals(device)) { @@ -776,8 +784,8 @@ public class HidDeviceService extends ProfileService { return inputDevices; } - synchronized void onApplicationStateChangedFromNative(BluetoothDevice device, - boolean registered) { + synchronized void onApplicationStateChangedFromNative( + BluetoothDevice device, boolean registered) { Log.d(TAG, "onApplicationStateChanged(): registered=" + registered); Message msg = mHandler.obtainMessage(MESSAGE_APPLICATION_STATE_CHANGED); @@ -787,8 +795,7 @@ public class HidDeviceService extends ProfileService { } synchronized void onConnectStateChangedFromNative(BluetoothDevice device, int state) { - Log.d(TAG, "onConnectStateChanged(): device=" - + device + " state=" + state); + Log.d(TAG, "onConnectStateChanged(): device=" + device + " state=" + state); Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_STATE_CHANGED); msg.obj = device; @@ -845,8 +852,14 @@ public class HidDeviceService extends ProfileService { } private void setAndBroadcastConnectionState(BluetoothDevice device, int newState) { - Log.d(TAG, "setAndBroadcastConnectionState(): device=" + device - + " oldState=" + mHidDeviceState + " newState=" + newState); + Log.d( + TAG, + "setAndBroadcastConnectionState(): device=" + + device + + " oldState=" + + mHidDeviceState + + " newState=" + + newState); if (mHidDevice != null && !mHidDevice.equals(device)) { Log.w(TAG, "Connection state changed for unknown device, ignoring"); diff --git a/android/app/src/com/android/bluetooth/hid/HidHostService.java b/android/app/src/com/android/bluetooth/hid/HidHostService.java index 389aed59da8..1833de1b15c 100644 --- a/android/app/src/com/android/bluetooth/hid/HidHostService.java +++ b/android/app/src/com/android/bluetooth/hid/HidHostService.java @@ -57,10 +57,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -/** - * Provides Bluetooth Hid Host profile, as a service in - * the Bluetooth application. - */ +/** Provides Bluetooth Hid Host profile, as a service in the Bluetooth application. */ public class HidHostService extends ProfileService { private static final String TAG = HidHostService.class.getSimpleName(); @@ -991,10 +988,9 @@ public class HidHostService extends ProfileService { return service.getIdleTime(device); } } - ; - //APIs + // APIs /** * Connects the hid host profile for the passed in device @@ -1048,10 +1044,10 @@ public class HidHostService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { Log.d(TAG, "getConnectionState: device=" + device); @@ -1071,15 +1067,14 @@ public class HidHostService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -1088,8 +1083,8 @@ public class HidHostService extends ProfileService { public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { Log.d(TAG, "setConnectionPolicy: device=" + device); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HID_HOST, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HID_HOST, connectionPolicy)) { return false; } Log.d(TAG, "Saved connectionPolicy=" + connectionPolicy + " for device=" + device); @@ -1139,18 +1134,16 @@ public class HidHostService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { Log.d(TAG, "getConnectionPolicy: device=" + device); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.HID_HOST); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HID_HOST); } /** @@ -1241,10 +1234,7 @@ public class HidHostService extends ProfileService { if (!Flags.allowSwitchingHidAndHogp()) { return mNativeInterface.sendData( - getByteAddress(device), - getAddressType(device), - getTransport(device), - report); + getByteAddress(device), getAddressType(device), getTransport(device), report); } Message msg = mHandler.obtainMessage(MESSAGE_SEND_DATA, device); @@ -1473,8 +1463,8 @@ public class HidHostService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false diff --git a/android/app/src/com/android/bluetooth/le_audio/ContentControlIdKeeper.java b/android/app/src/com/android/bluetooth/le_audio/ContentControlIdKeeper.java index 23c08255648..920d6fde33c 100644 --- a/android/app/src/com/android/bluetooth/le_audio/ContentControlIdKeeper.java +++ b/android/app/src/com/android/bluetooth/le_audio/ContentControlIdKeeper.java @@ -32,9 +32,7 @@ import java.util.Objects; import java.util.SortedSet; import java.util.TreeSet; -/** - * This class keeps Content Control Ids for LE Audio profiles. - */ +/** This class keeps Content Control Ids for LE Audio profiles. */ public class ContentControlIdKeeper { private static final String TAG = "ContentControlIdKeeper"; @@ -54,9 +52,9 @@ public class ContentControlIdKeeper { } /** - * Functions is used to acquire Content Control ID (Ccid). Ccid is connected - * with a context type and the user uuid. In most of cases user uuid is the GATT service - * UUID which makes use of Ccid + * Functions is used to acquire Content Control ID (Ccid). Ccid is connected with a context type + * and the user uuid. In most of cases user uuid is the GATT service UUID which makes use of + * Ccid * * @param userUuid user identifier (GATT service) * @param contextType the context types as defined in {@link BluetoothLeAudio} @@ -92,7 +90,7 @@ public class ContentControlIdKeeper { } } - if (ccid != CCID_INVALID) { + if (ccid != CCID_INVALID) { sAssignedCcidList.add(ccid); sUuidToCcidContextPair.put(userUuid, new Pair(ccid, contextType)); diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterface.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterface.java index aa05e88624e..16803b0fd76 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterface.java @@ -31,9 +31,7 @@ import com.android.bluetooth.Utils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -/** - * LeAudio Native Interface to/from JNI. - */ +/** LeAudio Native Interface to/from JNI. */ public class LeAudioBroadcasterNativeInterface { private static final String TAG = "LeAudioBroadcasterNativeInterface"; private BluetoothAdapter mAdapter; @@ -50,9 +48,7 @@ public class LeAudioBroadcasterNativeInterface { } } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static LeAudioBroadcasterNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -138,24 +134,20 @@ public class LeAudioBroadcasterNativeInterface { /** * Initializes the native interface. * - * priorities to configure. + *

priorities to configure. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { initNative(); } - /** - * Stop the Broadcast Service. - */ + /** Stop the Broadcast Service. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void stop() { stopNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { cleanupNative(); @@ -170,15 +162,23 @@ public class LeAudioBroadcasterNativeInterface { * @param publicMetadata BIG public broadcast meta data * @param qualityArray BIG sub group audio quality array * @param metadataArray BIG sub group metadata array - * - * qualityArray and metadataArray use the same subgroup index + *

qualityArray and metadataArray use the same subgroup index */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public void createBroadcast(boolean isPublicBroadcast, String broadcastName, - byte[] broadcastCode, byte[] publicMetadata, int[] qualityArray, + public void createBroadcast( + boolean isPublicBroadcast, + String broadcastName, + byte[] broadcastCode, + byte[] publicMetadata, + int[] qualityArray, byte[][] metadataArray) { - createBroadcastNative(isPublicBroadcast, broadcastName, broadcastCode, publicMetadata, - qualityArray, metadataArray); + createBroadcastNative( + isPublicBroadcast, + broadcastName, + broadcastCode, + publicMetadata, + qualityArray, + metadataArray); } /** @@ -190,8 +190,8 @@ public class LeAudioBroadcasterNativeInterface { * @param metadataArray BIG sub group metadata array */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public void updateMetadata(int broadcastId, String broadcastName, - byte[] publicMetadata, byte[][] metadataArray) { + public void updateMetadata( + int broadcastId, String broadcastName, byte[] publicMetadata, byte[][] metadataArray) { updateMetadataNative(broadcastId, broadcastName, publicMetadata, metadataArray); } @@ -235,9 +235,7 @@ public class LeAudioBroadcasterNativeInterface { destroyBroadcastNative(broadcastId); } - /** - * Get all LeAudio Broadcast instance states. - */ + /** Get all LeAudio Broadcast instance states. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void getBroadcastMetadata(int broadcastId) { getBroadcastMetadataNative(broadcastId); @@ -245,16 +243,29 @@ public class LeAudioBroadcasterNativeInterface { // Native methods that call into the JNI interface private native void initNative(); + private native void stopNative(); + private native void cleanupNative(); - private native void createBroadcastNative(boolean isPublicBroadcast, String broadcastName, - byte[] broadcastCode, byte[] publicMetadata, int[] qualityArray, + + private native void createBroadcastNative( + boolean isPublicBroadcast, + String broadcastName, + byte[] broadcastCode, + byte[] publicMetadata, + int[] qualityArray, byte[][] metadataArray); - private native void updateMetadataNative(int broadcastId, String broadcastName, - byte[] publicMetadata, byte[][] metadataArray); + + private native void updateMetadataNative( + int broadcastId, String broadcastName, byte[] publicMetadata, byte[][] metadataArray); + private native void startBroadcastNative(int broadcastId); + private native void stopBroadcastNative(int broadcastId); + private native void pauseBroadcastNative(int broadcastId); + private native void destroyBroadcastNative(int broadcastId); + private native void getBroadcastMetadataNative(int broadcastId); } diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioCodecConfig.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioCodecConfig.java index de8a3d6edf5..b49a4992012 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioCodecConfig.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioCodecConfig.java @@ -41,14 +41,19 @@ class LeAudioCodecConfig { return; } - mCodecConfigOffloading = audioManager.getHwOffloadFormatsSupportedForLeAudio() - .toArray(mCodecConfigOffloading); + mCodecConfigOffloading = + audioManager + .getHwOffloadFormatsSupportedForLeAudio() + .toArray(mCodecConfigOffloading); Log.i(TAG, "mCodecConfigOffloading size for le -> " + mCodecConfigOffloading.length); for (int idx = 0; idx < mCodecConfigOffloading.length; idx++) { - Log.i(TAG, String.format("mCodecConfigOffloading[%d] -> %s", - idx, mCodecConfigOffloading[idx].toString())); + Log.i( + TAG, + String.format( + "mCodecConfigOffloading[%d] -> %s", + idx, mCodecConfigOffloading[idx].toString())); } } @@ -56,4 +61,3 @@ class LeAudioCodecConfig { return mCodecConfigOffloading; } } - diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java index c05e2490423..a501c6d8a76 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java @@ -33,9 +33,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; -/** - * LeAudio Native Interface to/from JNI. - */ +/** LeAudio Native Interface to/from JNI. */ public class LeAudioNativeInterface { private static final String TAG = LeAudioNativeInterface.class.getSimpleName(); @@ -53,9 +51,7 @@ public class LeAudioNativeInterface { } } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static LeAudioNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -139,8 +135,12 @@ public class LeAudioNativeInterface { } @VisibleForTesting - void onAudioConf(int direction, int groupId, int sinkAudioLocation, - int sourceAudioLocation, int availableContexts) { + void onAudioConf( + int direction, + int groupId, + int sinkAudioLocation, + int sourceAudioLocation, + int availableContexts) { LeAudioStackEvent event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); event.valueInt1 = direction; @@ -166,8 +166,8 @@ public class LeAudioNativeInterface { @VisibleForTesting void onAudioLocalCodecCapabilities( - BluetoothLeAudioCodecConfig[] localInputCodecCapabilities, - BluetoothLeAudioCodecConfig[] localOutputCodecCapabilities) { + BluetoothLeAudioCodecConfig[] localInputCodecCapabilities, + BluetoothLeAudioCodecConfig[] localOutputCodecCapabilities) { LeAudioStackEvent event = new LeAudioStackEvent( LeAudioStackEvent.EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED); @@ -261,15 +261,13 @@ public class LeAudioNativeInterface { /** * Initializes the native interface. * - * priorities to configure. + *

priorities to configure. */ public void init(BluetoothLeAudioCodecConfig[] codecConfigOffloading) { initNative(codecConfigOffloading); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ public void cleanup() { cleanupNative(); } @@ -307,15 +305,17 @@ public class LeAudioNativeInterface { /** * Add new Node into a group. + * * @param groupId group identifier * @param device remote device */ - public boolean groupAddNode(int groupId, BluetoothDevice device) { + public boolean groupAddNode(int groupId, BluetoothDevice device) { return groupAddNodeNative(groupId, getByteAddress(device)); } /** * Add new Node into a group. + * * @param groupId group identifier * @param device remote device */ @@ -325,6 +325,7 @@ public class LeAudioNativeInterface { /** * Set active group. + * * @param groupId group ID to set as active */ public void groupSetActive(int groupId) { @@ -333,11 +334,13 @@ public class LeAudioNativeInterface { /** * Set codec config preference. + * * @param groupId group ID for the preference * @param inputCodecConfig input codec configuration * @param outputCodecConfig output codec configuration */ - public void setCodecConfigPreference(int groupId, + public void setCodecConfigPreference( + int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig) { setCodecConfigPreferenceNative(groupId, inputCodecConfig, outputCodecConfig); @@ -345,6 +348,7 @@ public class LeAudioNativeInterface { /** * Set content control id (Ccid) along with context type. + * * @param ccid content control id * @param contextType assigned contextType */ @@ -355,6 +359,7 @@ public class LeAudioNativeInterface { /** * Set in call call flag. + * * @param inCall true when device in call (any state), false otherwise */ public void setInCall(boolean inCall) { @@ -366,8 +371,8 @@ public class LeAudioNativeInterface { * Set unicast monitor mode flag. * * @param direction direction for which monitor mode should be used - * @param enable true when LE Audio device should be listening for streaming status - * on direction stream. false otherwise + * @param enable true when LE Audio device should be listening for streaming status on direction + * stream. false otherwise */ public void setUnicastMonitorMode(int direction, boolean enable) { Log.d(TAG, "setUnicastMonitorMode enable: " + enable + ", direction : " + direction); @@ -381,13 +386,18 @@ public class LeAudioNativeInterface { * @param isOutputPreferenceLeAudio whether LEA is preferred for OUTPUT_ONLY * @param isDuplexPreferenceLeAudio whether LEA is preferred for DUPLEX */ - public void sendAudioProfilePreferences(int groupId, boolean isOutputPreferenceLeAudio, - boolean isDuplexPreferenceLeAudio) { - Log.d(TAG, "sendAudioProfilePreferences groupId=" + groupId - + ", isOutputPreferenceLeAudio=" + isOutputPreferenceLeAudio - + ", isDuplexPreferenceLeAudio=" + isDuplexPreferenceLeAudio); - sendAudioProfilePreferencesNative(groupId, isOutputPreferenceLeAudio, - isDuplexPreferenceLeAudio); + public void sendAudioProfilePreferences( + int groupId, boolean isOutputPreferenceLeAudio, boolean isDuplexPreferenceLeAudio) { + Log.d( + TAG, + "sendAudioProfilePreferences groupId=" + + groupId + + ", isOutputPreferenceLeAudio=" + + isOutputPreferenceLeAudio + + ", isDuplexPreferenceLeAudio=" + + isDuplexPreferenceLeAudio); + sendAudioProfilePreferencesNative( + groupId, isOutputPreferenceLeAudio, isDuplexPreferenceLeAudio); } /** @@ -412,24 +422,37 @@ public class LeAudioNativeInterface { // Native methods that call into the JNI interface private native void initNative(BluetoothLeAudioCodecConfig[] codecConfigOffloading); + private native void cleanupNative(); + private native boolean connectLeAudioNative(byte[] address); + private native boolean disconnectLeAudioNative(byte[] address); + private native boolean setEnableStateNative(byte[] address, boolean enabled); + private native boolean groupAddNodeNative(int groupId, byte[] address); + private native boolean groupRemoveNodeNative(int groupId, byte[] address); + private native void groupSetActiveNative(int groupId); - private native void setCodecConfigPreferenceNative(int groupId, + + private native void setCodecConfigPreferenceNative( + int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig); + private native void setCcidInformationNative(int ccid, int contextType); + private native void setInCallNative(boolean inCall); private native void setUnicastMonitorModeNative(int direction, boolean enable); + private native void confirmUnicastStreamRequestNative(); + /*package*/ - private native void sendAudioProfilePreferencesNative(int groupId, - boolean isOutputPreferenceLeAudio, boolean isDuplexPreferenceLeAudio); + private native void sendAudioProfilePreferencesNative( + int groupId, boolean isOutputPreferenceLeAudio, boolean isDuplexPreferenceLeAudio); private native void setGroupAllowedContextMaskNative( int groupId, int sinkContextTypes, int sourceContextTypes); diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioObjectsFactory.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioObjectsFactory.java index 5f0f8c03c47..a061fb6933e 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioObjectsFactory.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioObjectsFactory.java @@ -22,9 +22,7 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.internal.annotations.VisibleForTesting; -/** - * Factory class for object initialization to help with unit testing - */ +/** Factory class for object initialization to help with unit testing */ public class LeAudioObjectsFactory { private static final String TAG = LeAudioObjectsFactory.class.getSimpleName(); private static LeAudioObjectsFactory sInstance; diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java index 7f6eaf165dd..1c40b6c7fda 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -107,9 +107,7 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; -/** - * Provides Bluetooth LeAudio profile, as a service in the Bluetooth application. - */ +/** Provides Bluetooth LeAudio profile, as a service in the Bluetooth application. */ public class LeAudioService extends ProfileService { private static final String TAG = "LeAudioService"; @@ -118,19 +116,13 @@ public class LeAudioService extends ProfileService { private static LeAudioService sLeAudioService; - /** - * Indicates group audio support for none direction - */ + /** Indicates group audio support for none direction */ private static final int AUDIO_DIRECTION_NONE = 0x00; - /** - * Indicates group audio support for output direction - */ + /** Indicates group audio support for output direction */ private static final int AUDIO_DIRECTION_OUTPUT_BIT = 0x01; - /** - * Indicates group audio support for input direction - */ + /** Indicates group audio support for input direction */ private static final int AUDIO_DIRECTION_INPUT_BIT = 0x02; /** Indicates group is not active */ @@ -142,10 +134,7 @@ public class LeAudioService extends ProfileService { /** Indicates group is active */ private static final int ACTIVE_STATE_ACTIVE = 0x02; - /** - * This is used by application read-only for checking the fallback active group id. - * - */ + /** This is used by application read-only for checking the fallback active group id. */ public static final String BLUETOOTH_LE_BROADCAST_FALLBACK_ACTIVE_GROUP_ID = "bluetooth_le_broadcast_fallback_active_group_id"; @@ -195,8 +184,7 @@ public class LeAudioService extends ProfileService { LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface = null; private DialingOutTimeoutEvent mDialingOutTimeoutEvent = null; - @VisibleForTesting - AudioManager mAudioManager; + @VisibleForTesting AudioManager mAudioManager; LeAudioTmapGattServer mTmapGattServer; int mTmapRoleMask; int mUnicastGroupIdDeactivatedForBroadcastTransition = LE_AUDIO_GROUP_ID_INVALID; @@ -209,28 +197,21 @@ public class LeAudioService extends ProfileService { new LinkedList<>(); boolean mIsSourceStreamMonitorModeEnabled = false; - @VisibleForTesting - TbsService mTbsService; + @VisibleForTesting TbsService mTbsService; - @VisibleForTesting - McpService mMcpService; + @VisibleForTesting McpService mMcpService; - @VisibleForTesting - VolumeControlService mVolumeControlService; + @VisibleForTesting VolumeControlService mVolumeControlService; - @VisibleForTesting - HapClientService mHapClientService; + @VisibleForTesting HapClientService mHapClientService; - @VisibleForTesting - CsipSetCoordinatorService mCsipSetCoordinatorService; + @VisibleForTesting CsipSetCoordinatorService mCsipSetCoordinatorService; @VisibleForTesting BassClientService mBassClientService; - @VisibleForTesting - RemoteCallbackList mBroadcastCallbacks; + @VisibleForTesting RemoteCallbackList mBroadcastCallbacks; - @VisibleForTesting - RemoteCallbackList mLeAudioCallbacks; + @VisibleForTesting RemoteCallbackList mLeAudioCallbacks; BluetoothLeScanner mAudioServersScanner; /* When mScanCallback is not null, it means scan is started. */ @@ -438,20 +419,24 @@ public class LeAudioService extends ProfileService { throw new IllegalStateException("start() called twice"); } - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when LeAudioService starts"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when LeAudioService starts"); if (mLeAudioNativeInterface == null) { mLeAudioNativeInterface = Objects.requireNonNull( LeAudioNativeInterface.getInstance(), "LeAudioNativeInterface cannot be null when LeAudioService starts"); } - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when LeAudioService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when LeAudioService starts"); mAudioManager = getSystemService(AudioManager.class); - Objects.requireNonNull(mAudioManager, - "AudioManager cannot be null when LeAudioService starts"); + Objects.requireNonNull( + mAudioManager, "AudioManager cannot be null when LeAudioService starts"); // Start handler thread for state machines mStateMachinesThread = new HandlerThread("LeAudioService.StateMachines"); @@ -475,12 +460,15 @@ public class LeAudioService extends ProfileService { // Initialize Broadcast native interface if ((mAdapterService.getSupportedProfilesBitMask() - & (1 << BluetoothProfile.LE_AUDIO_BROADCAST)) != 0) { + & (1 << BluetoothProfile.LE_AUDIO_BROADCAST)) + != 0) { Log.i(TAG, "Init Le Audio broadcaster"); mBroadcastCallbacks = new RemoteCallbackList(); - mLeAudioBroadcasterNativeInterface = Objects.requireNonNull( - LeAudioBroadcasterNativeInterface.getInstance(), - "LeAudioBroadcasterNativeInterface cannot be null when LeAudioService starts"); + mLeAudioBroadcasterNativeInterface = + Objects.requireNonNull( + LeAudioBroadcasterNativeInterface.getInstance(), + "LeAudioBroadcasterNativeInterface cannot be null when LeAudioService" + + " starts"); mLeAudioBroadcasterNativeInterface.init(); mTmapRoleMask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_BMS; } else { @@ -490,10 +478,9 @@ public class LeAudioService extends ProfileService { mTmapStarted = registerTmap(); mLeAudioInbandRingtoneSupportedByPlatform = - BluetoothProperties.isLeAudioInbandRingtoneSupported().orElse(true); + BluetoothProperties.isLeAudioInbandRingtoneSupported().orElse(true); - mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, - mHandler); + mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler); // Mark service as started setLeAudioService(this); @@ -711,8 +698,8 @@ public class LeAudioService extends ProfileService { return volumeControlService.getAudioDeviceGroupVolume(groupId); } - LeAudioDeviceDescriptor createDeviceDescriptor(BluetoothDevice device, - boolean isInbandRingtoneEnabled) { + LeAudioDeviceDescriptor createDeviceDescriptor( + BluetoothDevice device, boolean isInbandRingtoneEnabled) { LeAudioDeviceDescriptor descriptor = mDeviceDescriptors.get(device); if (descriptor == null) { mDeviceDescriptors.put(device, new LeAudioDeviceDescriptor(isInbandRingtoneEnabled)); @@ -838,8 +825,7 @@ public class LeAudioService extends ProfileService { LeAudioStateMachine sm = descriptor.mStateMachine; if (sm == null) { - Log.e(TAG, "Ignored disconnect request for " + device - + " : no state machine"); + Log.e(TAG, "Ignored disconnect request for " + device + " : no state machine"); return false; } @@ -894,8 +880,11 @@ public class LeAudioService extends ProfileService { int connectionState = BluetoothProfile.STATE_DISCONNECTED; LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); if (descriptor == null) { - Log.e(TAG, "getDevicesMatchingConnectionStates: " - + "No valid descriptor for device: " + device); + Log.e( + TAG, + "getDevicesMatchingConnectionStates: " + + "No valid descriptor for device: " + + device); return null; } @@ -941,10 +930,10 @@ public class LeAudioService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { mGroupReadLock.lock(); @@ -966,6 +955,7 @@ public class LeAudioService extends ProfileService { /** * Add device to the given group. + * * @param groupId group ID the device is being added to * @param device the active device * @return true on success, otherwise false @@ -980,6 +970,7 @@ public class LeAudioService extends ProfileService { /** * Remove device from a given group. + * * @param groupId group ID the device is being removed from * @param device the active device * @return true on success, otherwise false @@ -1010,6 +1001,7 @@ public class LeAudioService extends ProfileService { /** * Get all the devices within a given group. + * * @param groupId group id to get devices * @return all devices within a given group or empty list */ @@ -1022,8 +1014,8 @@ public class LeAudioService extends ProfileService { mGroupReadLock.lock(); try { - for (Map.Entry entry - : mDeviceDescriptors.entrySet()) { + for (Map.Entry entry : + mDeviceDescriptors.entrySet()) { if (entry.getValue().mGroupId == groupId) { result.add(entry.getKey()); } @@ -1036,6 +1028,7 @@ public class LeAudioService extends ProfileService { /** * Get all the devices within a given group. + * * @param device the device for which we want to get all devices in its group * @return all devices within a given group or empty list */ @@ -1049,8 +1042,8 @@ public class LeAudioService extends ProfileService { mGroupReadLock.lock(); try { - for (Map.Entry entry - : mDeviceDescriptors.entrySet()) { + for (Map.Entry entry : + mDeviceDescriptors.entrySet()) { if (entry.getValue().mGroupId == groupId) { result.add(entry.getKey()); } @@ -1061,9 +1054,7 @@ public class LeAudioService extends ProfileService { return result; } - /** - * Get the active device group id - */ + /** Get the active device group id */ public Integer getActiveGroupId() { mGroupReadLock.lock(); try { @@ -1111,12 +1102,14 @@ public class LeAudioService extends ProfileService { if (!areAllGroupsInNotActiveState()) { /* Broadcast would be created once unicast group became inactive */ - Log.i(TAG, "Unicast group is active, queueing Broadcast creation, while the Unicast" - + " group is deactivated."); + Log.i( + TAG, + "Unicast group is active, queueing Broadcast creation, while the Unicast" + + " group is deactivated."); mCreateBroadcastQueue.add(broadcastSettings); if (Flags.leaudioBroadcastAudioHandoverPolicies()) { - mLeAudioNativeInterface.setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SINK, - true); + mLeAudioNativeInterface.setUnicastMonitorMode( + LeAudioStackEvent.DIRECTION_SINK, true); } removeActiveDevice(true); @@ -1193,6 +1186,7 @@ public class LeAudioService extends ProfileService { /** * Start LeAudio Broadcast instance. + * * @param broadcastId broadcast instance identifier */ public void startBroadcast(int broadcastId) { @@ -1244,7 +1238,8 @@ public class LeAudioService extends ProfileService { broadcastSettings.getPublicBroadcastMetadata(); Log.d(TAG, "updateBroadcast"); - mLeAudioBroadcasterNativeInterface.updateMetadata(broadcastId, + mLeAudioBroadcasterNativeInterface.updateMetadata( + broadcastId, broadcastSettings.getBroadcastName(), publicMetadata == null ? null : publicMetadata.getRawMetadata(), settingsList.stream() @@ -1288,6 +1283,7 @@ public class LeAudioService extends ProfileService { /** * Stop LeAudio Broadcast instance. + * * @param broadcastId broadcast instance identifier */ public void stopBroadcast(Integer broadcastId) { @@ -1312,6 +1308,7 @@ public class LeAudioService extends ProfileService { /** * Destroy LeAudio Broadcast instance. + * * @param broadcastId broadcast instance identifier */ public void destroyBroadcast(int broadcastId) { @@ -1339,6 +1336,7 @@ public class LeAudioService extends ProfileService { /** * Checks if Broadcast instance is playing. + * * @param broadcastId broadcast instance identifier * @return true if if broadcast is playing, false otherwise */ @@ -1354,6 +1352,7 @@ public class LeAudioService extends ProfileService { /** * Get all broadcast metadata. + * * @return list of all know Broadcast metadata */ public List getAllBroadcastMetadata() { @@ -1373,6 +1372,7 @@ public class LeAudioService extends ProfileService { /** * Get the maximum number of supported simultaneous broadcasts. + * * @return number of supported simultaneous broadcasts */ public int getMaximumNumberOfBroadcasts() { @@ -1400,9 +1400,7 @@ public class LeAudioService extends ProfileService { return 1; } - /** - * Active Broadcast Assistant notification handler - */ + /** Active Broadcast Assistant notification handler */ public void activeBroadcastAssistantNotification(boolean active) { if (getBassClientService() == null) { Log.w(TAG, "Ignore active Broadcast Assistant notification"); @@ -1411,12 +1409,11 @@ public class LeAudioService extends ProfileService { if (active) { mIsSourceStreamMonitorModeEnabled = true; - mLeAudioNativeInterface - .setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SOURCE, true); + mLeAudioNativeInterface.setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SOURCE, true); } else { if (mIsSourceStreamMonitorModeEnabled) { - mLeAudioNativeInterface - .setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SOURCE, false); + mLeAudioNativeInterface.setUnicastMonitorMode( + LeAudioStackEvent.DIRECTION_SOURCE, false); } mIsSourceStreamMonitorModeEnabled = false; @@ -1543,12 +1540,15 @@ public class LeAudioService extends ProfileService { return null; } - private boolean updateActiveInDevice(BluetoothDevice device, Integer groupId, - Integer oldSupportedAudioDirections, Integer newSupportedAudioDirections) { - boolean oldSupportedByDeviceInput = (oldSupportedAudioDirections - & AUDIO_DIRECTION_INPUT_BIT) != 0; - boolean newSupportedByDeviceInput = (newSupportedAudioDirections - & AUDIO_DIRECTION_INPUT_BIT) != 0; + private boolean updateActiveInDevice( + BluetoothDevice device, + Integer groupId, + Integer oldSupportedAudioDirections, + Integer newSupportedAudioDirections) { + boolean oldSupportedByDeviceInput = + (oldSupportedAudioDirections & AUDIO_DIRECTION_INPUT_BIT) != 0; + boolean newSupportedByDeviceInput = + (newSupportedAudioDirections & AUDIO_DIRECTION_INPUT_BIT) != 0; /* * Do not update input if neither previous nor current device support input @@ -1593,9 +1593,13 @@ public class LeAudioService extends ProfileService { if (!Objects.equals(device, previousInDevice) || (oldSupportedByDeviceInput != newSupportedByDeviceInput)) { mActiveAudioInDevice = newSupportedByDeviceInput ? device : null; - Log.d(TAG, " handleBluetoothActiveDeviceChanged previousInDevice: " - + previousInDevice + ", mActiveAudioInDevice: " + mActiveAudioInDevice - + " isLeOutput: false"); + Log.d( + TAG, + " handleBluetoothActiveDeviceChanged previousInDevice: " + + previousInDevice + + ", mActiveAudioInDevice: " + + mActiveAudioInDevice + + " isLeOutput: false"); return true; } @@ -1603,12 +1607,15 @@ public class LeAudioService extends ProfileService { return false; } - private boolean updateActiveOutDevice(BluetoothDevice device, Integer groupId, - Integer oldSupportedAudioDirections, Integer newSupportedAudioDirections) { - boolean oldSupportedByDeviceOutput = (oldSupportedAudioDirections - & AUDIO_DIRECTION_OUTPUT_BIT) != 0; - boolean newSupportedByDeviceOutput = (newSupportedAudioDirections - & AUDIO_DIRECTION_OUTPUT_BIT) != 0; + private boolean updateActiveOutDevice( + BluetoothDevice device, + Integer groupId, + Integer oldSupportedAudioDirections, + Integer newSupportedAudioDirections) { + boolean oldSupportedByDeviceOutput = + (oldSupportedAudioDirections & AUDIO_DIRECTION_OUTPUT_BIT) != 0; + boolean newSupportedByDeviceOutput = + (newSupportedAudioDirections & AUDIO_DIRECTION_OUTPUT_BIT) != 0; /* * Do not update output if neither previous nor current device support output @@ -1634,8 +1641,12 @@ public class LeAudioService extends ProfileService { device = mActiveAudioOutDevice; } } else if (deviceDescriptor.mGroupId != LE_AUDIO_GROUP_ID_INVALID) { - Log.i(TAG, " Switching active group from " + deviceDescriptor.mGroupId + " to " - + groupId); + Log.i( + TAG, + " Switching active group from " + + deviceDescriptor.mGroupId + + " to " + + groupId); /* Mark old group as no active */ LeAudioGroupDescriptor descriptor = getGroupDescriptor(deviceDescriptor.mGroupId); if (descriptor != null) { @@ -1655,9 +1666,13 @@ public class LeAudioService extends ProfileService { if (!Objects.equals(device, previousOutDevice) || (oldSupportedByDeviceOutput != newSupportedByDeviceOutput)) { mActiveAudioOutDevice = newSupportedByDeviceOutput ? device : null; - Log.d(TAG, " handleBluetoothActiveDeviceChanged previousOutDevice: " - + previousOutDevice + ", mActiveAudioOutDevice: " + mActiveAudioOutDevice - + " isLeOutput: true"); + Log.d( + TAG, + " handleBluetoothActiveDeviceChanged previousOutDevice: " + + previousOutDevice + + ", mActiveAudioOutDevice: " + + mActiveAudioOutDevice + + " isLeOutput: true"); return true; } Log.d(TAG, "updateActiveOutDevice: Nothing to do."); @@ -1725,14 +1740,17 @@ public class LeAudioService extends ProfileService { } /** - * Send broadcast intent about LeAudio active device. - * This is called when AudioManager confirms, LeAudio device - * is added or removed. + * Send broadcast intent about LeAudio active device. This is called when AudioManager confirms, + * LeAudio device is added or removed. */ @VisibleForTesting void notifyActiveDeviceChanged(BluetoothDevice device) { - Log.d(TAG, "Notify Active device changed." + device - + ". Currently active device is " + mActiveAudioOutDevice); + Log.d( + TAG, + "Notify Active device changed." + + device + + ". Currently active device is " + + mActiveAudioOutDevice); mAdapterService.handleActiveDeviceChange(BluetoothProfile.LE_AUDIO, device); sentActiveDeviceChangeIntent(device); @@ -1799,13 +1817,13 @@ public class LeAudioService extends ProfileService { @Override public void onScanFailed(int errorCode) { Log.w(TAG, "Scan failed err: " + errorCode + " scan retries: " + mScanRetries); - switch(errorCode) { + switch (errorCode) { case SCAN_FAILED_INTERNAL_ERROR: case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED: if (mScanRetries < mMaxScanRetires) { mScanRetries++; Log.w(TAG, "Failed to start. Let's retry"); - mHandler.post(() -> startAudioServersBackgroundScan(/* retry = */ true)); + mHandler.post(() -> startAudioServersBackgroundScan(/* retry= */ true)); } break; default: @@ -1884,7 +1902,7 @@ public class LeAudioService extends ProfileService { private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback { @Override public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { - if (mAudioManager == null || mAdapterService == null) { + if (mAudioManager == null || mAdapterService == null) { Log.e(TAG, "Callback called when LeAudioService is stopped"); return; } @@ -1963,7 +1981,8 @@ public class LeAudioService extends ProfileService { * descriptor was created - idicate that create notification was received. */ private boolean wasSetSinkListeningMode() { - return !mCreateBroadcastQueue.isEmpty() || mAwaitingBroadcastCreateResponse + return !mCreateBroadcastQueue.isEmpty() + || mAwaitingBroadcastCreateResponse || !mBroadcastDescriptors.isEmpty(); } @@ -2003,20 +2022,36 @@ public class LeAudioService extends ProfileService { && ((newSupportedAudioDirections & AUDIO_DIRECTION_INPUT_BIT) != 0)) { newInDevice = getLeadDeviceForTheGroup(groupId); } else if (Flags.leaudioBroadcastAudioHandoverPolicies() && wasSetSinkListeningMode()) { - mLeAudioNativeInterface.setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SINK, - false); + mLeAudioNativeInterface.setUnicastMonitorMode( + LeAudioStackEvent.DIRECTION_SINK, false); } } - boolean isNewActiveOutDevice = updateActiveOutDevice(newOutDevice, groupId, - oldSupportedAudioDirections, newSupportedAudioDirections); - boolean isNewActiveInDevice = updateActiveInDevice(newInDevice, groupId, - oldSupportedAudioDirections, newSupportedAudioDirections); + boolean isNewActiveOutDevice = + updateActiveOutDevice( + newOutDevice, + groupId, + oldSupportedAudioDirections, + newSupportedAudioDirections); + boolean isNewActiveInDevice = + updateActiveInDevice( + newInDevice, + groupId, + oldSupportedAudioDirections, + newSupportedAudioDirections); - Log.d(TAG, " isNewActiveOutDevice: " + isNewActiveOutDevice + ", " - + mActiveAudioOutDevice + ", isNewActiveInDevice: " + isNewActiveInDevice - + ", " + mActiveAudioInDevice + ", notifyAndUpdateInactiveOutDeviceOnly: " - + notifyAndUpdateInactiveOutDeviceOnly); + Log.d( + TAG, + " isNewActiveOutDevice: " + + isNewActiveOutDevice + + ", " + + mActiveAudioOutDevice + + ", isNewActiveInDevice: " + + isNewActiveInDevice + + ", " + + mActiveAudioInDevice + + ", notifyAndUpdateInactiveOutDeviceOnly: " + + notifyAndUpdateInactiveOutDeviceOnly); if (isNewActiveOutDevice) { int volume = IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME; @@ -2047,9 +2082,10 @@ public class LeAudioService extends ProfileService { } if (isNewActiveInDevice) { - mAudioManager.handleBluetoothActiveDeviceChanged(mActiveAudioInDevice, - previousActiveInDevice, BluetoothProfileConnectionInfo.createLeAudioInfo( - false, false)); + mAudioManager.handleBluetoothActiveDeviceChanged( + mActiveAudioInDevice, + previousActiveInDevice, + BluetoothProfileConnectionInfo.createLeAudioInfo(false, false)); } if ((mActiveAudioOutDevice == null) @@ -2190,8 +2226,8 @@ public class LeAudioService extends ProfileService { /** * Remove the current active group. * - * @param hasFallbackDevice whether any fallback device exists when deactivating - * the current active device. + * @param hasFallbackDevice whether any fallback device exists when deactivating the current + * active device. * @return true on success, otherwise false */ public boolean removeActiveDevice(boolean hasFallbackDevice) { @@ -2208,16 +2244,26 @@ public class LeAudioService extends ProfileService { * @return true on success, otherwise false */ public boolean setActiveDevice(BluetoothDevice device) { - Log.i(TAG, "setActiveDevice: device=" + device + ", current out=" - + mActiveAudioOutDevice + ", current in=" + mActiveAudioInDevice); + Log.i( + TAG, + "setActiveDevice: device=" + + device + + ", current out=" + + mActiveAudioOutDevice + + ", current in=" + + mActiveAudioInDevice); /* Clear active group */ if (device == null) { Log.e(TAG, "device should not be null!"); return removeActiveDevice(false); } if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) { - Log.e(TAG, "setActiveDevice(" + device + "): failed because group device is not " - + "connected"); + Log.e( + TAG, + "setActiveDevice(" + + device + + "): failed because group device is not " + + "connected"); return false; } @@ -2241,10 +2287,9 @@ public class LeAudioService extends ProfileService { /** * Get the active LE audio devices. * - * Note: When LE audio group is active, one of the Bluetooth device address - * which belongs to the group, represents the active LE audio group - it is called - * Lead device. - * Internally, this address is translated to LE audio group id. + *

Note: When LE audio group is active, one of the Bluetooth device address which belongs to + * the group, represents the active LE audio group - it is called Lead device. Internally, this + * address is translated to LE audio group id. * * @return List of active group members. First element is a Lead device. */ @@ -2292,8 +2337,8 @@ public class LeAudioService extends ProfileService { Integer setGroupId = descriptor.mGroupId; - for (Map.Entry entry - : mDeviceDescriptors.entrySet()) { + for (Map.Entry entry : + mDeviceDescriptors.entrySet()) { BluetoothDevice storedDevice = entry.getKey(); descriptor = entry.getValue(); if (device.equals(storedDevice)) { @@ -2310,8 +2355,9 @@ public class LeAudioService extends ProfileService { try { LeAudioStateMachine sm = getOrCreateStateMachine(storedDevice); if (sm == null) { - Log.e(TAG, "Ignored connect request for " + storedDevice - + " : no state machine"); + Log.e( + TAG, + "Ignored connect request for " + storedDevice + " : no state machine"); continue; } sm.sendMessage(LeAudioStateMachine.CONNECT); @@ -2343,8 +2389,10 @@ public class LeAudioService extends ProfileService { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(descriptor.mLostLeadDeviceWhileStreaming); if (deviceDescriptor == null) { - Log.e(TAG, "clearLostDevicesWhileStreaming: No valid descriptor for device: " - + descriptor.mLostLeadDeviceWhileStreaming); + Log.e( + TAG, + "clearLostDevicesWhileStreaming: No valid descriptor for device: " + + descriptor.mLostLeadDeviceWhileStreaming); return; } @@ -2438,8 +2486,11 @@ public class LeAudioService extends ProfileService { try { LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null || (descriptor.isActive())) { - Log.e(TAG, "handleGroupTransitToActive: no descriptors for group: " + groupId - + " or group already active"); + Log.e( + TAG, + "handleGroupTransitToActive: no descriptors for group: " + + groupId + + " or group already active"); return; } @@ -2486,8 +2537,11 @@ public class LeAudioService extends ProfileService { try { LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null || descriptor.isInactive()) { - Log.e(TAG, "handleGroupTransitToInactive: no descriptors for group: " + groupId - + " or group already inactive"); + Log.e( + TAG, + "handleGroupTransitToInactive: no descriptors for group: " + + groupId + + " or group already inactive"); return; } @@ -2547,8 +2601,10 @@ public class LeAudioService extends ProfileService { if (status == LeAudioStackEvent.STATUS_LOCAL_STREAM_REQUESTED) { Optional broadcastId = getFirstNotStoppedBroadcastId(); if (broadcastId.isEmpty() || (mBroadcastDescriptors.get(broadcastId.get()) == null)) { - Log.e(TAG, "handleUnicastStreamStatusChange: Broadcast to Unicast handover not" - + " possible"); + Log.e( + TAG, + "handleUnicastStreamStatusChange: Broadcast to Unicast handover not" + + " possible"); return; } @@ -2675,8 +2731,8 @@ public class LeAudioService extends ProfileService { } boolean ringtoneContextAvailable = - ((groupDescriptor.mAvailableContexts - & BluetoothLeAudio.CONTEXT_TYPE_RINGTONE) != 0); + ((groupDescriptor.mAvailableContexts & BluetoothLeAudio.CONTEXT_TYPE_RINGTONE) + != 0); Log.d( TAG, @@ -2687,12 +2743,16 @@ public class LeAudioService extends ProfileService { boolean isRingtoneEnabled = (groupDescriptor.isActive() && ringtoneContextAvailable); - Log.d(TAG, "updateInbandRingtoneForTheGroup old: " - + groupDescriptor.mInbandRingtoneEnabled + " new: " + isRingtoneEnabled); + Log.d( + TAG, + "updateInbandRingtoneForTheGroup old: " + + groupDescriptor.mInbandRingtoneEnabled + + " new: " + + isRingtoneEnabled); /* If at least one device from the group removes the Ringtone from available - * context types, the inband ringtone will be removed - */ + * context types, the inband ringtone will be removed + */ groupDescriptor.mInbandRingtoneEnabled = isRingtoneEnabled; TbsService tbsService = getTbsService(); if (tbsService == null) { @@ -2701,17 +2761,26 @@ public class LeAudioService extends ProfileService { } for (Map.Entry entry : - mDeviceDescriptors.entrySet()) { + mDeviceDescriptors.entrySet()) { if (entry.getValue().mGroupId == groupId) { BluetoothDevice device = entry.getKey(); LeAudioDeviceDescriptor deviceDescriptor = entry.getValue(); - Log.i(TAG, "updateInbandRingtoneForTheGroup, setting inband ringtone to: " - + groupDescriptor.mInbandRingtoneEnabled + " for " + device - + " " + deviceDescriptor.mDevInbandRingtoneEnabled); + Log.i( + TAG, + "updateInbandRingtoneForTheGroup, setting inband ringtone to: " + + groupDescriptor.mInbandRingtoneEnabled + + " for " + + device + + " " + + deviceDescriptor.mDevInbandRingtoneEnabled); if (Objects.equals( groupDescriptor.mInbandRingtoneEnabled, deviceDescriptor.mDevInbandRingtoneEnabled)) { - Log.d(TAG, "Device " + device + " has already set inband ringtone to " + Log.d( + TAG, + "Device " + + device + + " has already set inband ringtone to " + groupDescriptor.mInbandRingtoneEnabled); continue; } @@ -2775,12 +2844,13 @@ public class LeAudioService extends ProfileService { * Eventually we should be able to start scan from native when * b/276350722 is done */ - byte[] serviceData = new byte[]{0x11}; + byte[] serviceData = new byte[] {0x11}; ArrayList filterList = new ArrayList(); - ScanFilter filter = new ScanFilter.Builder() - .setServiceData(BluetoothUuid.LE_AUDIO, serviceData) - .build(); + ScanFilter filter = + new ScanFilter.Builder() + .setServiceData(BluetoothUuid.LE_AUDIO, serviceData) + .build(); filterList.add(filter); ScanSettings settings = @@ -2918,14 +2988,14 @@ public class LeAudioService extends ProfileService { case LeAudioStackEvent.CONNECTION_STATE_DISCONNECTING: case LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED: deviceDescriptor.mAclConnected = false; - startAudioServersBackgroundScan(/* retry = */ false); + startAudioServersBackgroundScan(/* retry= */ false); boolean disconnectDueToUnbond = (BluetoothDevice.BOND_NONE == mAdapterService.getBondState(device)); - if (descriptor != null && (Objects.equals(device, - mActiveAudioOutDevice) - || Objects.equals(device, mActiveAudioInDevice)) + if (descriptor != null + && (Objects.equals(device, mActiveAudioOutDevice) + || Objects.equals(device, mActiveAudioInDevice)) && (getConnectedPeerDevices(groupId).size() > 1) && !disconnectDueToUnbond) { @@ -2939,8 +3009,7 @@ public class LeAudioService extends ProfileService { deviceDescriptor.mAclConnected = true; if (descriptor != null && Objects.equals( - descriptor.mLostLeadDeviceWhileStreaming, - device)) { + descriptor.mLostLeadDeviceWhileStreaming, device)) { Log.d(TAG, "Removing from lost devices : " + device); descriptor.mLostLeadDeviceWhileStreaming = null; /* Try to connect other devices from the group */ @@ -2977,8 +3046,8 @@ public class LeAudioService extends ProfileService { int groupId = stackEvent.valueInt1; int nodeStatus = stackEvent.valueInt2; - Objects.requireNonNull(stackEvent.device, - "Device should never be null, event: " + stackEvent); + Objects.requireNonNull( + stackEvent.device, "Device should never be null, event: " + stackEvent); switch (nodeStatus) { case LeAudioStackEvent.GROUP_NODE_ADDED: @@ -3122,8 +3191,8 @@ public class LeAudioService extends ProfileService { mGroupReadLock.unlock(); } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE) { - Objects.requireNonNull(stackEvent.device, - "Device should never be null, event: " + stackEvent); + Objects.requireNonNull( + stackEvent.device, "Device should never be null, event: " + stackEvent); int sink_audio_location = stackEvent.valueInt1; @@ -3135,91 +3204,101 @@ public class LeAudioService extends ProfileService { descriptor.mSinkAudioLocation = sink_audio_location; - Log.i(TAG, "EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE:" + device - + " audio location:" + sink_audio_location); + Log.i( + TAG, + "EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE:" + + device + + " audio location:" + + sink_audio_location); } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED) { int groupId = stackEvent.valueInt1; int groupStatus = stackEvent.valueInt2; switch (groupStatus) { - case LeAudioStackEvent.GROUP_STATUS_ACTIVE: { - handleGroupTransitToActive(groupId); + case LeAudioStackEvent.GROUP_STATUS_ACTIVE: + { + handleGroupTransitToActive(groupId); - /* Clear possible exposed broadcast device after activating unicast */ - if (mActiveBroadcastAudioDevice != null) { - updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, true); - } - break; - } - case LeAudioStackEvent.GROUP_STATUS_INACTIVE: { - if (Flags.leaudioGettingActiveStateSupport()) { - LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); - if (descriptor == null) { - Log.e(TAG, "deviceDisconnected: no descriptors for group: " + groupId); - return; + /* Clear possible exposed broadcast device after activating unicast */ + if (mActiveBroadcastAudioDevice != null) { + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, true); } + break; + } + case LeAudioStackEvent.GROUP_STATUS_INACTIVE: + { + if (Flags.leaudioGettingActiveStateSupport()) { + LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); + if (descriptor == null) { + Log.e( + TAG, + "deviceDisconnected: no descriptors for group: " + groupId); + return; + } - if (descriptor.isActive()) { - handleGroupTransitToInactive(groupId); - } + if (descriptor.isActive()) { + handleGroupTransitToInactive(groupId); + } - descriptor.setActiveState(ACTIVE_STATE_INACTIVE); + descriptor.setActiveState(ACTIVE_STATE_INACTIVE); + + /* In case if group is inactivated due to switch to other */ + Integer gettingActiveGroupId = getFirstGroupIdInGettingActiveState(); + if (gettingActiveGroupId != LE_AUDIO_GROUP_ID_INVALID) { + if (leaudioAllowedContextMask()) { + /* Context were modified, apply mask to activating group */ + if (descriptor.areAllowedContextsModified()) { + setGroupAllowedContextMask( + gettingActiveGroupId, + descriptor.getAllowedSinkContexts(), + descriptor.getAllowedSourceContexts()); + setGroupAllowedContextMask( + groupId, + BluetoothLeAudio.CONTEXTS_ALL, + BluetoothLeAudio.CONTEXTS_ALL); + } + } + break; + } - /* In case if group is inactivated due to switch to other */ - Integer gettingActiveGroupId = getFirstGroupIdInGettingActiveState(); - if (gettingActiveGroupId != LE_AUDIO_GROUP_ID_INVALID) { if (leaudioAllowedContextMask()) { - /* Context were modified, apply mask to activating group */ + /* Clear allowed context mask if there is no switch of group */ if (descriptor.areAllowedContextsModified()) { - setGroupAllowedContextMask( - gettingActiveGroupId, - descriptor.getAllowedSinkContexts(), - descriptor.getAllowedSourceContexts()); setGroupAllowedContextMask( groupId, BluetoothLeAudio.CONTEXTS_ALL, BluetoothLeAudio.CONTEXTS_ALL); } } - break; + } else { + handleGroupTransitToInactive(groupId); } - if (leaudioAllowedContextMask()) { - /* Clear allowed context mask if there is no switch of group */ - if (descriptor.areAllowedContextsModified()) { - setGroupAllowedContextMask( - groupId, - BluetoothLeAudio.CONTEXTS_ALL, - BluetoothLeAudio.CONTEXTS_ALL); + if (isBroadcastAllowedToBeActivateInCurrentAudioMode()) { + /* Check if broadcast was deactivated due to unicast */ + if (mBroadcastIdDeactivatedForUnicastTransition.isPresent()) { + updateFallbackUnicastGroupIdForBroadcast(groupId); + if (!leaudioUseAudioModeListener()) { + mQueuedInCallValue = Optional.empty(); + } + startBroadcast(mBroadcastIdDeactivatedForUnicastTransition.get()); + mBroadcastIdDeactivatedForUnicastTransition = Optional.empty(); } - } - } else { - handleGroupTransitToInactive(groupId); - } - - if (isBroadcastAllowedToBeActivateInCurrentAudioMode()) { - /* Check if broadcast was deactivated due to unicast */ - if (mBroadcastIdDeactivatedForUnicastTransition.isPresent()) { - updateFallbackUnicastGroupIdForBroadcast(groupId); - if (!leaudioUseAudioModeListener()) { - mQueuedInCallValue = Optional.empty(); - } - startBroadcast(mBroadcastIdDeactivatedForUnicastTransition.get()); - mBroadcastIdDeactivatedForUnicastTransition = Optional.empty(); - } - if (!mCreateBroadcastQueue.isEmpty()) { - updateFallbackUnicastGroupIdForBroadcast(groupId); - BluetoothLeBroadcastSettings settings = mCreateBroadcastQueue.remove(); - createBroadcast(settings); + if (!mCreateBroadcastQueue.isEmpty()) { + updateFallbackUnicastGroupIdForBroadcast(groupId); + BluetoothLeBroadcastSettings settings = + mCreateBroadcastQueue.remove(); + createBroadcast(settings); + } } + break; + } + case LeAudioStackEvent.GROUP_STATUS_TURNED_IDLE_DURING_CALL: + { + handleGroupIdleDuringCall(); + break; } - break; - } - case LeAudioStackEvent.GROUP_STATUS_TURNED_IDLE_DURING_CALL: { - handleGroupIdleDuringCall(); - break; - } default: break; } @@ -3298,8 +3377,10 @@ public class LeAudioService extends ProfileService { LeAudioBroadcastDescriptor descriptor = mBroadcastDescriptors.get(broadcastId); if (descriptor == null) { - Log.e(TAG, "EVENT_TYPE_BROADCAST_STATE: No valid descriptor for broadcastId: " - + broadcastId); + Log.e( + TAG, + "EVENT_TYPE_BROADCAST_STATE: No valid descriptor for broadcastId: " + + broadcastId); return; } @@ -3402,8 +3483,11 @@ public class LeAudioService extends ProfileService { } else { LeAudioBroadcastDescriptor descriptor = mBroadcastDescriptors.get(broadcastId); if (descriptor == null) { - Log.e(TAG, "EVENT_TYPE_BROADCAST_METADATA_CHANGED: No valid descriptor for " - + "broadcastId: " + broadcastId); + Log.e( + TAG, + "EVENT_TYPE_BROADCAST_METADATA_CHANGED: No valid descriptor for " + + "broadcastId: " + + broadcastId); return; } descriptor.mMetadata = stackEvent.broadcastMetadata; @@ -3467,10 +3551,9 @@ public class LeAudioService extends ProfileService { * Process a change in the bonding state for a device. * * @param device the device whose bonding state has changed - * @param bondState the new bond state for the device. Possible values are: - * {@link BluetoothDevice#BOND_NONE}, - * {@link BluetoothDevice#BOND_BONDING}, - * {@link BluetoothDevice#BOND_BONDED}. + * @param bondState the new bond state for the device. Possible values are: {@link + * BluetoothDevice#BOND_NONE}, {@link BluetoothDevice#BOND_BONDING}, {@link + * BluetoothDevice#BOND_BONDED}. */ @VisibleForTesting void bondStateChanged(BluetoothDevice device, int bondState) { @@ -3573,9 +3656,7 @@ public class LeAudioService extends ProfileService { return result; } - /** - * Process a change for connection of a device. - */ + /** Process a change for connection of a device. */ public synchronized void deviceConnected(BluetoothDevice device) { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); if (deviceDescriptor == null) { @@ -3595,8 +3676,7 @@ public class LeAudioService extends ProfileService { if (descriptor != null) { descriptor.mIsConnected = true; } else { - Log.e(TAG, "deviceConnected: no descriptors for group: " - + deviceDescriptor.mGroupId); + Log.e(TAG, "deviceConnected: no descriptors for group: " + deviceDescriptor.mGroupId); } if (!isScannerNeeded()) { @@ -3685,9 +3765,7 @@ public class LeAudioService extends ProfileService { } } - /** - * Process a change for disconnection of a device. - */ + /** Process a change for disconnection of a device. */ public synchronized void deviceDisconnected(BluetoothDevice device, boolean hasFallbackDevice) { if (Flags.leaudioApiSynchronizedBlockFix()) { deviceDisconnectedV2(device, hasFallbackDevice); @@ -3717,16 +3795,19 @@ public class LeAudioService extends ProfileService { LeAudioGroupDescriptor descriptor = getGroupDescriptor(deviceDescriptor.mGroupId); if (descriptor == null) { - Log.e(TAG, "deviceDisconnected: no descriptors for group: " - + deviceDescriptor.mGroupId); + Log.e( + TAG, + "deviceDisconnected: no descriptors for group: " + + deviceDescriptor.mGroupId); return; } List connectedDevices = getConnectedPeerDevices(deviceDescriptor.mGroupId); /* Let's check if the last connected device is really connected */ - if (connectedDevices.size() == 1 && Objects.equals( - connectedDevices.get(0), descriptor.mLostLeadDeviceWhileStreaming)) { + if (connectedDevices.size() == 1 + && Objects.equals( + connectedDevices.get(0), descriptor.mLostLeadDeviceWhileStreaming)) { clearLostDevicesWhileStreaming(descriptor); return; } @@ -3767,8 +3848,8 @@ public class LeAudioService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -3798,6 +3879,7 @@ public class LeAudioService extends ProfileService { /** * Get device audio location. + * * @param device LE Audio capable device * @return the sink audioi location that this device currently exposed */ @@ -3816,8 +3898,9 @@ public class LeAudioService extends ProfileService { } /** - * Check if inband ringtone is enabled by the LE Audio group. - * Group id for the device can be found with {@link BluetoothLeAudio#getGroupId}. + * Check if inband ringtone is enabled by the LE Audio group. Group id for the device can be + * found with {@link BluetoothLeAudio#getGroupId}. + * * @param groupId LE Audio group id * @return true if inband ringtone is enabled, false otherwise */ @@ -3836,6 +3919,7 @@ public class LeAudioService extends ProfileService { /** * Set In Call state + * * @param inCall True if device in call (any state), false otherwise. */ public void setInCall(boolean inCall) { @@ -3878,20 +3962,20 @@ public class LeAudioService extends ProfileService { * * @param groupId is the group id of the device which had a preference change * @param isOutputPreferenceLeAudio {@code true} if {@link BluetoothProfile#LE_AUDIO} is - * preferred for {@link BluetoothAdapter#AUDIO_MODE_OUTPUT_ONLY}, {@code false} if it is - * {@link BluetoothProfile#A2DP} + * preferred for {@link BluetoothAdapter#AUDIO_MODE_OUTPUT_ONLY}, {@code false} if it is + * {@link BluetoothProfile#A2DP} * @param isDuplexPreferenceLeAudio {@code true} if {@link BluetoothProfile#LE_AUDIO} is - * preferred for {@link BluetoothAdapter#AUDIO_MODE_DUPLEX}, {@code false} if it is - * {@link BluetoothProfile#HEADSET} + * preferred for {@link BluetoothAdapter#AUDIO_MODE_DUPLEX}, {@code false} if it is {@link + * BluetoothProfile#HEADSET} */ - public void sendAudioProfilePreferencesToNative(int groupId, boolean isOutputPreferenceLeAudio, - boolean isDuplexPreferenceLeAudio) { + public void sendAudioProfilePreferencesToNative( + int groupId, boolean isOutputPreferenceLeAudio, boolean isDuplexPreferenceLeAudio) { if (!mLeAudioNativeIsInitialized) { Log.e(TAG, "Le Audio not initialized properly."); return; } - mLeAudioNativeInterface.sendAudioProfilePreferences(groupId, isOutputPreferenceLeAudio, - isDuplexPreferenceLeAudio); + mLeAudioNativeInterface.sendAudioProfilePreferences( + groupId, isOutputPreferenceLeAudio, isDuplexPreferenceLeAudio); } /** @@ -3942,15 +4026,14 @@ public class LeAudioService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device the remote device * @param connectionPolicy is the connection policy to set to for this profile @@ -3958,17 +4041,17 @@ public class LeAudioService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.LE_AUDIO, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { - setEnabledState(device, /* enabled = */ true); + setEnabledState(device, /* enabled= */ true); // Authorizes LEA GATT server services if already assigned to a group int groupId = getGroupId(device); if (groupId != LE_AUDIO_GROUP_ID_INVALID) { @@ -3976,7 +4059,7 @@ public class LeAudioService extends ProfileService { } connect(device); } else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - setEnabledState(device, /* enabled = */ false); + setEnabledState(device, /* enabled= */ false); // Remove authorization for LEA GATT server services setAuthorizationForRelatedProfiles(device, false); disconnect(device); @@ -3987,12 +4070,17 @@ public class LeAudioService extends ProfileService { /** * Sets the connection policy for LE Audio GATT client profiles + * * @param device is the remote device * @param connectionPolicy is the connection policy we wish to set */ private void setLeAudioGattClientProfilesPolicy(BluetoothDevice device, int connectionPolicy) { - Log.d(TAG, "setLeAudioGattClientProfilesPolicy for device " + device + " to policy=" - + connectionPolicy); + Log.d( + TAG, + "setLeAudioGattClientProfilesPolicy for device " + + device + + " to policy=" + + connectionPolicy); VolumeControlService volumeControlService = getVolumeControlService(); if (volumeControlService != null) { volumeControlService.setConnectionPolicy(device, connectionPolicy); @@ -4018,17 +4106,16 @@ public class LeAudioService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { - int connection_policy = mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO); + int connection_policy = + mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO); Log.d(TAG, device + " connection policy = " + connection_policy); return connection_policy; } @@ -4036,6 +4123,7 @@ public class LeAudioService extends ProfileService { /** * Get device group id. Devices with same group id belong to same group (i.e left and right * earbud) + * * @param device LE Audio capable device * @return group id that this device currently belongs to */ @@ -4081,6 +4169,7 @@ public class LeAudioService extends ProfileService { /** * Set the user application ccid along with used context type + * * @param userUuid user uuid * @param ccid content control id * @param contextType context type @@ -4100,6 +4189,7 @@ public class LeAudioService extends ProfileService { /** * Set volume for streaming devices + * * @param volume volume to set */ public void setVolume(int volume) { @@ -4227,7 +4317,7 @@ public class LeAudioService extends ProfileService { mGroupReadLock.unlock(); } - startAudioServersBackgroundScan(/* retry = */ false); + startAudioServersBackgroundScan(/* retry= */ false); } @VisibleForTesting @@ -4298,8 +4388,7 @@ public class LeAudioService extends ProfileService { LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId); if (groupDescriptor == null) { - mGroupDescriptors.put(groupId, - new LeAudioGroupDescriptor(false)); + mGroupDescriptors.put(groupId, new LeAudioGroupDescriptor(false)); } groupDescriptor = getGroupDescriptor(groupId); if (groupDescriptor == null) { @@ -4308,11 +4397,14 @@ public class LeAudioService extends ProfileService { } LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); if (deviceDescriptor == null) { - deviceDescriptor = createDeviceDescriptor(device, - groupDescriptor.mInbandRingtoneEnabled); + deviceDescriptor = + createDeviceDescriptor(device, groupDescriptor.mInbandRingtoneEnabled); if (deviceDescriptor == null) { - Log.e(TAG, "handleGroupNodeAdded: Can't create descriptor for added from" - + " storage device: " + device); + Log.e( + TAG, + "handleGroupNodeAdded: Can't create descriptor for added from" + + " storage device: " + + device); return; } @@ -4331,7 +4423,7 @@ public class LeAudioService extends ProfileService { if (mBluetoothEnabled) { setAuthorizationForRelatedProfiles(device, true); - startAudioServersBackgroundScan(/* retry = */ false); + startAudioServersBackgroundScan(/* retry= */ false); } } @@ -4564,8 +4656,8 @@ public class LeAudioService extends ProfileService { } } - private void notifyBroadcastMetadataChanged(int broadcastId, - BluetoothLeBroadcastMetadata metadata) { + private void notifyBroadcastMetadataChanged( + int broadcastId, BluetoothLeBroadcastMetadata metadata) { if (mBroadcastCallbacks != null) { int n = mBroadcastCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { @@ -4649,12 +4741,17 @@ public class LeAudioService extends ProfileService { * @param inputCodecConfig the input codec configuration preference * @param outputCodecConfig the output codec configuration preference */ - public void setCodecConfigPreference(int groupId, + public void setCodecConfigPreference( + int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig) { - Log.d(TAG, "setCodecConfigPreference(" + groupId + "): " - + Objects.toString(inputCodecConfig) - + Objects.toString(outputCodecConfig)); + Log.d( + TAG, + "setCodecConfigPreference(" + + groupId + + "): " + + Objects.toString(inputCodecConfig) + + Objects.toString(outputCodecConfig)); LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null) { Log.e(TAG, "setCodecConfigPreference: Invalid groupId, " + groupId); @@ -4669,9 +4766,12 @@ public class LeAudioService extends ProfileService { /* We support different configuration for input and output but codec type * shall be same */ if (inputCodecConfig.getCodecType() != outputCodecConfig.getCodecType()) { - Log.e(TAG, "setCodecConfigPreference: Input codec type: " - + inputCodecConfig.getCodecType() - + "does not match output codec type: " + outputCodecConfig.getCodecType()); + Log.e( + TAG, + "setCodecConfigPreference: Input codec type: " + + inputCodecConfig.getCodecType() + + "does not match output codec type: " + + outputCodecConfig.getCodecType()); return; } @@ -4691,6 +4791,7 @@ public class LeAudioService extends ProfileService { /** * Checks if the remote device supports LE Audio duplex (output and input). + * * @param device the remote device to check * @return {@code true} if LE Audio duplex is supported, {@code false} otherwise */ @@ -4710,6 +4811,7 @@ public class LeAudioService extends ProfileService { /** * Checks if the remote device supports LE Audio output + * * @param device the remote device to check * @return {@code true} if LE Audio output is supported, {@code false} otherwise */ @@ -4728,6 +4830,7 @@ public class LeAudioService extends ProfileService { /** * Gets the lead device for the CSIP group containing the provided device + * * @param device the remote device whose CSIP group lead device we want to find * @return the lead device of the CSIP group or {@code null} if the group does not exist */ @@ -4740,11 +4843,11 @@ public class LeAudioService extends ProfileService { } /** - * Sends the preferred audio profile change requested from a call to - * {@link BluetoothAdapter#setPreferredAudioProfiles(BluetoothDevice, Bundle)} to the audio - * framework to apply the change. The audio framework will call - * {@link BluetoothAdapter#notifyActiveDeviceChangeApplied(BluetoothDevice)} once the - * change is successfully applied. + * Sends the preferred audio profile change requested from a call to {@link + * BluetoothAdapter#setPreferredAudioProfiles(BluetoothDevice, Bundle)} to the audio framework + * to apply the change. The audio framework will call {@link + * BluetoothAdapter#notifyActiveDeviceChangeApplied(BluetoothDevice)} once the change is + * successfully applied. * * @return the number of requests sent to the audio framework */ @@ -4759,9 +4862,13 @@ public class LeAudioService extends ProfileService { if (mActiveAudioOutDevice != null) { int volume = getAudioDeviceGroupVolume(getGroupId(mActiveAudioOutDevice)); final boolean suppressNoisyIntent = mActiveAudioOutDevice != null; - Log.i(TAG, "Sending LE Audio Output active device changed for preferred profile " - + "change with volume=" + volume + " and suppressNoisyIntent=" - + suppressNoisyIntent); + Log.i( + TAG, + "Sending LE Audio Output active device changed for preferred profile " + + "change with volume=" + + volume + + " and suppressNoisyIntent=" + + suppressNoisyIntent); final BluetoothProfileConnectionInfo connectionInfo; if (isAtLeastU()) { @@ -4780,9 +4887,10 @@ public class LeAudioService extends ProfileService { if (mActiveAudioInDevice != null) { Log.i(TAG, "Sending LE Audio Input active device changed for audio profile change"); - mAudioManager.handleBluetoothActiveDeviceChanged(mActiveAudioInDevice, - mActiveAudioInDevice, BluetoothProfileConnectionInfo.createLeAudioInfo(false, - false)); + mAudioManager.handleBluetoothActiveDeviceChanged( + mActiveAudioInDevice, + mActiveAudioInDevice, + BluetoothProfileConnectionInfo.createLeAudioInfo(false, false)); audioFrameworkCalls++; } @@ -4827,9 +4935,7 @@ public class LeAudioService extends ProfileService { } } - /** - * Binder object: must be a static class or memory leak may occur - */ + /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting static class BluetoothLeAudioBinder extends IBluetoothLeAudio.Stub implements IProfileServiceBinder { @@ -5286,7 +5392,8 @@ public class LeAudioService extends ProfileService { } @Override - public void setCodecConfigPreference(int groupId, + public void setCodecConfigPreference( + int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig, AttributionSource source) { @@ -5319,8 +5426,10 @@ public class LeAudioService extends ProfileService { ProfileService.println(sb, " currentlyActiveGroupId: " + getActiveGroupId()); ProfileService.println(sb, " mActiveAudioOutDevice: " + mActiveAudioOutDevice); ProfileService.println(sb, " mActiveAudioInDevice: " + mActiveAudioInDevice); - ProfileService.println(sb, " mUnicastGroupIdDeactivatedForBroadcastTransition: " - + mUnicastGroupIdDeactivatedForBroadcastTransition); + ProfileService.println( + sb, + " mUnicastGroupIdDeactivatedForBroadcastTransition: " + + mUnicastGroupIdDeactivatedForBroadcastTransition); ProfileService.println( sb, " mBroadcastIdDeactivatedForUnicastTransition: " @@ -5331,8 +5440,9 @@ public class LeAudioService extends ProfileService { sb, " mLeAudioDeviceInactivatedForHfpHandover:" + mLeAudioDeviceInactivatedForHfpHandover); - ProfileService.println(sb, " mLeAudioIsInbandRingtoneSupported:" - + mLeAudioInbandRingtoneSupportedByPlatform); + ProfileService.println( + sb, + " mLeAudioIsInbandRingtoneSupported:" + mLeAudioInbandRingtoneSupportedByPlatform); int numberOfUngroupedDevs = 0; mGroupReadLock.lock(); @@ -5349,17 +5459,17 @@ public class LeAudioService extends ProfileService { ProfileService.println(sb, " isConnected: " + groupDescriptor.mIsConnected); ProfileService.println(sb, " mDirection: " + groupDescriptor.mDirection); ProfileService.println(sb, " group lead: " + leadDevice); - ProfileService.println(sb, " lost lead device: " - + groupDescriptor.mLostLeadDeviceWhileStreaming); - ProfileService.println(sb, " mInbandRingtoneEnabled: " - + groupDescriptor.mInbandRingtoneEnabled); + ProfileService.println( + sb, " lost lead device: " + groupDescriptor.mLostLeadDeviceWhileStreaming); + ProfileService.println( + sb, " mInbandRingtoneEnabled: " + groupDescriptor.mInbandRingtoneEnabled); ProfileService.println( sb, "mInactivatedDueToContextType: " + groupDescriptor.mInactivatedDueToContextType); - for (Map.Entry deviceEntry - : mDeviceDescriptors.entrySet()) { + for (Map.Entry deviceEntry : + mDeviceDescriptors.entrySet()) { LeAudioDeviceDescriptor deviceDescriptor = deviceEntry.getValue(); if (!Objects.equals(deviceDescriptor.mGroupId, groupId)) { if (deviceDescriptor.mGroupId == LE_AUDIO_GROUP_ID_INVALID) { @@ -5375,10 +5485,12 @@ public class LeAudioService extends ProfileService { } ProfileService.println( sb, " mAclConnected: " + deviceDescriptor.mAclConnected); - ProfileService.println(sb, " mDevInbandRingtoneEnabled: " - + deviceDescriptor.mDevInbandRingtoneEnabled); - ProfileService.println(sb, " mSinkAudioLocation: " - + deviceDescriptor.mSinkAudioLocation); + ProfileService.println( + sb, + " mDevInbandRingtoneEnabled: " + + deviceDescriptor.mDevInbandRingtoneEnabled); + ProfileService.println( + sb, " mSinkAudioLocation: " + deviceDescriptor.mSinkAudioLocation); ProfileService.println(sb, " mDirection: " + deviceDescriptor.mDirection); } } @@ -5388,8 +5500,8 @@ public class LeAudioService extends ProfileService { if (numberOfUngroupedDevs > 0) { ProfileService.println(sb, "UnGroup devices:"); - for (Map.Entry entry - : mDeviceDescriptors.entrySet()) { + for (Map.Entry entry : + mDeviceDescriptors.entrySet()) { LeAudioDeviceDescriptor deviceDescriptor = entry.getValue(); if (deviceDescriptor.mGroupId != LE_AUDIO_GROUP_ID_INVALID) { continue; @@ -5397,10 +5509,12 @@ public class LeAudioService extends ProfileService { deviceDescriptor.mStateMachine.dump(sb); ProfileService.println(sb, " mAclConnected: " + deviceDescriptor.mAclConnected); - ProfileService.println(sb, " mDevInbandRingtoneEnabled: " - + deviceDescriptor.mDevInbandRingtoneEnabled); - ProfileService.println(sb, " mSinkAudioLocation: " - + deviceDescriptor.mSinkAudioLocation); + ProfileService.println( + sb, + " mDevInbandRingtoneEnabled: " + + deviceDescriptor.mDevInbandRingtoneEnabled); + ProfileService.println( + sb, " mSinkAudioLocation: " + deviceDescriptor.mSinkAudioLocation); ProfileService.println(sb, " mDirection: " + deviceDescriptor.mDirection); } } diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java index 20dc87aba0f..9e12bd68728 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java @@ -24,8 +24,8 @@ import android.bluetooth.BluetoothLeBroadcastMetadata; import java.util.List; /** - * Stack event sent via a callback from JNI to Java, or generated - * internally by the LeAudio State Machine. + * Stack event sent via a callback from JNI to Java, or generated internally by the LeAudio State + * Machine. */ public class LeAudioStackEvent { // Event types for STACK_EVENT message (coming from native in bt_le_audio.h) @@ -147,8 +147,9 @@ public class LeAudioStackEvent { } if (type == EVENT_TYPE_BROADCAST_METADATA_CHANGED) { - result.append(", broadcastMetadata:" - + eventTypeValueBroadcastMetadataToString(broadcastMetadata)); + result.append( + ", broadcastMetadata:" + + eventTypeValueBroadcastMetadataToString(broadcastMetadata)); } result.append("}"); return result.toString(); @@ -202,13 +203,13 @@ public class LeAudioStackEvent { case EVENT_TYPE_CONNECTION_STATE_CHANGED: switch (value) { case CONNECTION_STATE_DISCONNECTED: - return "CONNECTION_STATE_DISCONNECTED"; + return "CONNECTION_STATE_DISCONNECTED"; case CONNECTION_STATE_CONNECTING: - return "CONNECTION_STATE_CONNECTING"; + return "CONNECTION_STATE_CONNECTING"; case CONNECTION_STATE_CONNECTED: - return "CONNECTION_STATE_CONNECTED"; + return "CONNECTION_STATE_CONNECTED"; case CONNECTION_STATE_DISCONNECTING: - return "CONNECTION_STATE_DISCONNECTING"; + return "CONNECTION_STATE_DISCONNECTING"; default: return "UNKNOWN"; } @@ -369,8 +370,8 @@ public class LeAudioStackEvent { } } - private static String eventTypeValueCodec1ToString(int type, - BluetoothLeAudioCodecConfig value) { + private static String eventTypeValueCodec1ToString( + int type, BluetoothLeAudioCodecConfig value) { switch (type) { case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "{input codec =" + value + "}"; @@ -379,8 +380,8 @@ public class LeAudioStackEvent { } } - private static String eventTypeValueCodec2ToString(int type, - BluetoothLeAudioCodecConfig value) { + private static String eventTypeValueCodec2ToString( + int type, BluetoothLeAudioCodecConfig value) { switch (type) { case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "{output codec =" + value + "}"; @@ -389,8 +390,8 @@ public class LeAudioStackEvent { } } - private static String eventTypeValueCodecList1ToString(int type, - List value) { + private static String eventTypeValueCodecList1ToString( + int type, List value) { String valueStr = ""; switch (type) { case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: @@ -408,8 +409,8 @@ public class LeAudioStackEvent { } } - private static String eventTypeValueCodecList2ToString(int type, - List value) { + private static String eventTypeValueCodecList2ToString( + int type, List value) { String valueStr = ""; switch (type) { case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java index 1741e9f2a31..2748bb07f86 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java @@ -16,34 +16,18 @@ */ /** - * Bluetooth LeAudio StateMachine. There is one instance per remote device's ASE. - * - "Disconnected" and "Connected" are steady states. - * - "Connecting" and "Disconnecting" are transient states until the - * connection / disconnection is completed. + * Bluetooth LeAudio StateMachine. There is one instance per remote device's ASE. - "Disconnected" + * and "Connected" are steady states. - "Connecting" and "Disconnecting" are transient states until + * the connection / disconnection is completed. * + *

(Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting)<--->(Disconnecting) | ^ CONNECTED + * | | DISCONNECT V | (Connected) NOTES: - If state machine is in "Connecting" state and the remote + * device sends DISCONNECT request, the state machine transitions to "Disconnecting" state. - + * Similarly, if the state machine is in "Disconnecting" state and the remote device sends CONNECT + * request, the state machine transitions to "Connecting" state. * - * (Disconnected) - * | ^ - * CONNECT | | DISCONNECTED - * V | - * (Connecting)<--->(Disconnecting) - * | ^ - * CONNECTED | | DISCONNECT - * V | - * (Connected) - * NOTES: - * - If state machine is in "Connecting" state and the remote device sends - * DISCONNECT request, the state machine transitions to "Disconnecting" state. - * - Similarly, if the state machine is in "Disconnecting" state and the remote device - * sends CONNECT request, the state machine transitions to "Connecting" state. - * - * DISCONNECT - * (Connecting) ---------------> (Disconnecting) - * <--------------- - * CONNECT - * + *

DISCONNECT (Connecting) ---------------> (Disconnecting) <--------------- CONNECT */ - package com.android.bluetooth.le_audio; import android.bluetooth.BluetoothDevice; @@ -68,12 +52,10 @@ final class LeAudioStateMachine extends StateMachine { static final int CONNECT = 1; static final int DISCONNECT = 2; - @VisibleForTesting - static final int STACK_EVENT = 101; + @VisibleForTesting static final int STACK_EVENT = 101; private static final int CONNECT_TIMEOUT = 201; - @VisibleForTesting - static int sConnectTimeoutMs = 30000; // 30s + @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s private Disconnected mDisconnected; private Connecting mConnecting; @@ -136,16 +118,19 @@ final class LeAudioStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_DISCONNECTED; removeDeferredMessages(DISCONNECT); if (mLastConnectionState != -1) { // Don't broadcast during startup - broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, - mLastConnectionState); + broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, mLastConnectionState); if (Flags.audioRoutingCentralization()) { mService.deviceDisconnected(mDevice, false); } @@ -154,15 +139,21 @@ final class LeAudioStateMachine extends StateMachine { @Override public void exit() { - log("Exit Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + log( + "Exit Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected process message(" + mDevice + "): " + messageWhatToString( - message.what)); + log( + "Disconnected process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -244,8 +235,12 @@ final class LeAudioStateMachine extends StateMachine { class Connecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_CONNECTING; broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState); @@ -253,16 +248,22 @@ final class LeAudioStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -331,8 +332,12 @@ final class LeAudioStateMachine extends StateMachine { class Disconnecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); mConnectionState = BluetoothProfile.STATE_DISCONNECTING; broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState); @@ -340,32 +345,39 @@ final class LeAudioStateMachine extends StateMachine { @Override public void exit() { - log("Exit Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Disconnecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Disconnecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Disconnecting connection timeout: " + mDevice); - mNativeInterface.disconnectLeAudio(mDevice); - LeAudioStackEvent disconnectEvent = - new LeAudioStackEvent( - LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - disconnectEvent.device = mDevice; - disconnectEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, disconnectEvent); - break; - } + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Disconnecting connection timeout: " + mDevice); + mNativeInterface.disconnectLeAudio(mDevice); + LeAudioStackEvent disconnectEvent = + new LeAudioStackEvent( + LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + disconnectEvent.device = mDevice; + disconnectEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, disconnectEvent); + break; + } case DISCONNECT: deferMessage(message); break; @@ -430,8 +442,12 @@ final class LeAudioStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - Log.i(TAG, "Enter Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_CONNECTED; removeDeferredMessages(CONNECT); if (Flags.audioRoutingCentralization()) { @@ -442,15 +458,17 @@ final class LeAudioStateMachine extends StateMachine { @Override public void exit() { - log("Exit Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @Override public boolean processMessage(Message message) { - log("Connected process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log("Connected process message(" + mDevice + "): " + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -519,8 +537,13 @@ final class LeAudioStateMachine extends StateMachine { // This method does not check for error condition (newState == prevState) private void broadcastConnectionState(int newState, int prevState) { - log("Connection state " + mDevice + ": " + profileStateToString(prevState) - + "->" + profileStateToString(newState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(prevState) + + "->" + + profileStateToString(newState)); mService.notifyConnectionStateChanged(mDevice, newState, prevState); } @@ -562,7 +585,7 @@ final class LeAudioStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java index 817d76257d4..ed3399e9199 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java @@ -34,9 +34,7 @@ import java.util.Arrays; import java.util.List; import java.util.UUID; -/** - * A GATT server for Telephony and Media Audio Profile (TMAP) - */ +/** A GATT server for Telephony and Media Audio Profile (TMAP) */ @VisibleForTesting public class LeAudioTmapGattServer { private static final String TAG = "LeAudioTmapGattServer"; @@ -67,6 +65,7 @@ public class LeAudioTmapGattServer { /** * Init TMAP server + * * @param roleMask bit mask of supported roles. */ @VisibleForTesting @@ -78,8 +77,8 @@ public class LeAudioTmapGattServer { } BluetoothGattService service = - new BluetoothGattService(BluetoothUuid.TMAP.getUuid(), - BluetoothGattService.SERVICE_TYPE_PRIMARY); + new BluetoothGattService( + BluetoothUuid.TMAP.getUuid(), BluetoothGattService.SERVICE_TYPE_PRIMARY); BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic( @@ -95,9 +94,7 @@ public class LeAudioTmapGattServer { } } - /** - * Stop TMAP server - */ + /** Stop TMAP server */ @VisibleForTesting public void stop() { Log.d(TAG, "stop()"); @@ -109,29 +106,32 @@ public class LeAudioTmapGattServer { } /** - * Callback to handle incoming requests to the GATT server. - * All read/write requests for characteristics and descriptors are handled here. + * Callback to handle incoming requests to the GATT server. All read/write requests for + * characteristics and descriptors are handled here. */ private final BluetoothGattServerCallback mBluetoothGattServerCallback = new BluetoothGattServerCallback() { - @Override - public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattCharacteristic characteristic) { - byte[] value = characteristic.getValue(); - Log.d(TAG, "value " + Arrays.toString(value)); - if (value != null) { - Log.e(TAG, "value null"); - value = Arrays.copyOfRange(value, offset, value.length); - } - mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, - offset, value); - } - }; + @Override + public void onCharacteristicReadRequest( + BluetoothDevice device, + int requestId, + int offset, + BluetoothGattCharacteristic characteristic) { + byte[] value = characteristic.getValue(); + Log.d(TAG, "value " + Arrays.toString(value)); + if (value != null) { + Log.e(TAG, "value null"); + value = Arrays.copyOfRange(value, offset, value.length); + } + mBluetoothGattServer.sendResponse( + device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value); + } + }; - /** + /** * A proxy class that facilitates testing. * - * This is necessary due to the "final" attribute of the BluetoothGattServer class. + *

This is necessary due to the "final" attribute of the BluetoothGattServer class. */ public static class BluetoothGattServerProxy { private final Context mContext; @@ -139,28 +139,28 @@ public class LeAudioTmapGattServer { private BluetoothGattServer mBluetoothGattServer; - /** - * Create a new GATT server proxy object - * @param context context to use - */ + /** + * Create a new GATT server proxy object + * + * @param context context to use + */ public BluetoothGattServerProxy(Context context) { mContext = context; mBluetoothManager = context.getSystemService(BluetoothManager.class); } - /** - * Open with GATT server callback - * @param callback callback to invoke - * @return true on success - */ + /** + * Open with GATT server callback + * + * @param callback callback to invoke + * @return true on success + */ public boolean open(BluetoothGattServerCallback callback) { mBluetoothGattServer = mBluetoothManager.openGattServer(mContext, callback); return mBluetoothGattServer != null; } - /** - * Close the GATT server, should be called as soon as the server is not needed - */ + /** Close the GATT server, should be called as soon as the server is not needed */ public void close() { if (mBluetoothGattServer == null) { Log.w(TAG, "BluetoothGattServerProxy.close() called without open()"); @@ -170,33 +170,36 @@ public class LeAudioTmapGattServer { mBluetoothGattServer = null; } - /** - * Add a GATT service - * @param service added service - * @return true on success - */ + /** + * Add a GATT service + * + * @param service added service + * @return true on success + */ public boolean addService(BluetoothGattService service) { return mBluetoothGattServer.addService(service); } - /** - * Send GATT response to remote - * @param device remote device - * @param requestId request id - * @param status status of response - * @param offset offset of the value - * @param value value content - * @return true on success - */ + /** + * Send GATT response to remote + * + * @param device remote device + * @param requestId request id + * @param status status of response + * @param offset offset of the value + * @param value value content + * @return true on success + */ public boolean sendResponse( BluetoothDevice device, int requestId, int status, int offset, byte[] value) { return mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); } - /** - * Gatt a list of devices connected to this GATT server - * @return list of connected devices at this moment - */ + /** + * Gatt a list of devices connected to this GATT server + * + * @return list of connected devices at this moment + */ public List getConnectedDevices() { return mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT_SERVER); } diff --git a/android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java b/android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java index 372d3d0f754..31b2366db7f 100644 --- a/android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java +++ b/android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java @@ -38,9 +38,20 @@ public class AdvtFilterOnFoundOnLostInfo { private int mRssiValue; private int mTimeStamp; - public AdvtFilterOnFoundOnLostInfo(int clientIf, int advPktLen, byte[] advPkt, int scanRspLen, - byte[] scanRsp, int filtIndex, int advState, int advInfoPresent, String address, - int addrType, int txPower, int rssiValue, int timeStamp) { + public AdvtFilterOnFoundOnLostInfo( + int clientIf, + int advPktLen, + byte[] advPkt, + int scanRspLen, + byte[] scanRsp, + int filtIndex, + int advState, + int advInfoPresent, + String address, + int addrType, + int txPower, + int rssiValue, + int timeStamp) { mClientIf = clientIf; mAdvPktLen = advPktLen; @@ -118,6 +129,4 @@ public class AdvtFilterOnFoundOnLostInfo { } return result; } - } - diff --git a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java index 9790ccf8ebd..fc2f28f6801 100644 --- a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java +++ b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java @@ -43,10 +43,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; -/** - * ScanStats class helps keep track of information about scans - * on a per application basis. - */ +/** ScanStats class helps keep track of information about scans on a per application basis. */ public class AppScanStats { private static final String TAG = AppScanStats.class.getSimpleName(); @@ -74,8 +71,10 @@ public class AppScanStats { private final AdapterService mAdapterService; private static Object sLock = new Object(); + @GuardedBy("sLock") static long sRadioStartTime = 0; + static int sRadioScanMode; static boolean sIsRadioStarted = false; static boolean sIsScreenOn = false; @@ -100,8 +99,13 @@ public class AppScanStats { public int scanCallbackType; public String filterString; - LastScan(long timestamp, boolean isFilterScan, boolean isCallbackScan, int scannerId, - int scanMode, int scanCallbackType) { + LastScan( + long timestamp, + boolean isFilterScan, + boolean isCallbackScan, + int scannerId, + int scanMode, + int scanCallbackType) { this.duration = 0; this.timestamp = timestamp; this.isOpportunisticScan = false; @@ -122,6 +126,7 @@ public class AppScanStats { this.filterString = ""; } } + public String appName; private WorkSource mWorkSource; // Used for BatteryStatsManager private final WorkSourceUtil mWorkSourceUtil; // Used for BluetoothStatsLog @@ -177,8 +182,11 @@ public class AppScanStats { // to lower the cost of the binder transaction if (scan.results % 100 == 0) { mBatteryStatsManager.reportBleScanResults(mWorkSource, 100); - BluetoothStatsLog.write(BluetoothStatsLog.BLE_SCAN_RESULT_RECEIVED, - mWorkSourceUtil.getUids(), mWorkSourceUtil.getTags(), 100); + BluetoothStatsLog.write( + BluetoothStatsLog.BLE_SCAN_RESULT_RECEIVED, + mWorkSourceUtil.getUids(), + mWorkSourceUtil.getTags(), + 100); } } @@ -217,8 +225,12 @@ public class AppScanStats { return scan.isAutoBatchScan; } - public synchronized void recordScanStart(ScanSettings settings, List filters, - boolean isFilterScan, boolean isCallbackScan, int scannerId) { + public synchronized void recordScanStart( + ScanSettings settings, + List filters, + boolean isFilterScan, + boolean isCallbackScan, + int scannerId) { LastScan existingScan = getScanFromScannerId(scannerId); if (existingScan != null) { return; @@ -226,15 +238,21 @@ public class AppScanStats { this.mScansStarted++; startTime = SystemClock.elapsedRealtime(); - LastScan scan = new LastScan(startTime, isFilterScan, isCallbackScan, scannerId, - settings.getScanMode(), settings.getCallbackType()); + LastScan scan = + new LastScan( + startTime, + isFilterScan, + isCallbackScan, + scannerId, + settings.getScanMode(), + settings.getCallbackType()); if (settings != null) { scan.isOpportunisticScan = scan.scanMode == ScanSettings.SCAN_MODE_OPPORTUNISTIC; scan.isBackgroundScan = (scan.scanCallbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0; scan.isBatchScan = settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_ALL_MATCHES - && settings.getReportDelayMillis() != 0; + && settings.getReportDelayMillis() != 0; switch (scan.scanMode) { case ScanSettings.SCAN_MODE_OPPORTUNISTIC: mOppScan++; @@ -256,17 +274,20 @@ public class AppScanStats { if (isFilterScan) { for (ScanFilter filter : filters) { - scan.filterString += - "\n └ " + filterToStringWithoutNullParam(filter); + scan.filterString += "\n └ " + filterToStringWithoutNullParam(filter); } } - BluetoothMetricsProto.ScanEvent scanEvent = BluetoothMetricsProto.ScanEvent.newBuilder() - .setScanEventType(BluetoothMetricsProto.ScanEvent.ScanEventType.SCAN_EVENT_START) - .setScanTechnologyType( - BluetoothMetricsProto.ScanEvent.ScanTechnologyType.SCAN_TECH_TYPE_LE) - .setEventTimeMillis(System.currentTimeMillis()) - .setInitiator(truncateAppName(appName)).build(); + BluetoothMetricsProto.ScanEvent scanEvent = + BluetoothMetricsProto.ScanEvent.newBuilder() + .setScanEventType( + BluetoothMetricsProto.ScanEvent.ScanEventType.SCAN_EVENT_START) + .setScanTechnologyType( + BluetoothMetricsProto.ScanEvent.ScanTechnologyType + .SCAN_TECH_TYPE_LE) + .setEventTimeMillis(System.currentTimeMillis()) + .setInitiator(truncateAppName(appName)) + .build(); mScanHelper.addScanEvent(scanEvent); if (!isScanning()) { @@ -275,10 +296,14 @@ public class AppScanStats { boolean isUnoptimized = !(scan.isFilterScan || scan.isBackgroundScan || scan.isOpportunisticScan); mBatteryStatsManager.reportBleScanStarted(mWorkSource, isUnoptimized); - BluetoothStatsLog.write(BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, - mWorkSourceUtil.getUids(), mWorkSourceUtil.getTags(), + BluetoothStatsLog.write( + BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, + mWorkSourceUtil.getUids(), + mWorkSourceUtil.getTags(), BluetoothStatsLog.BLE_SCAN_STATE_CHANGED__STATE__ON, - scan.isFilterScan, scan.isBackgroundScan, scan.isOpportunisticScan); + scan.isFilterScan, + scan.isBackgroundScan, + scan.isOpportunisticScan); recordScanAppCountMetricsStart(scan); mOngoingScans.put(scannerId, scan); @@ -304,14 +329,17 @@ public class AppScanStats { } mLastScans.add(scan); - BluetoothMetricsProto.ScanEvent scanEvent = BluetoothMetricsProto.ScanEvent.newBuilder() - .setScanEventType(BluetoothMetricsProto.ScanEvent.ScanEventType.SCAN_EVENT_STOP) - .setScanTechnologyType( - BluetoothMetricsProto.ScanEvent.ScanTechnologyType.SCAN_TECH_TYPE_LE) - .setEventTimeMillis(System.currentTimeMillis()) - .setInitiator(truncateAppName(appName)) - .setNumberResults(scan.results) - .build(); + BluetoothMetricsProto.ScanEvent scanEvent = + BluetoothMetricsProto.ScanEvent.newBuilder() + .setScanEventType( + BluetoothMetricsProto.ScanEvent.ScanEventType.SCAN_EVENT_STOP) + .setScanTechnologyType( + BluetoothMetricsProto.ScanEvent.ScanTechnologyType + .SCAN_TECH_TYPE_LE) + .setEventTimeMillis(System.currentTimeMillis()) + .setInitiator(truncateAppName(appName)) + .setNumberResults(scan.results) + .build(); mScanHelper.addScanEvent(scanEvent); mTotalScanTime += scanDuration; @@ -340,12 +368,19 @@ public class AppScanStats { !(scan.isFilterScan || scan.isBackgroundScan || scan.isOpportunisticScan); mBatteryStatsManager.reportBleScanResults(mWorkSource, scan.results % 100); mBatteryStatsManager.reportBleScanStopped(mWorkSource, isUnoptimized); - BluetoothStatsLog.write(BluetoothStatsLog.BLE_SCAN_RESULT_RECEIVED, - mWorkSourceUtil.getUids(), mWorkSourceUtil.getTags(), scan.results % 100); - BluetoothStatsLog.write(BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, - mWorkSourceUtil.getUids(), mWorkSourceUtil.getTags(), + BluetoothStatsLog.write( + BluetoothStatsLog.BLE_SCAN_RESULT_RECEIVED, + mWorkSourceUtil.getUids(), + mWorkSourceUtil.getTags(), + scan.results % 100); + BluetoothStatsLog.write( + BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, + mWorkSourceUtil.getUids(), + mWorkSourceUtil.getTags(), BluetoothStatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF, - scan.isFilterScan, scan.isBackgroundScan, scan.isOpportunisticScan); + scan.isFilterScan, + scan.isBackgroundScan, + scan.isOpportunisticScan); recordScanAppCountMetricsStop(scan); } @@ -642,7 +677,7 @@ public class AppScanStats { } if (filter.getServiceSolicitationUuidMask() != null) { filterString += - " ServiceSolicitationUuidMask=" + filter.getServiceSolicitationUuidMask(); + " ServiceSolicitationUuidMask=" + filter.getServiceSolicitationUuidMask(); } if (filter.getServiceDataUuid() != null) { filterString += " ServiceDataUuid=" + Objects.toString(filter.getServiceDataUuid()); @@ -661,13 +696,12 @@ public class AppScanStats { } if (filter.getManufacturerDataMask() != null) { filterString += - " ManufacturerDataMask=" + Arrays.toString(filter.getManufacturerDataMask()); + " ManufacturerDataMask=" + Arrays.toString(filter.getManufacturerDataMask()); } filterString += " ]"; return filterString; } - private static String scanModeToString(int scanMode) { switch (scanMode) { case ScanSettings.SCAN_MODE_OPPORTUNISTIC: @@ -696,9 +730,11 @@ public class AppScanStats { case ScanSettings.CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH: return "ALL_MATCHES_AUTO_BATCH"; default: - return callbackType == (ScanSettings.CALLBACK_TYPE_FIRST_MATCH - | ScanSettings.CALLBACK_TYPE_MATCH_LOST) ? "[FIRST_MATCH | LOST]" : "UNKNOWN: " - + callbackType; + return callbackType + == (ScanSettings.CALLBACK_TYPE_FIRST_MATCH + | ScanSettings.CALLBACK_TYPE_MATCH_LOST) + ? "[FIRST_MATCH | LOST]" + : "UNKNOWN: " + callbackType; } } @@ -768,23 +804,49 @@ public class AppScanStats { sb.append(" (Registered)"); } - sb.append("\n LE scans (started/stopped) : " - + mScansStarted + " / " + mScansStopped); - sb.append("\n Scan time in ms (active/suspend/total) : " - + totalActiveTime + " / " + totalSuspendTime + " / " + totalScanTime); - sb.append("\n Scan time with mode in ms " - + "(Opp/LowPower/Balanced/LowLatency/AmbientDiscovery):" - + oppScanTime + " / " + lowPowerScanTime + " / " + balancedScanTime + " / " - + lowLatencyScanTime + " / " + ambientDiscoveryScanTime); - sb.append("\n Scan mode counter (Opp/LowPower/Balanced/LowLatency/AmbientDiscovery):" - + oppScan + " / " + lowPowerScan + " / " + balancedScan + " / " + lowLatencyScan - + " / " + ambientDiscoveryScan); + sb.append( + "\n LE scans (started/stopped) : " + + mScansStarted + + " / " + + mScansStopped); + sb.append( + "\n Scan time in ms (active/suspend/total) : " + + totalActiveTime + + " / " + + totalSuspendTime + + " / " + + totalScanTime); + sb.append( + "\n Scan time with mode in ms " + + "(Opp/LowPower/Balanced/LowLatency/AmbientDiscovery):" + + oppScanTime + + " / " + + lowPowerScanTime + + " / " + + balancedScanTime + + " / " + + lowLatencyScanTime + + " / " + + ambientDiscoveryScanTime); + sb.append( + "\n Scan mode counter (Opp/LowPower/Balanced/LowLatency/AmbientDiscovery):" + + oppScan + + " / " + + lowPowerScan + + " / " + + balancedScan + + " / " + + lowLatencyScan + + " / " + + ambientDiscoveryScan); sb.append("\n Score : " + Score); sb.append("\n Total number of results : " + results); if (!mLastScans.isEmpty()) { - sb.append("\n Last " + mLastScans.size() - + " scans :"); + sb.append( + "\n Last " + + mLastScans.size() + + " scans :"); for (int i = 0; i < mLastScans.size(); i++) { LastScan scan = mLastScans.get(i); @@ -819,12 +881,20 @@ public class AppScanStats { } if (scan.suspendDuration != 0) { activeDuration = scan.duration - scan.suspendDuration; - sb.append("\n └ " + "Suspended Time: " + scan.suspendDuration - + "ms, Active Time: " + activeDuration); + sb.append( + "\n └ " + + "Suspended Time: " + + scan.suspendDuration + + "ms, Active Time: " + + activeDuration); } - sb.append("\n └ " + "Scan Config: [ ScanMode=" - + scanModeToString(scan.scanMode) + ", callbackType=" - + callbackTypeToString(scan.scanCallbackType) + " ]"); + sb.append( + "\n └ " + + "Scan Config: [ ScanMode=" + + scanModeToString(scan.scanMode) + + ", callbackType=" + + callbackTypeToString(scan.scanCallbackType) + + " ]"); if (scan.isFilterScan) { sb.append(scan.filterString); } @@ -869,12 +939,20 @@ public class AppScanStats { } if (scan.suspendStartTime != 0) { activeDuration = scan.duration - scan.suspendDuration; - sb.append("\n └ " + "Suspended Time:" + scan.suspendDuration - + "ms, Active Time:" + activeDuration); + sb.append( + "\n └ " + + "Suspended Time:" + + scan.suspendDuration + + "ms, Active Time:" + + activeDuration); } - sb.append("\n └ " + "Scan Config: [ ScanMode=" - + scanModeToString(scan.scanMode) + ", callbackType=" - + callbackTypeToString(scan.scanCallbackType) + " ]"); + sb.append( + "\n └ " + + "Scan Config: [ ScanMode=" + + scanModeToString(scan.scanMode) + + ", callbackType=" + + callbackTypeToString(scan.scanCallbackType) + + " ]"); if (scan.isFilterScan) { sb.append(scan.filterString); } diff --git a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java index 0a0b8533ebc..5288a4ec8b9 100644 --- a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java @@ -36,9 +36,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -/** - * Manages Bluetooth LE Periodic scans - */ +/** Manages Bluetooth LE Periodic scans */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public class PeriodicScanManager { private static final String TAG = GattServiceConfig.TAG_PREFIX + "SyncManager"; @@ -86,7 +84,12 @@ public class PeriodicScanManager { public SyncDeathRecipient deathRecipient; public IPeriodicAdvertisingCallback callback; - SyncInfo(Integer id, Integer advSid, String address, Integer skip, Integer timeout, + SyncInfo( + Integer id, + Integer advSid, + String address, + Integer skip, + Integer timeout, SyncDeathRecipient deathRecipient, IPeriodicAdvertisingCallback callback) { this.id = id; @@ -155,19 +158,30 @@ public class PeriodicScanManager { if (e.getValue().id != syncHandle) { continue; } - syncMap.put(e.getKey(), new SyncInfo(e.getValue().id, - e.getValue().advSid, - e.getValue().address, - e.getValue().skip, - e.getValue().timeout, - e.getValue().deathRecipient, - e.getValue().callback)); + syncMap.put( + e.getKey(), + new SyncInfo( + e.getValue().id, + e.getValue().advSid, + e.getValue().address, + e.getValue().skip, + e.getValue().timeout, + e.getValue().deathRecipient, + e.getValue().callback)); } return syncMap; } - void onSyncStarted(int regId, int syncHandle, int sid, int addressType, String address, int phy, - int interval, int status) throws Exception { + void onSyncStarted( + int regId, + int syncHandle, + int sid, + int addressType, + String address, + int phy, + int interval, + int status) + throws Exception { Map syncMap = findAllSync(regId); if (syncMap.size() == 0) { Log.d(TAG, "onSyncStarted() - no callback found for regId " + regId); @@ -183,9 +197,15 @@ public class PeriodicScanManager { IPeriodicAdvertisingCallback callback = e.getValue().callback; if (status == 0) { Log.d(TAG, "onSyncStarted: updating id with syncHandle " + syncHandle); - e.setValue(new SyncInfo(syncHandle, sid, address, e.getValue().skip, - e.getValue().timeout, e.getValue().deathRecipient, - callback)); + e.setValue( + new SyncInfo( + syncHandle, + sid, + address, + e.getValue().skip, + e.getValue().timeout, + e.getValue().deathRecipient, + callback)); callback.onSyncEstablished( syncHandle, mAdapter.getRemoteLeDevice(address, addressType), @@ -216,11 +236,11 @@ public class PeriodicScanManager { Log.i(TAG, "onSyncReport() - no callback found for syncHandle " + syncHandle); return; } - for (Map.Entry e :syncMap.entrySet()) { + for (Map.Entry e : syncMap.entrySet()) { IPeriodicAdvertisingCallback callback = e.getValue().callback; PeriodicAdvertisingReport report = - new PeriodicAdvertisingReport(syncHandle, txPower, rssi, dataStatus, - ScanRecord.parseFromBytes(data)); + new PeriodicAdvertisingReport( + syncHandle, txPower, rssi, dataStatus, ScanRecord.parseFromBytes(data)); callback.onPeriodicAdvertisingReport(report); } } @@ -231,14 +251,13 @@ public class PeriodicScanManager { Log.i(TAG, "onSyncLost() - no callback found for syncHandle " + syncHandle); return; } - for (Map.Entry e :syncMap.entrySet()) { + for (Map.Entry e : syncMap.entrySet()) { IPeriodicAdvertisingCallback callback = e.getValue().callback; IBinder binder = toBinder(callback); synchronized (mSyncs) { mSyncs.remove(binder); } callback.onSyncLost(syncHandle); - } } @@ -254,8 +273,8 @@ public class PeriodicScanManager { } } - public void startSync(ScanResult scanResult, int skip, int timeout, - IPeriodicAdvertisingCallback callback) { + public void startSync( + ScanResult scanResult, int skip, int timeout, IPeriodicAdvertisingCallback callback) { SyncDeathRecipient deathRecipient = new SyncDeathRecipient(callback); IBinder binder = toBinder(callback); try { @@ -278,11 +297,18 @@ public class PeriodicScanManager { synchronized (mSyncs) { Map.Entry entry = findMatchingSync(sid, address); if (entry != null) { - //Found matching sync. Copy sync handle + // Found matching sync. Copy sync handle Log.d(TAG, "startSync: Matching entry found"); - mSyncs.put(binder, new SyncInfo(entry.getValue().id, sid, address, - entry.getValue().skip, entry.getValue().timeout, deathRecipient, - callback)); + mSyncs.put( + binder, + new SyncInfo( + entry.getValue().id, + sid, + address, + entry.getValue().skip, + entry.getValue().timeout, + deathRecipient, + callback)); if (entry.getValue().id >= 0) { try { callback.onSyncEstablished( @@ -303,8 +329,8 @@ public class PeriodicScanManager { } int cbId = --sTempRegistrationId; - mSyncs.put(binder, new SyncInfo(cbId, sid, address, skip, timeout, - deathRecipient, callback)); + mSyncs.put( + binder, new SyncInfo(cbId, sid, address, skip, timeout, deathRecipient, callback)); Log.d(TAG, "startSync() - reg_id=" + cbId + ", callback: " + binder); mNativeInterface.startSync(sid, address, skip, timeout, cbId); @@ -362,14 +388,17 @@ public class PeriodicScanManager { Log.d(TAG, "transferSync: callback not registered"); return; } - //check for duplicate transfers - mSyncTransfers.put(entry.getKey(), new SyncTransferInfo(bda.getAddress(), - entry.getValue().callback)); + // check for duplicate transfers + mSyncTransfers.put( + entry.getKey(), new SyncTransferInfo(bda.getAddress(), entry.getValue().callback)); mNativeInterface.syncTransfer(bda, serviceData, syncHandle); } - public void transferSetInfo(BluetoothDevice bda, int serviceData, - int advHandle, IPeriodicAdvertisingCallback callback) { + public void transferSetInfo( + BluetoothDevice bda, + int serviceData, + int advHandle, + IPeriodicAdvertisingCallback callback) { SyncDeathRecipient deathRecipient = new SyncDeathRecipient(callback); IBinder binder = toBinder(callback); Log.d(TAG, "transferSetInfo() " + binder); diff --git a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java index 7372a6817ac..0d06dfb0cc6 100644 --- a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java @@ -126,9 +126,7 @@ public class PeriodicScanNativeInterface { void onBigInfoReport(int syncHandle, boolean encrypted) throws Exception { Log.d( TAG, - "onBigInfoReport():" - + (" syncHandle=" + syncHandle) - + (" encrypted=" + encrypted)); + "onBigInfoReport():" + (" syncHandle=" + syncHandle) + (" encrypted=" + encrypted)); mManager.onBigInfoReport(syncHandle, encrypted); } diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanClient.java b/android/app/src/com/android/bluetooth/le_scan/ScanClient.java index 21ca3c3ebe4..bc6f206bafc 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanClient.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanClient.java @@ -24,9 +24,7 @@ import android.os.UserHandle; import java.util.List; import java.util.Objects; -/** - * Helper class identifying a client that has requested LE scan results. - */ +/** Helper class identifying a client that has requested LE scan results. */ public class ScanClient { public int scannerId; public ScanSettings settings; @@ -88,8 +86,10 @@ public class ScanClient { public String toString() { StringBuilder sb = new StringBuilder(); sb.append(" [ScanClient") - .append(" scanModeApp ").append(scanModeApp) - .append(" scanModeUsed ").append(settings.getScanMode()); + .append(" scanModeApp ") + .append(scanModeApp) + .append(" scanModeUsed ") + .append(settings.getScanMode()); if (stats != null && stats.appName != null) { sb.append(" [appScanStats ").append(stats.appName).append("]"); } @@ -99,6 +99,7 @@ public class ScanClient { /** * Update scan settings with the new scan mode. + * * @param newScanMode * @return true if scan settings are updated, false otherwise. */ @@ -108,15 +109,16 @@ public class ScanClient { } ScanSettings.Builder builder = new ScanSettings.Builder(); - settings = builder.setScanMode(newScanMode) - .setCallbackType(settings.getCallbackType()) - .setScanResultType(settings.getScanResultType()) - .setReportDelay(settings.getReportDelayMillis()) - .setNumOfMatches(settings.getNumOfMatches()) - .setMatchMode(settings.getMatchMode()) - .setLegacy(settings.getLegacy()) - .setPhy(settings.getPhy()) - .build(); + settings = + builder.setScanMode(newScanMode) + .setCallbackType(settings.getCallbackType()) + .setScanResultType(settings.getScanResultType()) + .setReportDelay(settings.getReportDelayMillis()) + .setNumOfMatches(settings.getNumOfMatches()) + .setMatchMode(settings.getMatchMode()) + .setLegacy(settings.getLegacy()) + .setPhy(settings.getPhy()) + .build(); return true; } } diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java b/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java index cd100ee30a4..68df1664bde 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java @@ -28,9 +28,7 @@ import java.util.Iterator; import java.util.Set; import java.util.UUID; -/** - * Helper class used to manage advertisement package filters. - */ +/** Helper class used to manage advertisement package filters. */ /* package */ class ScanFilterQueue { public static final int TYPE_DEVICE_ADDRESS = 0; public static final int TYPE_SERVICE_DATA_CHANGED = 1; @@ -154,8 +152,14 @@ import java.util.UUID; mEntries.add(entry); } - void addTransportDiscoveryData(int orgId, int tdsFlags, int tdsFlagsMask, - byte[] transportData, byte[] transportDataMask, int metaDataType, byte[] metaData) { + void addTransportDiscoveryData( + int orgId, + int tdsFlags, + int tdsFlagsMask, + byte[] transportData, + byte[] transportDataMask, + int metaDataType, + byte[] metaData) { Entry entry = new Entry(); entry.type = TYPE_TRANSPORT_DISCOVERY_DATA; entry.org_id = orgId; @@ -187,9 +191,7 @@ import java.util.UUID; return entry; } - /** - * Compute feature selection based on the filters presented. - */ + /** Compute feature selection based on the filters presented. */ int getFeatureSelection() { int selc = 0; for (Entry entry : mEntries) { @@ -202,9 +204,7 @@ import java.util.UUID; return mEntries.toArray(new ScanFilterQueue.Entry[mEntries.size()]); } - /** - * Add ScanFilter to scan filter queue. - */ + /** Add ScanFilter to scan filter queue. */ void addScanFilter(ScanFilter filter) { if (filter == null) { return; @@ -218,8 +218,8 @@ import java.util.UUID; * however, the host stack will force the type to 0x02 for the APCF filter in * btm_ble_adv_filter.cc#BTM_LE_PF_addr_filter(...) */ - addDeviceAddress(filter.getDeviceAddress(), (byte) filter.getAddressType(), - filter.getIrk()); + addDeviceAddress( + filter.getDeviceAddress(), (byte) filter.getAddressType(), filter.getIrk()); } if (filter.getServiceUuid() != null) { if (filter.getServiceUuidMask() == null) { @@ -232,7 +232,8 @@ import java.util.UUID; if (filter.getServiceSolicitationUuidMask() == null) { addSolicitUuid(filter.getServiceSolicitationUuid().getUuid()); } else { - addSolicitUuid(filter.getServiceSolicitationUuid().getUuid(), + addSolicitUuid( + filter.getServiceSolicitationUuid().getUuid(), filter.getServiceSolicitationUuidMask().getUuid()); } } @@ -240,8 +241,11 @@ import java.util.UUID; if (filter.getManufacturerDataMask() == null) { addManufacturerData(filter.getManufacturerId(), filter.getManufacturerData()); } else { - addManufacturerData(filter.getManufacturerId(), 0xFFFF, - filter.getManufacturerData(), filter.getManufacturerDataMask()); + addManufacturerData( + filter.getManufacturerId(), + 0xFFFF, + filter.getManufacturerData(), + filter.getManufacturerDataMask()); } } if (filter.getServiceDataUuid() != null && filter.getServiceData() != null) { @@ -259,23 +263,33 @@ import java.util.UUID; } } if (filter.getAdvertisingDataType() > 0) { - addAdvertisingDataType(filter.getAdvertisingDataType(), - filter.getAdvertisingData(), filter.getAdvertisingDataMask()); + addAdvertisingDataType( + filter.getAdvertisingDataType(), + filter.getAdvertisingData(), + filter.getAdvertisingDataMask()); } final TransportBlockFilter transportBlockFilter = filter.getTransportBlockFilter(); if (transportBlockFilter != null) { if (transportBlockFilter.getOrgId() == OrganizationId.WIFI_ALLIANCE_NEIGHBOR_AWARENESS_NETWORKING) { - addTransportDiscoveryData(transportBlockFilter.getOrgId(), - transportBlockFilter.getTdsFlags(), transportBlockFilter.getTdsFlagsMask(), - null, null, TYPE_WIFI_NAN_HASH, transportBlockFilter.getWifiNanHash()); + addTransportDiscoveryData( + transportBlockFilter.getOrgId(), + transportBlockFilter.getTdsFlags(), + transportBlockFilter.getTdsFlagsMask(), + null, + null, + TYPE_WIFI_NAN_HASH, + transportBlockFilter.getWifiNanHash()); } else { - addTransportDiscoveryData(transportBlockFilter.getOrgId(), - transportBlockFilter.getTdsFlags(), transportBlockFilter.getTdsFlagsMask(), + addTransportDiscoveryData( + transportBlockFilter.getOrgId(), + transportBlockFilter.getTdsFlags(), + transportBlockFilter.getTdsFlagsMask(), transportBlockFilter.getTransportData(), - transportBlockFilter.getTransportDataMask(), TYPE_INVALID, null); + transportBlockFilter.getTransportDataMask(), + TYPE_INVALID, + null); } - } } diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java index 42d9850b3c1..0a95c12faf8 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java @@ -65,16 +65,13 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -/** - * Class that handles Bluetooth LE scan related operations. - */ +/** Class that handles Bluetooth LE scan related operations. */ public class ScanManager { private static final String TAG = GattServiceConfig.TAG_PREFIX + "ScanManager"; - /** - * Scan params corresponding to regular scan setting - */ + /** Scan params corresponding to regular scan setting */ private static final int SCAN_MODE_LOW_POWER_WINDOW_MS = 140; + private static final int SCAN_MODE_LOW_POWER_INTERVAL_MS = 1400; private static final int SCAN_MODE_BALANCED_WINDOW_MS = 183; private static final int SCAN_MODE_BALANCED_INTERVAL_MS = 730; @@ -91,8 +88,7 @@ public class ScanManager { static final int SCAN_RESULT_TYPE_BOTH = 3; // Messages for handling BLE scan operations. - @VisibleForTesting - static final int MSG_START_BLE_SCAN = 0; + @VisibleForTesting static final int MSG_START_BLE_SCAN = 0; static final int MSG_STOP_BLE_SCAN = 1; static final int MSG_FLUSH_BATCH_RESULTS = 2; static final int MSG_SCAN_TIMEOUT = 3; @@ -117,6 +113,7 @@ public class ScanManager { private BatchScanParams mBatchScanParams; private final Object mCurUsedTrackableAdvertisementsLock = new Object(); + @GuardedBy("mCurUsedTrackableAdvertisementsLock") private int mCurUsedTrackableAdvertisements = 0; @@ -199,8 +196,8 @@ public class ScanManager { AppScanStats.initScanRadioState(); AppScanStats.setScreenState(mScreenOn); if (mActivityManager != null) { - mActivityManager.addOnUidImportanceListener(mUidImportanceListener, - FOREGROUND_IMPORTANCE_CUTOFF); + mActivityManager.addOnUidImportanceListener( + mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF); } IntentFilter locationIntentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); locationIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -243,38 +240,29 @@ public class ScanManager { } public void registerScanner(UUID uuid) { - mScanNative.registerScanner(uuid.getLeastSignificantBits(), - uuid.getMostSignificantBits()); + mScanNative.registerScanner(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); } public void unregisterScanner(int scannerId) { mScanNative.unregisterScanner(scannerId); } - /** - * Returns the regular scan queue. - */ + /** Returns the regular scan queue. */ public Set getRegularScanQueue() { return mRegularScanClients; } - /** - * Returns the suspended scan queue. - */ + /** Returns the suspended scan queue. */ Set getSuspendedScanQueue() { return mSuspendedScanClients; } - /** - * Returns batch scan queue. - */ + /** Returns batch scan queue. */ public Set getBatchScanQueue() { return mBatchClients; } - /** - * Returns a set of full batch scan clients. - */ + /** Returns a set of full batch scan clients. */ public Set getFullBatchScanQueue() { // TODO: split full batch scan clients and truncated batch clients so we don't need to // construct this every time. @@ -404,8 +392,11 @@ public class ScanManager { } if (requiresScreenOn(client) && !mScreenOn) { - Log.w(TAG, "Cannot start unfiltered scan in screen-off. This scan will be resumed " - + "later: " + client.scannerId); + Log.w( + TAG, + "Cannot start unfiltered scan in screen-off. This scan will be resumed " + + "later: " + + client.scannerId); mSuspendedScanClients.add(client); if (client.stats != null) { client.stats.recordScanSuspend(client.scannerId); @@ -415,8 +406,11 @@ public class ScanManager { final boolean locationEnabled = mLocationManager.isLocationEnabled(); if (requiresLocationOn(client) && !locationEnabled) { - Log.i(TAG, "Cannot start unfiltered scan in location-off. This scan will be" - + " resumed when location is on: " + client.scannerId); + Log.i( + TAG, + "Cannot start unfiltered scan in location-off. This scan will be" + + " resumed when location is on: " + + client.scannerId); mSuspendedScanClients.add(client); if (client.stats != null) { client.stats.recordScanSuspend(client.scannerId); @@ -450,9 +444,13 @@ public class ScanManager { // Only one timeout message should exist at any time removeMessages(MSG_SCAN_TIMEOUT, client); sendMessageDelayed(msg, mAdapterService.getScanTimeoutMillis()); - Log.d(TAG, - "apply scan timeout (" + mAdapterService.getScanTimeoutMillis() - + ")" + "to scannerId " + client.scannerId); + Log.d( + TAG, + "apply scan timeout (" + + mAdapterService.getScanTimeoutMillis() + + ")" + + "to scannerId " + + client.scannerId); } } } @@ -912,9 +910,7 @@ public class ScanManager { } } - /** - * Parameters for batch scans. - */ + /** Parameters for batch scans. */ class BatchScanParams { public int scanMode; public int fullScanscannerId; @@ -935,9 +931,9 @@ public class ScanManager { return false; } BatchScanParams other = (BatchScanParams) obj; - return scanMode == other.scanMode && fullScanscannerId == other.fullScanscannerId + return scanMode == other.scanMode + && fullScanscannerId == other.fullScanscannerId && truncatedScanscannerId == other.truncatedScanscannerId; - } } @@ -963,11 +959,9 @@ public class ScanManager { private static final int DISCARD_OLDEST_WHEN_BUFFER_FULL = 0; - - /** - * Onfound/onlost for scan settings - */ + /** Onfound/onlost for scan settings */ private static final int MATCH_MODE_AGGRESSIVE_TIMEOUT_FACTOR = (1); + private static final int MATCH_MODE_STICKY_TIMEOUT_FACTOR = (3); private static final int ONLOST_FACTOR = 2; private static final int ONLOST_ONFOUND_BASE_TIMEOUT_MS = 500; @@ -1109,7 +1103,8 @@ public class ScanManager { } void startRegularScan(ScanClient client) { - if (isFilteringSupported() && mFilterIndexStack.isEmpty() + if (isFilteringSupported() + && mFilterIndexStack.isEmpty() && mClientFilterIndexMap.isEmpty()) { initFilterIndexStack(); } @@ -1209,16 +1204,21 @@ public class ScanManager { int fullScanPercent = getFullScanStoragePercent(resultType); resetCountDownLatch(); Log.d(TAG, "configuring batch scan storage, appIf " + client.scannerId); - mNativeInterface.gattClientConfigBatchScanStorage(client.scannerId, fullScanPercent, - 100 - fullScanPercent, notifyThreshold); + mNativeInterface.gattClientConfigBatchScanStorage( + client.scannerId, fullScanPercent, 100 - fullScanPercent, notifyThreshold); waitForCallback(); resetCountDownLatch(); int scanInterval = Utils.millsToUnit(getBatchScanIntervalMillis(batchScanParams.scanMode)); int scanWindow = Utils.millsToUnit(getBatchScanWindowMillis(batchScanParams.scanMode)); - mNativeInterface.gattClientStartBatchScan(scannerId, resultType, scanInterval, - scanWindow, 0, DISCARD_OLDEST_WHEN_BUFFER_FULL); + mNativeInterface.gattClientStartBatchScan( + scannerId, + resultType, + scanInterval, + scanWindow, + 0, + DISCARD_OLDEST_WHEN_BUFFER_FULL); waitForCallback(); } mBatchScanParams = batchScanParams; @@ -1267,16 +1267,16 @@ public class ScanManager { switch (scanMode) { case ScanSettings.SCAN_MODE_LOW_LATENCY: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_BALANCED_WINDOW_MS, - SCAN_MODE_BALANCED_WINDOW_MS); + resolver, + Settings.Global.BLE_SCAN_BALANCED_WINDOW_MS, + SCAN_MODE_BALANCED_WINDOW_MS); case ScanSettings.SCAN_MODE_SCREEN_OFF: return mAdapterService.getScreenOffLowPowerWindowMillis(); default: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_POWER_WINDOW_MS, - SCAN_MODE_LOW_POWER_WINDOW_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_POWER_WINDOW_MS, + SCAN_MODE_LOW_POWER_WINDOW_MS); } } @@ -1285,16 +1285,16 @@ public class ScanManager { switch (scanMode) { case ScanSettings.SCAN_MODE_LOW_LATENCY: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_BALANCED_INTERVAL_MS, - SCAN_MODE_BALANCED_INTERVAL_MS); + resolver, + Settings.Global.BLE_SCAN_BALANCED_INTERVAL_MS, + SCAN_MODE_BALANCED_INTERVAL_MS); case ScanSettings.SCAN_MODE_SCREEN_OFF: return mAdapterService.getScreenOffLowPowerIntervalMillis(); default: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_POWER_INTERVAL_MS, - SCAN_MODE_LOW_POWER_INTERVAL_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_POWER_INTERVAL_MS, + SCAN_MODE_LOW_POWER_INTERVAL_MS); } } @@ -1311,8 +1311,11 @@ public class ScanManager { // [batchTriggerIntervalMillis, 1.1 * batchTriggerIntervalMillis] long windowLengthMillis = batchTriggerIntervalMillis / 10; long windowStartMillis = SystemClock.elapsedRealtime() + batchTriggerIntervalMillis; - mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, windowStartMillis, - windowLengthMillis, mBatchScanIntervalIntent); + mAlarmManager.setWindow( + AlarmManager.ELAPSED_REALTIME_WAKEUP, + windowStartMillis, + windowLengthMillis, + mBatchScanIntervalIntent); } void stopRegularScan(ScanClient client) { @@ -1355,9 +1358,11 @@ public class ScanManager { && (client.stats == null || client.stats.isScanningTooLong())) { Log.d(TAG, "regularScanTimeout - client scan time was too long"); if (client.filters == null || client.filters.isEmpty()) { - Log.w(TAG, + Log.w( + TAG, "Moving unfiltered scan client to opportunistic scan (scannerId " - + client.scannerId + ")"); + + client.scannerId + + ")"); setOpportunisticScanClient(client); removeScanFilters(client.scannerId); @@ -1489,12 +1494,13 @@ public class ScanManager { if (shouldUseAllPassFilter(client)) { int filterIndex = - (deliveryMode == DELIVERY_MODE_BATCH) ? ALL_PASS_FILTER_INDEX_BATCH_SCAN + (deliveryMode == DELIVERY_MODE_BATCH) + ? ALL_PASS_FILTER_INDEX_BATCH_SCAN : ALL_PASS_FILTER_INDEX_REGULAR_SCAN; resetCountDownLatch(); // Don't allow Onfound/onlost with all pass - configureFilterParameter(scannerId, client, ALL_PASS_FILTER_SELECTION, filterIndex, - 0); + configureFilterParameter( + scannerId, client, ALL_PASS_FILTER_SELECTION, filterIndex, 0); waitForCallback(); } else { Deque clientFilterIndices = new ArrayDeque(); @@ -1505,8 +1511,8 @@ public class ScanManager { int filterIndex = mFilterIndexStack.pop(); resetCountDownLatch(); - mNativeInterface.gattClientScanFilterAdd(scannerId, queue.toArray(), - filterIndex); + mNativeInterface.gattClientScanFilterAdd( + scannerId, queue.toArray(), filterIndex); waitForCallback(); resetCountDownLatch(); @@ -1528,8 +1534,8 @@ public class ScanManager { } } } - configureFilterParameter(scannerId, client, featureSelection, filterIndex, - trackEntries); + configureFilterParameter( + scannerId, client, featureSelection, filterIndex, trackEntries); waitForCallback(); clientFilterIndices.add(filterIndex); } @@ -1565,10 +1571,10 @@ public class ScanManager { } } // Remove if ALL_PASS filters are used. - removeFilterIfExisits(mAllPassRegularClients, scannerId, - ALL_PASS_FILTER_INDEX_REGULAR_SCAN); - removeFilterIfExisits(mAllPassBatchClients, scannerId, - ALL_PASS_FILTER_INDEX_BATCH_SCAN); + removeFilterIfExisits( + mAllPassRegularClients, scannerId, ALL_PASS_FILTER_INDEX_REGULAR_SCAN); + removeFilterIfExisits( + mAllPassBatchClients, scannerId, ALL_PASS_FILTER_INDEX_BATCH_SCAN); } private void removeFilterIfExisits(Set clients, int scannerId, int filterIndex) { @@ -1593,9 +1599,7 @@ public class ScanManager { return null; } - /** - * Return batch scan result type value defined in bt stack. - */ + /** Return batch scan result type value defined in bt stack. */ private int getResultType(BatchScanParams params) { if (params.fullScanscannerId != -1 && params.truncatedScanscannerId != -1) { return SCAN_RESULT_TYPE_BOTH; @@ -1640,20 +1644,42 @@ public class ScanManager { } // Configure filter parameters. - private void configureFilterParameter(int scannerId, ScanClient client, - int featureSelection, int filterIndex, int numOfTrackingEntries) { + private void configureFilterParameter( + int scannerId, + ScanClient client, + int featureSelection, + int filterIndex, + int numOfTrackingEntries) { int deliveryMode = getDeliveryMode(client); int rssiThreshold = Byte.MIN_VALUE; ScanSettings settings = client.settings; int onFoundTimeout = getOnFoundOnLostTimeoutMillis(settings, true); int onFoundCount = getOnFoundOnLostSightings(settings); int onLostTimeout = 10000; - Log.d(TAG, "configureFilterParameter " + onFoundTimeout + " " + onLostTimeout + " " - + onFoundCount + " " + numOfTrackingEntries); + Log.d( + TAG, + "configureFilterParameter " + + onFoundTimeout + + " " + + onLostTimeout + + " " + + onFoundCount + + " " + + numOfTrackingEntries); FilterParams filtValue = - new FilterParams(scannerId, filterIndex, featureSelection, LIST_LOGIC_TYPE, - FILTER_LOGIC_TYPE, rssiThreshold, rssiThreshold, deliveryMode, - onFoundTimeout, onLostTimeout, onFoundCount, numOfTrackingEntries); + new FilterParams( + scannerId, + filterIndex, + featureSelection, + LIST_LOGIC_TYPE, + FILTER_LOGIC_TYPE, + rssiThreshold, + rssiThreshold, + deliveryMode, + onFoundTimeout, + onLostTimeout, + onFoundCount, + numOfTrackingEntries); mNativeInterface.gattClientScanFilterParamAdd(filtValue); } @@ -1675,7 +1701,8 @@ public class ScanManager { ? DELIVERY_MODE_BATCH : DELIVERY_MODE_IMMEDIATE; } - return settings.getReportDelayMillis() == 0 ? DELIVERY_MODE_IMMEDIATE + return settings.getReportDelayMillis() == 0 + ? DELIVERY_MODE_IMMEDIATE : DELIVERY_MODE_BATCH; } @@ -1683,28 +1710,28 @@ public class ScanManager { ContentResolver resolver = mContext.getContentResolver(); if (settings == null) { return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_POWER_WINDOW_MS, - SCAN_MODE_LOW_POWER_WINDOW_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_POWER_WINDOW_MS, + SCAN_MODE_LOW_POWER_WINDOW_MS); } switch (settings.getScanMode()) { case ScanSettings.SCAN_MODE_LOW_LATENCY: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_LATENCY_WINDOW_MS, - SCAN_MODE_LOW_LATENCY_WINDOW_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_LATENCY_WINDOW_MS, + SCAN_MODE_LOW_LATENCY_WINDOW_MS); case ScanSettings.SCAN_MODE_BALANCED: case ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_BALANCED_WINDOW_MS, - SCAN_MODE_BALANCED_WINDOW_MS); + resolver, + Settings.Global.BLE_SCAN_BALANCED_WINDOW_MS, + SCAN_MODE_BALANCED_WINDOW_MS); case ScanSettings.SCAN_MODE_LOW_POWER: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_POWER_WINDOW_MS, - SCAN_MODE_LOW_POWER_WINDOW_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_POWER_WINDOW_MS, + SCAN_MODE_LOW_POWER_WINDOW_MS); case ScanSettings.SCAN_MODE_SCREEN_OFF: return mAdapterService.getScreenOffLowPowerWindowMillis(); case ScanSettings.SCAN_MODE_SCREEN_OFF_BALANCED: @@ -1721,22 +1748,22 @@ public class ScanManager { ContentResolver resolver = mContext.getContentResolver(); if (settings == null) { return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_POWER_INTERVAL_MS, - SCAN_MODE_LOW_POWER_INTERVAL_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_POWER_INTERVAL_MS, + SCAN_MODE_LOW_POWER_INTERVAL_MS); } switch (settings.getScanMode()) { case ScanSettings.SCAN_MODE_LOW_LATENCY: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_LATENCY_INTERVAL_MS, - SCAN_MODE_LOW_LATENCY_INTERVAL_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_LATENCY_INTERVAL_MS, + SCAN_MODE_LOW_LATENCY_INTERVAL_MS); case ScanSettings.SCAN_MODE_BALANCED: case ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_BALANCED_INTERVAL_MS, - SCAN_MODE_BALANCED_INTERVAL_MS); + resolver, + Settings.Global.BLE_SCAN_BALANCED_INTERVAL_MS, + SCAN_MODE_BALANCED_INTERVAL_MS); case ScanSettings.SCAN_MODE_LOW_POWER: return Settings.Global.getInt( resolver, @@ -1748,9 +1775,9 @@ public class ScanManager { return mAdapterService.getScreenOffBalancedIntervalMillis(); default: return Settings.Global.getInt( - resolver, - Settings.Global.BLE_SCAN_LOW_POWER_INTERVAL_MS, - SCAN_MODE_LOW_POWER_INTERVAL_MS); + resolver, + Settings.Global.BLE_SCAN_LOW_POWER_INTERVAL_MS, + SCAN_MODE_LOW_POWER_INTERVAL_MS); } } @@ -1829,14 +1856,15 @@ public class ScanManager { break; default: val = 1; - Log.d(TAG, "Invalid setting for getNumOfMatches() " - + settings.getNumOfMatches()); + Log.d( + TAG, + "Invalid setting for getNumOfMatches() " + settings.getNumOfMatches()); } return val; } - private boolean manageAllocationOfTrackingAdvertisement(int numOfTrackableAdvertisement, - boolean allocate) { + private boolean manageAllocationOfTrackingAdvertisement( + int numOfTrackableAdvertisement, boolean allocate) { int maxTotalTrackableAdvertisements = AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements(); synchronized (mCurUsedTrackableAdvertisementsLock) { @@ -1986,8 +2014,14 @@ public class ScanManager { break; default: } - Log.d(TAG, "mProfilesConnecting " + mProfilesConnecting + ", mProfilesConnected " - + mProfilesConnected + ", mProfilesDisconnecting " + mProfilesDisconnecting); + Log.d( + TAG, + "mProfilesConnecting " + + mProfilesConnecting + + ", mProfilesConnected " + + mProfilesConnected + + ", mProfilesDisconnecting " + + mProfilesDisconnecting); return (mProfilesConnecting > 0); } @@ -1998,8 +2032,8 @@ public class ScanManager { int uid = imp.uid; int importance = imp.importance; boolean updatedScanParams = false; - boolean isForeground = importance <= ActivityManager.RunningAppProcessInfo - .IMPORTANCE_FOREGROUND_SERVICE; + boolean isForeground = + importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; if (mIsUidForegroundMap.size() < MAX_IS_UID_FOREGROUND_MAP_SIZE) { mIsUidForegroundMap.put(uid, isForeground); @@ -2026,8 +2060,14 @@ public class ScanManager { updatedScanParams = true; } } - Log.d(TAG, "uid " + uid + " isForeground " + isForeground - + " scanMode " + client.settings.getScanMode()); + Log.d( + TAG, + "uid " + + uid + + " isForeground " + + isForeground + + " scanMode " + + client.settings.getScanMode()); } if (updatedScanParams) { diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java b/android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java index b9f77ca2fcc..35ea6775b20 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java @@ -26,9 +26,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -/** - * BLE Scan Native Interface to/from JNI. - */ +/** BLE Scan Native Interface to/from JNI. */ public class ScanNativeInterface { private static final String TAG = ScanNativeInterface.class.getSimpleName(); @@ -74,49 +72,62 @@ public class ScanNativeInterface { private native void initializeNative(); private native void cleanupNative(); + /************************** Regular scan related native methods **************************/ private native void registerScannerNative(long appUuidLsb, long appUuidMsb); + private native void unregisterScannerNative(int scannerId); + private native void gattClientScanNative(boolean start); private native void gattSetScanParametersNative( int clientIf, int scanInterval, int scanWindow, int scanPhy); /************************** Filter related native methods ********************************/ - private native void gattClientScanFilterAddNative(int clientId, - ScanFilterQueue.Entry[] entries, int filterIndex); + private native void gattClientScanFilterAddNative( + int clientId, ScanFilterQueue.Entry[] entries, int filterIndex); + private native void gattClientScanFilterParamAddNative(FilterParams filtValue); + // Note this effectively remove scan filters for ALL clients. private native void gattClientScanFilterParamClearAllNative(int clientIf); + private native void gattClientScanFilterParamDeleteNative(int clientIf, int filtIndex); + private native void gattClientScanFilterClearNative(int clientIf, int filterIndex); + private native void gattClientScanFilterEnableNative(int clientIf, boolean enable); + /************************** Batch related native methods *********************************/ - private native void gattClientConfigBatchScanStorageNative(int clientIf, - int maxFullReportsPercent, int maxTruncatedReportsPercent, + private native void gattClientConfigBatchScanStorageNative( + int clientIf, + int maxFullReportsPercent, + int maxTruncatedReportsPercent, int notifyThresholdPercent); - private native void gattClientStartBatchScanNative(int clientIf, int scanMode, - int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule); + + private native void gattClientStartBatchScanNative( + int clientIf, + int scanMode, + int scanIntervalUnit, + int scanWindowUnit, + int addressType, + int discardRule); + private native void gattClientStopBatchScanNative(int clientIf); + private native void gattClientReadScanReportsNative(int clientIf, int scanType); - /** - * Register BLE scanner - */ + /** Register BLE scanner */ public void registerScanner(long appUuidLsb, long appUuidMsb) { registerScannerNative(appUuidLsb, appUuidMsb); } - /** - * Unregister BLE scanner - */ + /** Unregister BLE scanner */ public void unregisterScanner(int scannerId) { unregisterScannerNative(scannerId); } - /** - * Enable/disable BLE scan - */ + /** Enable/disable BLE scan */ public void gattClientScan(boolean start) { gattClientScanNative(start); } @@ -126,79 +137,69 @@ public class ScanNativeInterface { gattSetScanParametersNative(clientIf, scanInterval, scanWindow, scanPhy); } - /** - * Add BLE scan filter - */ - public void gattClientScanFilterAdd(int clientId, ScanFilterQueue.Entry[] entries, - int filterIndex) { + /** Add BLE scan filter */ + public void gattClientScanFilterAdd( + int clientId, ScanFilterQueue.Entry[] entries, int filterIndex) { gattClientScanFilterAddNative(clientId, entries, filterIndex); } - /** - * Add BLE scan filter parameters - */ + /** Add BLE scan filter parameters */ public void gattClientScanFilterParamAdd(FilterParams filtValue) { gattClientScanFilterParamAddNative(filtValue); } - /** - * Clear all BLE scan filter parameters - */ + /** Clear all BLE scan filter parameters */ // Note this effectively remove scan filters for ALL clients. public void gattClientScanFilterParamClearAll(int clientIf) { gattClientScanFilterParamClearAllNative(clientIf); } - /** - * Delete BLE scan filter parameters - */ + /** Delete BLE scan filter parameters */ public void gattClientScanFilterParamDelete(int clientIf, int filtIndex) { gattClientScanFilterParamDeleteNative(clientIf, filtIndex); } - /** - * Clear BLE scan filter - */ + /** Clear BLE scan filter */ public void gattClientScanFilterClear(int clientIf, int filterIndex) { gattClientScanFilterClearNative(clientIf, filterIndex); } - /** - * Enable/disable BLE scan filter - */ + /** Enable/disable BLE scan filter */ public void gattClientScanFilterEnable(int clientIf, boolean enable) { gattClientScanFilterEnableNative(clientIf, enable); } - /** - * Configure BLE batch scan storage - */ - public void gattClientConfigBatchScanStorage(int clientIf, - int maxFullReportsPercent, int maxTruncatedReportsPercent, + /** Configure BLE batch scan storage */ + public void gattClientConfigBatchScanStorage( + int clientIf, + int maxFullReportsPercent, + int maxTruncatedReportsPercent, int notifyThresholdPercent) { - gattClientConfigBatchScanStorageNative(clientIf, maxFullReportsPercent, - maxTruncatedReportsPercent, notifyThresholdPercent); + gattClientConfigBatchScanStorageNative( + clientIf, + maxFullReportsPercent, + maxTruncatedReportsPercent, + notifyThresholdPercent); } - /** - * Enable BLE batch scan with the parameters - */ - public void gattClientStartBatchScan(int clientIf, int scanMode, - int scanIntervalUnit, int scanWindowUnit, int addressType, int discardRule) { - gattClientStartBatchScanNative(clientIf, scanMode, scanIntervalUnit, scanWindowUnit, - addressType, discardRule); + /** Enable BLE batch scan with the parameters */ + public void gattClientStartBatchScan( + int clientIf, + int scanMode, + int scanIntervalUnit, + int scanWindowUnit, + int addressType, + int discardRule) { + gattClientStartBatchScanNative( + clientIf, scanMode, scanIntervalUnit, scanWindowUnit, addressType, discardRule); } - /** - * Disable BLE batch scan - */ + /** Disable BLE batch scan */ public void gattClientStopBatchScan(int clientIf) { gattClientStopBatchScanNative(clientIf); } - /** - * Read BLE batch scan reports - */ + /** Read BLE batch scan reports */ public void gattClientReadScanReports(int clientIf, int scanType) { gattClientReadScanReportsNative(clientIf, scanType); } diff --git a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java index 8662f43478d..85bfb46dab9 100644 --- a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java +++ b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java @@ -442,10 +442,7 @@ public class TransitionalScanHelper { if (!hasPermission || !matchResult) { Log.v( TAG, - "Skipping client: permission=" - + hasPermission - + " matches=" - + matchResult); + "Skipping client: permission=" + hasPermission + " matches=" + matchResult); continue; } @@ -645,9 +642,7 @@ public class TransitionalScanHelper { /** Callback method for configuration of batch scan storage. */ public void onBatchScanStorageConfigured(int status, int clientIf) { - Log.d( - TAG, - "onBatchScanStorageConfigured() - clientIf=" + clientIf + ", status=" + status); + Log.d(TAG, "onBatchScanStorageConfigured() - clientIf=" + clientIf + ", status=" + status); mScanManager.callbackDone(clientIf, status); } @@ -1383,7 +1378,7 @@ public class TransitionalScanHelper { @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int numHwTrackFiltersAvailable(AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( - mContext, attributionSource, "ScanHelper numHwTrackFiltersAvailable")) { + mContext, attributionSource, "ScanHelper numHwTrackFiltersAvailable")) { return 0; } return (AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements() diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java index e6d8ca6a665..c03347ec326 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; @@ -19,9 +19,8 @@ import android.graphics.drawable.Drawable; import android.util.Log; /** - * Class to contain all the info about the items of the Map Email Settings Menu. - * It can be used for both Email Apps (group Parent item) and Accounts (Group child Item). - * + * Class to contain all the info about the items of the Map Email Settings Menu. It can be used for + * both Email Apps (group Parent item) and Accounts (Group child Item). */ public class BluetoothMapAccountItem implements Comparable { private static final String TAG = "BluetoothMapAccountItem"; @@ -38,8 +37,15 @@ public class BluetoothMapAccountItem implements Comparable> parsePackages( boolean includeIcon) { @@ -68,7 +69,7 @@ public class BluetoothMapAccountLoader { LinkedHashMap> groups = new LinkedHashMap>(); Intent[] searchIntents = new Intent[2]; - //Array searchIntents = new Array (); + // Array searchIntents = new Array (); searchIntents[0] = new Intent(BluetoothMapContract.PROVIDER_INTERFACE_EMAIL); searchIntents[1] = new Intent(BluetoothMapContract.PROVIDER_INTERFACE_IM); // reset the counter every time this method is called. @@ -82,11 +83,18 @@ public class BluetoothMapAccountLoader { List resInfos = mPackageManager.queryIntentContentProviders(searchIntent, 0); if (resInfos != null) { - Log.d(TAG, "Found " + resInfos.size() + " application(s) with intent " - + searchIntent.getAction()); - BluetoothMapUtils.TYPE msgType = (Objects.equals(searchIntent.getAction(), - BluetoothMapContract.PROVIDER_INTERFACE_EMAIL)) - ? BluetoothMapUtils.TYPE.EMAIL : BluetoothMapUtils.TYPE.IM; + Log.d( + TAG, + "Found " + + resInfos.size() + + " application(s) with intent " + + searchIntent.getAction()); + BluetoothMapUtils.TYPE msgType = + (Objects.equals( + searchIntent.getAction(), + BluetoothMapContract.PROVIDER_INTERFACE_EMAIL)) + ? BluetoothMapUtils.TYPE.EMAIL + : BluetoothMapUtils.TYPE.IM; for (ResolveInfo rInfo : resInfos) { Log.d(TAG, "ResolveInfo " + rInfo.toString()); // We cannot rely on apps that have been force-stopped in the @@ -111,8 +119,11 @@ public class BluetoothMapAccountLoader { } } } else { - Log.d(TAG, "Ignoring force-stopped authority " - + rInfo.providerInfo.authority + "\n"); + Log.d( + TAG, + "Ignoring force-stopped authority " + + rInfo.providerInfo.authority + + "\n"); } } } else { @@ -122,17 +133,26 @@ public class BluetoothMapAccountLoader { return groups; } - public BluetoothMapAccountItem createAppItem(ResolveInfo rInfo, boolean includeIcon, - BluetoothMapUtils.TYPE type) { + public BluetoothMapAccountItem createAppItem( + ResolveInfo rInfo, boolean includeIcon, BluetoothMapUtils.TYPE type) { String provider = rInfo.providerInfo.authority; if (provider != null) { String name = rInfo.loadLabel(mPackageManager).toString(); - Log.d(TAG, - rInfo.providerInfo.packageName + " - " + name + " - meta-data(provider = " - + provider + ")\n"); + Log.d( + TAG, + rInfo.providerInfo.packageName + + " - " + + name + + " - meta-data(provider = " + + provider + + ")\n"); BluetoothMapAccountItem app = - BluetoothMapAccountItem.create("0", name, rInfo.providerInfo.packageName, - provider, (!includeIcon) ? null : rInfo.loadIcon(mPackageManager), + BluetoothMapAccountItem.create( + "0", + name, + rInfo.providerInfo.packageName, + provider, + (!includeIcon) ? null : rInfo.loadIcon(mPackageManager), type); return app; } @@ -142,6 +162,7 @@ public class BluetoothMapAccountLoader { /** * Method for getting the accounts under a given contentprovider from a package. + * * @param app The parent app object * @return An ArrayList of BluetoothMapAccountItems containing all the accounts from the app */ @@ -152,8 +173,9 @@ public class BluetoothMapAccountLoader { // Get the list of accounts from the email apps content resolver (if possible) mResolver = mContext.getContentResolver(); try { - mProviderClient = mResolver.acquireUnstableContentProviderClient( - Uri.parse(app.mBase_uri_no_account)); + mProviderClient = + mResolver.acquireUnstableContentProviderClient( + Uri.parse(app.mBase_uri_no_account)); if (mProviderClient == null) { throw new RemoteException("Failed to acquire provider for " + app.getPackageName()); } @@ -163,8 +185,13 @@ public class BluetoothMapAccountLoader { Uri.parse(app.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_ACCOUNT); if (app.getType() == TYPE.IM) { - c = mProviderClient.query(uri, BluetoothMapContract.BT_IM_ACCOUNT_PROJECTION, null, - null, BluetoothMapContract.AccountColumns._ID + " DESC"); + c = + mProviderClient.query( + uri, + BluetoothMapContract.BT_IM_ACCOUNT_PROJECTION, + null, + null, + BluetoothMapContract.AccountColumns._ID + " DESC"); } else { c = mProviderClient.query( @@ -180,8 +207,11 @@ public class BluetoothMapAccountLoader { BluetoothProtoEnums.BLUETOOTH_MAP_ACCOUNT_LOADER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 0); - Log.d(TAG, "Could not establish ContentProviderClient for " + app.getPackageName() - + " - returning empty account list"); + Log.d( + TAG, + "Could not establish ContentProviderClient for " + + app.getPackageName() + + " - returning empty account list"); return children; } finally { if (mProviderClient != null) { @@ -199,8 +229,12 @@ public class BluetoothMapAccountLoader { int uciPreIndex = c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_UCI_PREFIX); while (c.moveToNext()) { - Log.d(TAG, "Adding account " + c.getString(dispNameIndex) + " with ID " + String - .valueOf(c.getInt(idIndex))); + Log.d( + TAG, + "Adding account " + + c.getString(dispNameIndex) + + " with ID " + + String.valueOf(c.getInt(idIndex))); String uci = null; String uciPrefix = null; if (app.getType() == TYPE.IM) { @@ -210,9 +244,15 @@ public class BluetoothMapAccountLoader { } BluetoothMapAccountItem child = - BluetoothMapAccountItem.create(String.valueOf((c.getInt(idIndex))), - c.getString(dispNameIndex), app.getPackageName(), - app.getProviderAuthority(), null, app.getType(), uci, uciPrefix); + BluetoothMapAccountItem.create( + String.valueOf((c.getInt(idIndex))), + c.getString(dispNameIndex), + app.getPackageName(), + app.getProviderAuthority(), + null, + app.getType(), + uci, + uciPrefix); child.mIsChecked = (c.getInt(exposeIndex) != 0); child.mIsChecked = true; // TODO: Revert when this works @@ -231,14 +271,13 @@ public class BluetoothMapAccountLoader { } /** - * Gets the number of enabled accounts in total across all supported apps. - * NOTE that this method should not be called before the parsePackages method - * has been successfully called. + * Gets the number of enabled accounts in total across all supported apps. NOTE that this method + * should not be called before the parsePackages method has been successfully called. + * * @return number of enabled accounts */ public int getAccountsEnabledCount() { Log.d(TAG, "Enabled Accounts count:" + mAccountsEnabledCount); return mAccountsEnabledCount; } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java index 8fa67a19c91..dfc2e5b1634 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -64,7 +64,6 @@ public class BluetoothMapAppObserver { initObservers(); } - private BluetoothMapAccountItem getApp(String authoritiesName) { Log.v(TAG, "getApp(): Looking for " + authoritiesName); for (BluetoothMapAccountItem app : mFullList.keySet()) { @@ -80,9 +79,10 @@ public class BluetoothMapAppObserver { private void handleAccountChanges(String packageNameWithProvider) { - Log.d(TAG, "handleAccountChanges (packageNameWithProvider: " + packageNameWithProvider - + "\n"); - //String packageName = packageNameWithProvider.replaceFirst("\\.[^\\.]+$", ""); + Log.d( + TAG, + "handleAccountChanges (packageNameWithProvider: " + packageNameWithProvider + "\n"); + // String packageName = packageNameWithProvider.replaceFirst("\\.[^\\.]+$", ""); BluetoothMapAccountItem app = getApp(packageNameWithProvider); if (app != null) { ArrayList newAccountList = mLoader.parseAccounts(app); @@ -117,14 +117,18 @@ public class BluetoothMapAppObserver { // account added - create SDP record mMapService.updateMasInstances( BluetoothMapService.UPDATE_MAS_INSTANCES_ACCOUNT_ADDED); - Log.v(TAG, "UPDATE_MAS_INSTANCES_ACCOUNT_ADDED " - + "isChecked changed"); + Log.v( + TAG, + "UPDATE_MAS_INSTANCES_ACCOUNT_ADDED " + + "isChecked changed"); } else { // account removed - remove SDP record mMapService.updateMasInstances( BluetoothMapService.UPDATE_MAS_INSTANCES_ACCOUNT_REMOVED); - Log.v(TAG, " UPDATE_MAS_INSTANCES_ACCOUNT_REMOVED " - + "isChecked changed"); + Log.v( + TAG, + " UPDATE_MAS_INSTANCES_ACCOUNT_REMOVED " + + "isChecked changed"); } } break; @@ -194,7 +198,7 @@ public class BluetoothMapAppObserver { } }; mObserverMap.put(uri.toString(), observer); - //False "notifyForDescendents" : Get notified whenever a change occurs to the exact URI. + // False "notifyForDescendents" : Get notified whenever a change occurs to the exact URI. mResolver.registerContentObserver(uri, false, observer); } @@ -389,6 +393,7 @@ public class BluetoothMapAppObserver { /** * Method to get a list of the accounts (across all apps). + * * @return Arraylist containing all accounts */ public ArrayList getAllAccountItems() { @@ -401,10 +406,7 @@ public class BluetoothMapAppObserver { return list; } - - /** - * Cleanup all resources - must be called to avoid leaks. - */ + /** Cleanup all resources - must be called to avoid leaks. */ public void shutdown() { deinitObservers(); removeReceiver(); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java index a7e44be6887..630a90e4d87 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -78,26 +78,26 @@ public class BluetoothMapAppParams { private static final int CONVO_PARAMETER_MASK = 0x26; // Length defined for Application Parameters - private static final int MAX_LIST_COUNT_LEN = 0x02; //, 0x0000, 0xFFFF), - private static final int START_OFFSET_LEN = 0x02; //, 0x0000, 0xFFFF), - private static final int FILTER_MESSAGE_TYPE_LEN = 0x01; //, 0x0000, 0x000f), - private static final int FILTER_READ_STATUS_LEN = 0x01; //, 0x0000, 0x0002), - private static final int FILTER_PRIORITY_LEN = 0x01; //, 0x0000, 0x0002), - private static final int ATTACHMENT_LEN = 0x01; //, 0x0000, 0x0001), - private static final int TRANSPARENT_LEN = 0x01; //, 0x0000, 0x0001), - private static final int RETRY_LEN = 0x01; //, 0x0000, 0x0001), - private static final int NEW_MESSAGE_LEN = 0x01; //, 0x0000, 0x0001), - private static final int NOTIFICATION_STATUS_LEN = 0x01; //, 0x0000, 0xFFFF), - private static final int MAS_INSTANCE_ID_LEN = 0x01; //, 0x0000, 0x00FF), - private static final int PARAMETER_MASK_LEN = 0x04; //, 0x0000, 0x0000), - private static final int FOLDER_LISTING_SIZE_LEN = 0x02; //, 0x0000, 0xFFFF), - private static final int MESSAGE_LISTING_SIZE_LEN = 0x02; //, 0x0000, 0xFFFF), - private static final int SUBJECT_LENGTH_LEN = 0x01; //, 0x0000, 0x00FF), - private static final int CHARSET_LEN = 0x01; //, 0x0000, 0x0001), - private static final int FRACTION_REQUEST_LEN = 0x01; //, 0x0000, 0x0001), - private static final int FRACTION_DELIVER_LEN = 0x01; //, 0x0000, 0x0001), - private static final int STATUS_INDICATOR_LEN = 0x01; //, 0x0000, 0x0001), - private static final int STATUS_VALUE_LEN = 0x01; //, 0x0000, 0x0001), + private static final int MAX_LIST_COUNT_LEN = 0x02; // , 0x0000, 0xFFFF), + private static final int START_OFFSET_LEN = 0x02; // , 0x0000, 0xFFFF), + private static final int FILTER_MESSAGE_TYPE_LEN = 0x01; // , 0x0000, 0x000f), + private static final int FILTER_READ_STATUS_LEN = 0x01; // , 0x0000, 0x0002), + private static final int FILTER_PRIORITY_LEN = 0x01; // , 0x0000, 0x0002), + private static final int ATTACHMENT_LEN = 0x01; // , 0x0000, 0x0001), + private static final int TRANSPARENT_LEN = 0x01; // , 0x0000, 0x0001), + private static final int RETRY_LEN = 0x01; // , 0x0000, 0x0001), + private static final int NEW_MESSAGE_LEN = 0x01; // , 0x0000, 0x0001), + private static final int NOTIFICATION_STATUS_LEN = 0x01; // , 0x0000, 0xFFFF), + private static final int MAS_INSTANCE_ID_LEN = 0x01; // , 0x0000, 0x00FF), + private static final int PARAMETER_MASK_LEN = 0x04; // , 0x0000, 0x0000), + private static final int FOLDER_LISTING_SIZE_LEN = 0x02; // , 0x0000, 0xFFFF), + private static final int MESSAGE_LISTING_SIZE_LEN = 0x02; // , 0x0000, 0xFFFF), + private static final int SUBJECT_LENGTH_LEN = 0x01; // , 0x0000, 0x00FF), + private static final int CHARSET_LEN = 0x01; // , 0x0000, 0x0001), + private static final int FRACTION_REQUEST_LEN = 0x01; // , 0x0000, 0x0001), + private static final int FRACTION_DELIVER_LEN = 0x01; // , 0x0000, 0x0001), + private static final int STATUS_INDICATOR_LEN = 0x01; // , 0x0000, 0x0001), + private static final int STATUS_VALUE_LEN = 0x01; // , 0x0000, 0x0001), private static final int DATABASE_INDETIFIER_LEN = 0x10; private static final int CONVO_LIST_VER_COUNTER_LEN = 0x10; private static final int PRESENCE_AVAILABLE_LEN = 0X01; @@ -181,30 +181,22 @@ public class BluetoothMapAppParams { private long mConvoParameterMask = INVALID_VALUE_PARAMETER; /** - * Default constructor, used to build an application parameter object to be - * encoded. By default the member variables will be initialized to - * {@link INVALID_VALUE_PARAMETER} for values, and empty strings for String - * typed members. + * Default constructor, used to build an application parameter object to be encoded. By default + * the member variables will be initialized to {@link INVALID_VALUE_PARAMETER} for values, and + * empty strings for String typed members. */ - public BluetoothMapAppParams() { - } + public BluetoothMapAppParams() {} /** - * Creates an application parameter object based on a application parameter - * OBEX header. The content of the {@link appParam} byte array will be - * parsed, and its content will be stored in the member variables. - * {@link INVALID_VALUE_PARAMETER} can be used to determine if a value is - * set or not, where strings will be empty, if {@link appParam} did not - * contain the parameter. + * Creates an application parameter object based on a application parameter OBEX header. The + * content of the {@link appParam} byte array will be parsed, and its content will be stored in + * the member variables. {@link INVALID_VALUE_PARAMETER} can be used to determine if a value is + * set or not, where strings will be empty, if {@link appParam} did not contain the parameter. * - * @param appParams - * the byte array containing the application parameters OBEX - * header - * @throws IllegalArgumentException - * when a parameter does not respect the valid ranges specified - * in the MAP spec. - * @throws ParseException - * if a parameter string if formated incorrectly. + * @param appParams the byte array containing the application parameters OBEX header + * @throws IllegalArgumentException when a parameter does not respect the valid ranges specified + * in the MAP spec. + * @throws ParseException if a parameter string if formated incorrectly. */ public BluetoothMapAppParams(final byte[] appParams) throws IllegalArgumentException, ParseException { @@ -214,14 +206,10 @@ public class BluetoothMapAppParams { /** * Parse an application parameter OBEX header stored in a byte array. * - * @param appParams - * the byte array containing the application parameters OBEX - * header - * @throws IllegalArgumentException - * when a parameter does not respect the valid ranges specified - * in the MAP spec. - * @throws ParseException - * if a parameter string if formated incorrectly. + * @param appParams the byte array containing the application parameters OBEX header + * @throws IllegalArgumentException when a parameter does not respect the valid ranges specified + * in the MAP spec. + * @throws ParseException if a parameter string if formated incorrectly. */ private void parseParams(final byte[] appParams) throws ParseException, IllegalArgumentException { @@ -230,7 +218,7 @@ public class BluetoothMapAppParams { ByteBuffer appParamBuf = ByteBuffer.wrap(appParams); appParamBuf.order(ByteOrder.BIG_ENDIAN); while (i < appParams.length) { - tagId = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 + tagId = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 tagLength = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 switch (tagId) { case MAX_LIST_COUNT: @@ -253,8 +241,11 @@ public class BluetoothMapAppParams { break; case START_OFFSET: if (tagLength != START_OFFSET_LEN) { - Log.w(TAG, - "START_OFFSET: Wrong length received: " + tagLength + " expected: " + Log.w( + TAG, + "START_OFFSET: Wrong length received: " + + tagLength + + " expected: " + START_OFFSET_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -268,8 +259,12 @@ public class BluetoothMapAppParams { break; case FILTER_MESSAGE_TYPE: if (tagLength != FILTER_MESSAGE_TYPE_LEN) { - Log.w(TAG, "FILTER_MESSAGE_TYPE: Wrong length received: " + tagLength - + " expected: " + FILTER_MESSAGE_TYPE_LEN); + Log.w( + TAG, + "FILTER_MESSAGE_TYPE: Wrong length received: " + + tagLength + + " expected: " + + FILTER_MESSAGE_TYPE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -284,8 +279,11 @@ public class BluetoothMapAppParams { if (tagLength != 0) { setFilterPeriodBegin(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "FILTER_PERIOD_BEGIN: Wrong length received: " + tagLength - + " expected to be more than 0"); + Log.w( + TAG, + "FILTER_PERIOD_BEGIN: Wrong length received: " + + tagLength + + " expected to be more than 0"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -298,8 +296,11 @@ public class BluetoothMapAppParams { if (tagLength != 0) { setFilterPeriodEnd(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "FILTER_PERIOD_END: Wrong length received: " + tagLength - + " expected to be more than 0"); + Log.w( + TAG, + "FILTER_PERIOD_END: Wrong length received: " + + tagLength + + " expected to be more than 0"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -330,8 +331,11 @@ public class BluetoothMapAppParams { if (tagLength != 0) { setFilterRecipient(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "FILTER_RECIPIENT: Wrong length received: " + tagLength - + " expected to be more than 0"); + Log.w( + TAG, + "FILTER_RECIPIENT: Wrong length received: " + + tagLength + + " expected to be more than 0"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -359,8 +363,12 @@ public class BluetoothMapAppParams { break; case FILTER_PRIORITY: if (tagLength != FILTER_PRIORITY_LEN) { - Log.w(TAG, "FILTER_PRIORITY: Wrong length received: " + tagLength - + " expected: " + FILTER_PRIORITY_LEN); + Log.w( + TAG, + "FILTER_PRIORITY: Wrong length received: " + + tagLength + + " expected: " + + FILTER_PRIORITY_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -373,8 +381,12 @@ public class BluetoothMapAppParams { break; case ATTACHMENT: if (tagLength != ATTACHMENT_LEN) { - Log.w(TAG, "ATTACHMENT: Wrong length received: " + tagLength + " expected: " - + ATTACHMENT_LEN); + Log.w( + TAG, + "ATTACHMENT: Wrong length received: " + + tagLength + + " expected: " + + ATTACHMENT_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -405,8 +417,12 @@ public class BluetoothMapAppParams { break; case RETRY: if (tagLength != RETRY_LEN) { - Log.w(TAG, "RETRY: Wrong length received: " + tagLength + " expected: " - + RETRY_LEN); + Log.w( + TAG, + "RETRY: Wrong length received: " + + tagLength + + " expected: " + + RETRY_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -437,8 +453,12 @@ public class BluetoothMapAppParams { break; case NOTIFICATION_STATUS: if (tagLength != NOTIFICATION_STATUS_LEN) { - Log.w(TAG, "NOTIFICATION_STATUS: Wrong length received: " + tagLength - + " expected: " + NOTIFICATION_STATUS_LEN); + Log.w( + TAG, + "NOTIFICATION_STATUS: Wrong length received: " + + tagLength + + " expected: " + + NOTIFICATION_STATUS_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -451,8 +471,12 @@ public class BluetoothMapAppParams { break; case NOTIFICATION_FILTER: if (tagLength != NOTIFICATION_FILTER_LEN) { - Log.w(TAG, "NOTIFICATION_FILTER: Wrong length received: " + tagLength - + " expected: " + NOTIFICATION_FILTER_LEN); + Log.w( + TAG, + "NOTIFICATION_FILTER: Wrong length received: " + + tagLength + + " expected: " + + NOTIFICATION_FILTER_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -483,8 +507,12 @@ public class BluetoothMapAppParams { break; case PARAMETER_MASK: if (tagLength != PARAMETER_MASK_LEN) { - Log.w(TAG, "PARAMETER_MASK: Wrong length received: " + tagLength - + " expected: " + PARAMETER_MASK_LEN); + Log.w( + TAG, + "PARAMETER_MASK: Wrong length received: " + + tagLength + + " expected: " + + PARAMETER_MASK_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -497,8 +525,12 @@ public class BluetoothMapAppParams { break; case FOLDER_LISTING_SIZE: if (tagLength != FOLDER_LISTING_SIZE_LEN) { - Log.w(TAG, "FOLDER_LISTING_SIZE: Wrong length received: " + tagLength - + " expected: " + FOLDER_LISTING_SIZE_LEN); + Log.w( + TAG, + "FOLDER_LISTING_SIZE: Wrong length received: " + + tagLength + + " expected: " + + FOLDER_LISTING_SIZE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -529,8 +561,12 @@ public class BluetoothMapAppParams { break; case SUBJECT_LENGTH: if (tagLength != SUBJECT_LENGTH_LEN) { - Log.w(TAG, "SUBJECT_LENGTH: Wrong length received: " + tagLength - + " expected: " + SUBJECT_LENGTH_LEN); + Log.w( + TAG, + "SUBJECT_LENGTH: Wrong length received: " + + tagLength + + " expected: " + + SUBJECT_LENGTH_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -543,8 +579,12 @@ public class BluetoothMapAppParams { break; case CHARSET: if (tagLength != CHARSET_LEN) { - Log.w(TAG, "CHARSET: Wrong length received: " + tagLength + " expected: " - + CHARSET_LEN); + Log.w( + TAG, + "CHARSET: Wrong length received: " + + tagLength + + " expected: " + + CHARSET_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -557,8 +597,12 @@ public class BluetoothMapAppParams { break; case FRACTION_REQUEST: if (tagLength != FRACTION_REQUEST_LEN) { - Log.w(TAG, "FRACTION_REQUEST: Wrong length received: " + tagLength - + " expected: " + FRACTION_REQUEST_LEN); + Log.w( + TAG, + "FRACTION_REQUEST: Wrong length received: " + + tagLength + + " expected: " + + FRACTION_REQUEST_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -571,8 +615,12 @@ public class BluetoothMapAppParams { break; case FRACTION_DELIVER: if (tagLength != FRACTION_DELIVER_LEN) { - Log.w(TAG, "FRACTION_DELIVER: Wrong length received: " + tagLength - + " expected: " + FRACTION_DELIVER_LEN); + Log.w( + TAG, + "FRACTION_DELIVER: Wrong length received: " + + tagLength + + " expected: " + + FRACTION_DELIVER_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -585,8 +633,12 @@ public class BluetoothMapAppParams { break; case STATUS_INDICATOR: if (tagLength != STATUS_INDICATOR_LEN) { - Log.w(TAG, "STATUS_INDICATOR: Wrong length received: " + tagLength - + " expected: " + STATUS_INDICATOR_LEN); + Log.w( + TAG, + "STATUS_INDICATOR: Wrong length received: " + + tagLength + + " expected: " + + STATUS_INDICATOR_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -620,8 +672,12 @@ public class BluetoothMapAppParams { break; case DATABASE_INDETIFIER: if ((tagLength != DATABASE_INDETIFIER_LEN)) { - Log.w(TAG, "DATABASE_IDENTIFIER: Wrong length received: " + tagLength - + " expected: " + DATABASE_INDETIFIER_LEN); + Log.w( + TAG, + "DATABASE_IDENTIFIER: Wrong length received: " + + tagLength + + " expected: " + + DATABASE_INDETIFIER_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -629,14 +685,18 @@ public class BluetoothMapAppParams { .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 25); } else { - setDatabaseIdentifier(appParamBuf.getLong(i)/*MSB*/, - appParamBuf.getLong(i + 8)/*LSB*/); + setDatabaseIdentifier( + appParamBuf.getLong(i) /*MSB*/, appParamBuf.getLong(i + 8) /*LSB*/); } break; case CONVO_LIST_VER_COUNTER: if ((tagLength != CONVO_LIST_VER_COUNTER_LEN)) { - Log.w(TAG, "CONVO_LIST_VER_COUNTER: Wrong length received: " + tagLength - + " expected: " + CONVO_LIST_VER_COUNTER_LEN); + Log.w( + TAG, + "CONVO_LIST_VER_COUNTER: Wrong length received: " + + tagLength + + " expected: " + + CONVO_LIST_VER_COUNTER_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -650,8 +710,12 @@ public class BluetoothMapAppParams { break; case PRESENCE_AVAILABLE: if ((tagLength != PRESENCE_AVAILABLE_LEN)) { - Log.w(TAG, "PRESENCE_AVAILABLE: Wrong length received: " + tagLength - + " expected: " + PRESENCE_AVAILABLE_LEN); + Log.w( + TAG, + "PRESENCE_AVAILABLE: Wrong length received: " + + tagLength + + " expected: " + + PRESENCE_AVAILABLE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -666,8 +730,11 @@ public class BluetoothMapAppParams { if (tagLength != 0) { setPresenceStatus(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "PRESENCE_STATUS: Wrong length received: " + tagLength - + " expected to be more than 0"); + Log.w( + TAG, + "PRESENCE_STATUS: Wrong length received: " + + tagLength + + " expected to be more than 0"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -680,8 +747,11 @@ public class BluetoothMapAppParams { if (tagLength != 0) { setLastActivity(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "LAST_ACTIVITY: Wrong length received: " + tagLength - + " expected to be more than 0"); + Log.w( + TAG, + "LAST_ACTIVITY: Wrong length received: " + + tagLength + + " expected to be more than 0"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -692,8 +762,12 @@ public class BluetoothMapAppParams { break; case CHAT_STATE: if ((tagLength != CHAT_STATE_LEN)) { - Log.w(TAG, "CHAT_STATE: Wrong length received: " + tagLength + " expected: " - + CHAT_STATE_LEN); + Log.w( + TAG, + "CHAT_STATE: Wrong length received: " + + tagLength + + " expected: " + + CHAT_STATE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -708,8 +782,12 @@ public class BluetoothMapAppParams { if ((tagLength != 0) && (tagLength <= FILTER_CONVO_ID_LEN)) { setFilterConvoId(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "FILTER_CONVO_ID: Wrong length received: " + tagLength - + " expected: " + FILTER_CONVO_ID_LEN); + Log.w( + TAG, + "FILTER_CONVO_ID: Wrong length received: " + + tagLength + + " expected: " + + FILTER_CONVO_ID_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -720,8 +798,11 @@ public class BluetoothMapAppParams { break; case CONVO_LISTING_SIZE: if (tagLength != CONVO_LISTING_SIZE_LEN) { - Log.w(TAG, - "LISTING_SIZE: Wrong length received: " + tagLength + " expected: " + Log.w( + TAG, + "LISTING_SIZE: Wrong length received: " + + tagLength + + " expected: " + CONVO_LISTING_SIZE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -735,8 +816,12 @@ public class BluetoothMapAppParams { break; case FILTER_PRESENCE: if ((tagLength != FILTER_PRESENCE_LEN)) { - Log.w(TAG, "FILTER_PRESENCE: Wrong length received: " + tagLength - + " expected: " + FILTER_PRESENCE_LEN); + Log.w( + TAG, + "FILTER_PRESENCE: Wrong length received: " + + tagLength + + " expected: " + + FILTER_PRESENCE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -749,8 +834,12 @@ public class BluetoothMapAppParams { break; case FILTER_UID_PRESENT: if ((tagLength != FILTER_UID_PRESENT_LEN)) { - Log.w(TAG, "FILTER_UID_PRESENT: Wrong length received: " + tagLength - + " expected: " + FILTER_UID_PRESENT_LEN); + Log.w( + TAG, + "FILTER_UID_PRESENT: Wrong length received: " + + tagLength + + " expected: " + + FILTER_UID_PRESENT_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -763,8 +852,12 @@ public class BluetoothMapAppParams { break; case CHAT_STATE_CONVO_ID: if ((tagLength != CHAT_STATE_CONVO_ID_LEN)) { - Log.w(TAG, "CHAT_STATE_CONVO_ID: Wrong length received: " + tagLength - + " expected: " + CHAT_STATE_CONVO_ID_LEN); + Log.w( + TAG, + "CHAT_STATE_CONVO_ID: Wrong length received: " + + tagLength + + " expected: " + + CHAT_STATE_CONVO_ID_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -772,14 +865,17 @@ public class BluetoothMapAppParams { .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 35); } else { - /* TODO: Is this correct convoId handling? */ - setChatStateConvoId(appParamBuf.getLong(i)/*MSB*/, - appParamBuf.getLong(i + 8)/*LSB*/); - Log.d(TAG, "CHAT_STATE_CONVO_ID: convo id " + "MSB=" - + BluetoothMapUtils.getLongAsString(appParamBuf.getLong(i)) - + ", LSB(+8)=" + BluetoothMapUtils.getLongAsString( - appParamBuf.getLong(i + 8))); - + /* TODO: Is this correct convoId handling? */ + setChatStateConvoId( + appParamBuf.getLong(i) /*MSB*/, appParamBuf.getLong(i + 8) /*LSB*/); + Log.d( + TAG, + "CHAT_STATE_CONVO_ID: convo id " + + "MSB=" + + BluetoothMapUtils.getLongAsString(appParamBuf.getLong(i)) + + ", LSB(+8)=" + + BluetoothMapUtils.getLongAsString( + appParamBuf.getLong(i + 8))); } break; case FOLDER_VER_COUNTER: @@ -788,8 +884,12 @@ public class BluetoothMapAppParams { if ((tagLength != 0 && tagLength <= FILTER_MESSAGE_HANDLE_LEN)) { setFilterMsgHandle(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "FILTER_MESSAGE_HANDLE: Wrong length received: " + tagLength - + " expected: " + FILTER_MESSAGE_HANDLE_LEN); + Log.w( + TAG, + "FILTER_MESSAGE_HANDLE: Wrong length received: " + + tagLength + + " expected: " + + FILTER_MESSAGE_HANDLE_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -801,8 +901,12 @@ public class BluetoothMapAppParams { break; case CONVO_PARAMETER_MASK: if (tagLength != CONVO_PARAMETER_MASK_LEN) { - Log.w(TAG, "CONVO_PARAMETER_MASK: Wrong length received: " + tagLength - + " expected: " + CONVO_PARAMETER_MASK_LEN); + Log.w( + TAG, + "CONVO_PARAMETER_MASK: Wrong length received: " + + tagLength + + " expected: " + + CONVO_PARAMETER_MASK_LEN); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -816,8 +920,11 @@ public class BluetoothMapAppParams { break; default: // Just skip unknown Tags, no need to report error - Log.w(TAG, "Unknown TagId received ( 0x" + Integer.toString(tagId, 16) - + "), skipping..."); + Log.w( + TAG, + "Unknown TagId received ( 0x" + + Integer.toString(tagId, 16) + + "), skipping..."); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -831,12 +938,10 @@ public class BluetoothMapAppParams { } /** - * Get the approximate length needed to store the appParameters in a byte - * array. + * Get the approximate length needed to store the appParameters in a byte array. * * @return the length in bytes - * @throws UnsupportedEncodingException - * if the platform does not support UTF-8 encoding. + * @throws UnsupportedEncodingException if the platform does not support UTF-8 encoding. */ private int getParamMaxLength() throws UnsupportedEncodingException { int length = 0; @@ -862,8 +967,7 @@ public class BluetoothMapAppParams { * Encode the application parameter object to a byte array. * * @return a byte Array representation of the application parameter object. - * @throws UnsupportedEncodingException - * if the platform does not support UTF-8 encoding. + * @throws UnsupportedEncodingException if the platform does not support UTF-8 encoding. */ public byte[] encodeParams() throws UnsupportedEncodingException { ByteBuffer appParamBuf = ByteBuffer.allocate(getParamMaxLength()); @@ -1075,8 +1179,11 @@ public class BluetoothMapAppParams { } // We need to reduce the length of the array to match the content - retBuf = Arrays.copyOfRange(appParamBuf.array(), appParamBuf.arrayOffset(), - appParamBuf.arrayOffset() + appParamBuf.position()); + retBuf = + Arrays.copyOfRange( + appParamBuf.array(), + appParamBuf.arrayOffset(), + appParamBuf.arrayOffset() + appParamBuf.position()); return retBuf; } @@ -1168,7 +1275,7 @@ public class BluetoothMapAppParams { } public void setFilterLastActivityEnd(long filterPeriodEnd) { - this.mFilterPeriodEnd = filterPeriodEnd; //er reuse the same + this.mFilterPeriodEnd = filterPeriodEnd; // er reuse the same } public void setFilterPeriodEnd(String filterPeriodEnd) throws ParseException { @@ -1345,14 +1452,14 @@ public class BluetoothMapAppParams { return mFilterPresence; } - public SignedLongLong getFilterConvoId() { return mFilterConvoId; } /** - * Get a decimal representation of the lower bits of the ConvoId - used for queries. - * The upper bits are used for convo-type. + * Get a decimal representation of the lower bits of the ConvoId - used for queries. The upper + * bits are used for convo-type. + * * @return decimal representation of the convo ID. */ public String getFilterConvoIdString() { @@ -1363,7 +1470,6 @@ public class BluetoothMapAppParams { return str; } - public void setFilterConvoId(String id) { try { mFilterConvoId = SignedLongLong.fromString(id); @@ -1377,7 +1483,6 @@ public class BluetoothMapAppParams { } } - public void setChatState(int state) { if (state < 0 || state > 0x00FF) { throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); @@ -1654,6 +1759,4 @@ public class BluetoothMapAppParams { Date date = format.parse(mseTime); this.mMseTime = date.getTime(); } - - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java index 61c26fb96a5..d77a7b22ab3 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -68,24 +68,18 @@ public class BluetoothMapContent { private static final String TAG = "BluetoothMapContent"; - // Parameter Mask for selection of parameters to return in listings private static final int MASK_SUBJECT = 0x00000001; - @VisibleForTesting - static final int MASK_DATETIME = 0x00000002; - @VisibleForTesting - static final int MASK_SENDER_NAME = 0x00000004; - @VisibleForTesting - static final int MASK_SENDER_ADDRESSING = 0x00000008; + @VisibleForTesting static final int MASK_DATETIME = 0x00000002; + @VisibleForTesting static final int MASK_SENDER_NAME = 0x00000004; + @VisibleForTesting static final int MASK_SENDER_ADDRESSING = 0x00000008; private static final int MASK_RECIPIENT_NAME = 0x00000010; - @VisibleForTesting - static final int MASK_RECIPIENT_ADDRESSING = 0x00000020; + @VisibleForTesting static final int MASK_RECIPIENT_ADDRESSING = 0x00000020; private static final int MASK_TYPE = 0x00000040; private static final int MASK_SIZE = 0x00000080; private static final int MASK_RECEPTION_STATUS = 0x00000100; private static final int MASK_TEXT = 0x00000200; - @VisibleForTesting - static final int MASK_ATTACHMENT_SIZE = 0x00000400; + @VisibleForTesting static final int MASK_ATTACHMENT_SIZE = 0x00000400; private static final int MASK_PRIORITY = 0x00000800; private static final int MASK_READ = 0x00001000; private static final int MASK_SENT = 0x00002000; @@ -93,8 +87,7 @@ public class BluetoothMapContent { // private static final int MASK_REPLYTO_ADDRESSING = 0x00008000; // TODO: Duplicate in proposed spec // private static final int MASK_RECEPTION_STATE = 0x00010000; - @VisibleForTesting - static final int MASK_DELIVERY_STATUS = 0x00010000; + @VisibleForTesting static final int MASK_DELIVERY_STATUS = 0x00010000; private static final int MASK_CONVERSATION_ID = 0x00020000; private static final int MASK_CONVERSATION_NAME = 0x00040000; // private static final int MASK_FOLDER_TYPE = 0x00100000; @@ -124,10 +117,11 @@ public class BluetoothMapContent { public static final long PARAMETER_MASK_ALL_ENABLED = 0xFFFFFFFFL; public static final long CONVO_PARAMETER_MASK_ALL_ENABLED = 0xFFFFFFFFL; public static final long CONVO_PARAMETER_MASK_DEFAULT = - CONVO_PARAM_MASK_CONVO_NAME | CONVO_PARAM_MASK_PARTTICIPANTS | CONVO_PARAM_MASK_PART_UCI + CONVO_PARAM_MASK_CONVO_NAME + | CONVO_PARAM_MASK_PARTTICIPANTS + | CONVO_PARAM_MASK_PART_UCI | CONVO_PARAM_MASK_PART_DISP_NAME; - private static final int FILTER_READ_STATUS_UNREAD_ONLY = 0x01; private static final int FILTER_READ_STATUS_READ_ONLY = 0x02; // private static final int FILTER_READ_STATUS_ALL = 0x00; @@ -140,107 +134,113 @@ public class BluetoothMapContent { public static final int MMS_CC = 0x82; /* OMA-TS-MMS-ENC defined many types in X-Mms-Message-Type. - Only m-send-req (128) m-retrieve-conf (132), m-notification-ind (130) - are interested by user */ + Only m-send-req (128) m-retrieve-conf (132), m-notification-ind (130) + are interested by user */ private static final String INTERESTED_MESSAGE_TYPE_CLAUSE = - String.format("( %s = %d OR %s = %d OR %s = %d )", Mms.MESSAGE_TYPE, - PduHeaders.MESSAGE_TYPE_SEND_REQ, Mms.MESSAGE_TYPE, - PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF, Mms.MESSAGE_TYPE, + String.format( + "( %s = %d OR %s = %d OR %s = %d )", + Mms.MESSAGE_TYPE, + PduHeaders.MESSAGE_TYPE_SEND_REQ, + Mms.MESSAGE_TYPE, + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF, + Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND); public static final String INSERT_ADDRES_TOKEN = "insert-address-token"; private final Context mContext; private final ContentResolver mResolver; - @VisibleForTesting - final String mBaseUri; + @VisibleForTesting final String mBaseUri; private final BluetoothMapAccountItem mAccount; /* The MasInstance reference is used to update persistent (over a connection) version counters*/ private final BluetoothMapMasInstance mMasInstance; - @VisibleForTesting - String mMessageVersion = BluetoothMapUtils.MAP_V10_STR; + @VisibleForTesting String mMessageVersion = BluetoothMapUtils.MAP_V10_STR; private int mRemoteFeatureMask = BluetoothMapUtils.MAP_FEATURE_DEFAULT_BITMASK; - @VisibleForTesting - int mMsgListingVersion = BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V10; - - static final String[] SMS_PROJECTION = new String[]{ - BaseColumns._ID, - Sms.THREAD_ID, - Sms.ADDRESS, - Sms.BODY, - Sms.DATE, - Sms.READ, - Sms.TYPE, - Sms.STATUS, - Sms.LOCKED, - Sms.ERROR_CODE - }; - - static final String[] MMS_PROJECTION = new String[]{ - BaseColumns._ID, - Mms.THREAD_ID, - Mms.MESSAGE_ID, - Mms.MESSAGE_SIZE, - Mms.SUBJECT, - Mms.CONTENT_TYPE, - Mms.TEXT_ONLY, - Mms.DATE, - Mms.DATE_SENT, - Mms.READ, - Mms.MESSAGE_BOX, - Mms.STATUS, - Mms.PRIORITY, - }; - - static final String[] SMS_CONVO_PROJECTION = new String[]{ - BaseColumns._ID, - Sms.THREAD_ID, - Sms.ADDRESS, - Sms.DATE, - Sms.READ, - Sms.TYPE, - Sms.STATUS, - Sms.LOCKED, - Sms.ERROR_CODE - }; - - static final String[] MMS_CONVO_PROJECTION = new String[]{ - BaseColumns._ID, - Mms.THREAD_ID, - Mms.MESSAGE_ID, - Mms.MESSAGE_SIZE, - Mms.SUBJECT, - Mms.CONTENT_TYPE, - Mms.TEXT_ONLY, - Mms.DATE, - Mms.DATE_SENT, - Mms.READ, - Mms.MESSAGE_BOX, - Mms.STATUS, - Mms.PRIORITY, - Mms.Addr.ADDRESS - }; + @VisibleForTesting int mMsgListingVersion = BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V10; + + static final String[] SMS_PROJECTION = + new String[] { + BaseColumns._ID, + Sms.THREAD_ID, + Sms.ADDRESS, + Sms.BODY, + Sms.DATE, + Sms.READ, + Sms.TYPE, + Sms.STATUS, + Sms.LOCKED, + Sms.ERROR_CODE + }; + + static final String[] MMS_PROJECTION = + new String[] { + BaseColumns._ID, + Mms.THREAD_ID, + Mms.MESSAGE_ID, + Mms.MESSAGE_SIZE, + Mms.SUBJECT, + Mms.CONTENT_TYPE, + Mms.TEXT_ONLY, + Mms.DATE, + Mms.DATE_SENT, + Mms.READ, + Mms.MESSAGE_BOX, + Mms.STATUS, + Mms.PRIORITY, + }; + + static final String[] SMS_CONVO_PROJECTION = + new String[] { + BaseColumns._ID, + Sms.THREAD_ID, + Sms.ADDRESS, + Sms.DATE, + Sms.READ, + Sms.TYPE, + Sms.STATUS, + Sms.LOCKED, + Sms.ERROR_CODE + }; + + static final String[] MMS_CONVO_PROJECTION = + new String[] { + BaseColumns._ID, + Mms.THREAD_ID, + Mms.MESSAGE_ID, + Mms.MESSAGE_SIZE, + Mms.SUBJECT, + Mms.CONTENT_TYPE, + Mms.TEXT_ONLY, + Mms.DATE, + Mms.DATE_SENT, + Mms.READ, + Mms.MESSAGE_BOX, + Mms.STATUS, + Mms.PRIORITY, + Mms.Addr.ADDRESS + }; /* CONVO LISTING projections and column indexes */ @VisibleForTesting static final String[] MMS_SMS_THREAD_PROJECTION = { - Threads._ID, - Threads.DATE, - Threads.SNIPPET, - Threads.SNIPPET_CHARSET, - Threads.READ, - Threads.RECIPIENT_IDS + Threads._ID, + Threads.DATE, + Threads.SNIPPET, + Threads.SNIPPET_CHARSET, + Threads.READ, + Threads.RECIPIENT_IDS }; - private static final String[] CONVO_VERSION_PROJECTION = new String[]{ - /* Thread information */ - ConversationColumns.THREAD_ID, - ConversationColumns.THREAD_NAME, - ConversationColumns.READ_STATUS, - ConversationColumns.LAST_THREAD_ACTIVITY, - ConversationColumns.SUMMARY, - }; + private static final String[] CONVO_VERSION_PROJECTION = + new String[] { + /* Thread information */ + ConversationColumns.THREAD_ID, + ConversationColumns.THREAD_NAME, + ConversationColumns.READ_STATUS, + ConversationColumns.LAST_THREAD_ACTIVITY, + ConversationColumns.SUMMARY, + }; /* Optimize the Cursor access to avoid the need to do a getColumnIndex() */ private static final int MMS_SMS_THREAD_COL_ID; @@ -334,7 +334,6 @@ public class BluetoothMapContent { public int mContactColPresenceText = -1; public int mContactColPriority = -1; - public void setMessageColumns(Cursor c) { mMessageColId = c.getColumnIndex(BluetoothMapContract.MessageColumns._ID); mMessageColDate = c.getColumnIndex(BluetoothMapContract.MessageColumns.DATE); @@ -374,9 +373,8 @@ public class BluetoothMapContent { c.getColumnIndex(BluetoothMapContract.MessageColumns.THREAD_NAME); mMessageColAttachmentMime = c.getColumnIndex(BluetoothMapContract.MessageColumns.ATTACHMENT_MINE_TYPES); - //TODO this is temporary as text should come from parts table instead + // TODO this is temporary as text should come from parts table instead mMessageColBody = c.getColumnIndex(BluetoothMapContract.MessageColumns.BODY); - } public void setEmailImConvoColumns(Cursor c) { @@ -433,8 +431,8 @@ public class BluetoothMapContent { } } - public BluetoothMapContent(final Context context, BluetoothMapAccountItem account, - BluetoothMapMasInstance mas) { + public BluetoothMapContent( + final Context context, BluetoothMapAccountItem account, BluetoothMapMasInstance mas) { mContext = context; mResolver = mContext.getContentResolver(); mMasInstance = mas; @@ -466,7 +464,10 @@ public class BluetoothMapContent { } } - private void setProtected(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setProtected( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_PROTECTED) != 0) { String protect = "no"; @@ -481,7 +482,10 @@ public class BluetoothMapContent { } } - private void setThreadId(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setThreadId( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_CONVERSATION_ID) != 0) { long threadId = 0; @@ -500,7 +504,10 @@ public class BluetoothMapContent { } } - private void setThreadName(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setThreadName( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { // TODO: Maybe this should be valid for SMS/MMS if ((ap.getParameterMask() & MASK_CONVERSATION_NAME) != 0) { @@ -512,8 +519,10 @@ public class BluetoothMapContent { } } - - private void setSent(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setSent( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_SENT) != 0) { int msgType = 0; @@ -535,7 +544,10 @@ public class BluetoothMapContent { } } - private void setRead(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setRead( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { int read = 0; if (fi.mMsgType == FilterInfo.TYPE_SMS) { @@ -551,7 +563,10 @@ public class BluetoothMapContent { e.setRead((read == 1), ((ap.getParameterMask() & MASK_READ) != 0)); } - private void setPriority(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setPriority( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_PRIORITY) != 0) { String priority = "no"; @@ -574,14 +589,16 @@ public class BluetoothMapContent { } /** - * For SMS we set the attachment size to 0, as all data will be text data, hence - * attachments for SMS is not possible. - * For MMS all data is actually attachments, hence we do set the attachment size to - * the total message size. To provide a more accurate attachment size, one could - * extract the length (in bytes) of the text parts. + * For SMS we set the attachment size to 0, as all data will be text data, hence attachments for + * SMS is not possible. For MMS all data is actually attachments, hence we do set the attachment + * size to the total message size. To provide a more accurate attachment size, one could extract + * the length (in bytes) of the text parts. */ @VisibleForTesting - void setAttachment(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + void setAttachment( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_ATTACHMENT_SIZE) != 0) { int size = 0; @@ -593,8 +610,11 @@ public class BluetoothMapContent { // We know there are attachments, since it is not TextOnly // Hence the size in the database must be wrong. // Set size to 1 to indicate to the client, that attachments are present - Log.d(TAG, "Error in message database, size reported as: " + size - + " Changing size to 1"); + Log.d( + TAG, + "Error in message database, size reported as: " + + size + + " Changing size to 1"); size = 1; } // TODO: Add handling of attachemnt mime types @@ -603,8 +623,11 @@ public class BluetoothMapContent { int attachment = c.getInt(fi.mMessageColAttachment); size = c.getInt(fi.mMessageColAttachmentSize); if (attachment == 1 && size == 0) { - Log.d(TAG, "Error in message database, attachment size reported as: " + size - + " Changing size to 1"); + Log.d( + TAG, + "Error in message database, attachment size reported as: " + + size + + " Changing size to 1"); size = 1; /* Ensure we indicate we have attachments in the size, if the message has attachments, in case the e-mail client do not report a size */ @@ -619,18 +642,26 @@ public class BluetoothMapContent { attachmentMimeTypes = c.getString(fi.mMessageColAttachmentMime); } } - Log.v(TAG, "setAttachmentSize: " + size + "\n" + "setAttachmentMimeTypes: " - + attachmentMimeTypes); + Log.v( + TAG, + "setAttachmentSize: " + + size + + "\n" + + "setAttachmentMimeTypes: " + + attachmentMimeTypes); e.setAttachmentSize(size); - if ((mMsgListingVersion > BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V10) && ( - (ap.getParameterMask() & MASK_ATTACHMENT_MIME) != 0)) { + if ((mMsgListingVersion > BluetoothMapUtils.MAP_MESSAGE_LISTING_FORMAT_V10) + && ((ap.getParameterMask() & MASK_ATTACHMENT_MIME) != 0)) { e.setAttachmentMimeTypes(attachmentMimeTypes); } } } - private void setText(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setText( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_TEXT) != 0) { String hasText = ""; @@ -666,7 +697,10 @@ public class BluetoothMapContent { } @VisibleForTesting - void setDeliveryStatus(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + void setDeliveryStatus( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_DELIVERY_STATUS) != 0) { String deliveryStatus = "delivered"; @@ -679,7 +713,10 @@ public class BluetoothMapContent { } } - private void setSize(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setSize( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_SIZE) != 0) { int size = 0; @@ -688,7 +725,7 @@ public class BluetoothMapContent { size = subject.length(); } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { size = c.getInt(fi.mMmsColSize); - //MMS complete size = attachment_size + subject length + // MMS complete size = attachment_size + subject length String subject = e.getSubject(); if (subject == null || subject.length() == 0) { // Handle setSubject if not done case @@ -704,8 +741,11 @@ public class BluetoothMapContent { // A message cannot have size 0 // Hence the size in the database must be wrong. // Set size to 1 to indicate to the client, that the message has content. - Log.d(TAG, "Error in message database, size reported as: " + size - + " Changing size to 1"); + Log.d( + TAG, + "Error in message database, size reported as: " + + size + + " Changing size to 1"); size = 1; } Log.v(TAG, "setSize: " + size); @@ -754,7 +794,7 @@ public class BluetoothMapContent { Log.v(TAG, "ToName = " + tokens[i].toString()); String name = tokens[i].getName(); if (!first) { - sb.append("; "); //Delimiter + sb.append("; "); // Delimiter } sb.append(name); first = false; @@ -776,7 +816,7 @@ public class BluetoothMapContent { Log.v(TAG, "ccName = " + tokens[i].toString()); String name = tokens[i].getName(); if (!first) { - sb.append("; "); //Delimiter + sb.append("; "); // Delimiter } sb.append(name); first = false; @@ -797,7 +837,7 @@ public class BluetoothMapContent { Log.v(TAG, "bccName = " + tokens[i].toString()); String name = tokens[i].getName(); if (!first) { - sb.append("; "); //Delimiter + sb.append("; "); // Delimiter } sb.append(name); first = false; @@ -826,7 +866,7 @@ public class BluetoothMapContent { Log.v(TAG, "ToAddress = " + tokens[i].toString()); String email = tokens[i].getAddress(); if (!first) { - sb.append("; "); //Delimiter + sb.append("; "); // Delimiter } sb.append(email); first = false; @@ -848,7 +888,7 @@ public class BluetoothMapContent { Log.v(TAG, "ccAddress = " + tokens[i].toString()); String email = tokens[i].getAddress(); if (!first) { - sb.append("; "); //Delimiter + sb.append("; "); // Delimiter } sb.append(email); first = false; @@ -869,7 +909,7 @@ public class BluetoothMapContent { Log.v(TAG, "bccAddress = " + tokens[i].toString()); String email = tokens[i].getAddress(); if (!first) { - sb.append("; "); //Delimiter + sb.append("; "); // Delimiter } sb.append(email); first = false; @@ -881,8 +921,11 @@ public class BluetoothMapContent { } @VisibleForTesting - void setRecipientAddressing(BluetoothMapMessageListingElement e, Cursor c, - FilterInfo fi, BluetoothMapAppParams ap) { + void setRecipientAddressing( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, + BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_RECIPIENT_ADDRESSING) != 0) { String address = null; if (fi.mMsgType == FilterInfo.TYPE_SMS) { @@ -918,7 +961,10 @@ public class BluetoothMapContent { } } - private void setRecipientName(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setRecipientName( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_RECIPIENT_NAME) != 0) { String name = null; @@ -956,7 +1002,10 @@ public class BluetoothMapContent { } @VisibleForTesting - void setSenderAddressing(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + void setSenderAddressing( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_SENDER_ADDRESSING) != 0) { String address = ""; @@ -970,7 +1019,7 @@ public class BluetoothMapContent { } if (tempAddress == null) { /* This can only happen on devices with no SIM - - hence will typically not have any SMS messages. */ + hence will typically not have any SMS messages. */ } else { address = PhoneNumberUtils.extractNetworkPortion(tempAddress); /* extractNetworkPortion can return N if the number is a service "number" = @@ -978,8 +1027,9 @@ public class BluetoothMapContent { * because of the N in compaNy) * Hence we need to check if the number is actually a string with alpha chars. * */ - Boolean alpha = PhoneNumberUtils.stripSeparators(tempAddress) - .matches("[0-9]*[a-zA-Z]+[0-9]*"); + Boolean alpha = + PhoneNumberUtils.stripSeparators(tempAddress) + .matches("[0-9]*[a-zA-Z]+[0-9]*"); if (address == null || address.length() < 2 || alpha) { address = tempAddress; // if the number is a service acsii text just use it @@ -992,7 +1042,7 @@ public class BluetoothMapContent { if (address == null || address.length() < 1) { address = tempAddress; // if the number is a service acsii text just use it } - } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL/* || + } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL /* || fi.mMsgType == FilterInfo.TYPE_IM*/) { String nameEmail = c.getString(fi.mMessageColFromAddress); Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(nameEmail); @@ -1005,7 +1055,7 @@ public class BluetoothMapContent { String[] emails = new String[1]; emails[0] = tokens[i].getAddress(); if (!first) { - address += "; "; //Delimiter + address += "; "; // Delimiter } address += emails[0]; first = false; @@ -1018,22 +1068,30 @@ public class BluetoothMapContent { // TODO: This is a BAD hack, that we map the contact ID to a conversation ID!!! // We need to reach a conclusion on what to do Uri contactsUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_CONVOCONTACT); - Cursor contacts = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contactsUri, BluetoothMapContract.BT_CONTACT_PROJECTION, - BluetoothMapContract.ConvoContactColumns.CONVO_ID + " = " + contactId, null, - null); + Cursor contacts = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contactsUri, + BluetoothMapContract.BT_CONTACT_PROJECTION, + BluetoothMapContract.ConvoContactColumns.CONVO_ID + + " = " + + contactId, + null, + null); try { // TODO this will not work for group-chats if (contacts != null && contacts.moveToFirst()) { - address = contacts.getString(contacts.getColumnIndex( - BluetoothMapContract.ConvoContactColumns.UCI)); + address = + contacts.getString( + contacts.getColumnIndex( + BluetoothMapContract.ConvoContactColumns.UCI)); } } finally { if (contacts != null) { contacts.close(); } } - } Log.v(TAG, "setSenderAddressing: " + address); if (address == null) { @@ -1044,7 +1102,10 @@ public class BluetoothMapContent { } @VisibleForTesting - void setSenderName(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + void setSenderName( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_SENDER_NAME) != 0) { String name = ""; @@ -1069,7 +1130,7 @@ public class BluetoothMapContent { if (phone != null && !phone.isEmpty()) { name = getContactNameFromPhone(phone, mResolver); } - } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL/* || + } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL /* || fi.mMsgType == FilterInfo.TYPE_IM*/) { String nameEmail = c.getString(fi.mMessageColFromAddress); Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(nameEmail); @@ -1083,7 +1144,7 @@ public class BluetoothMapContent { emails[0] = tokens[i].getAddress(); String nameIn = tokens[i].getName(); if (!first) { - name += "; "; //Delimiter + name += "; "; // Delimiter } name += nameIn; first = false; @@ -1094,15 +1155,24 @@ public class BluetoothMapContent { // For IM we add the contact ID in the addressing long contactId = c.getLong(fi.mMessageColFromAddress); Uri contactsUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_CONVOCONTACT); - Cursor contacts = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contactsUri, BluetoothMapContract.BT_CONTACT_PROJECTION, - BluetoothMapContract.ConvoContactColumns.CONVO_ID + " = " + contactId, null, - null); + Cursor contacts = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contactsUri, + BluetoothMapContract.BT_CONTACT_PROJECTION, + BluetoothMapContract.ConvoContactColumns.CONVO_ID + + " = " + + contactId, + null, + null); try { // TODO this will not work for group-chats if (contacts != null && contacts.moveToFirst()) { - name = contacts.getString(contacts.getColumnIndex( - BluetoothMapContract.ConvoContactColumns.NAME)); + name = + contacts.getString( + contacts.getColumnIndex( + BluetoothMapContract.ConvoContactColumns.NAME)); } } finally { if (contacts != null) { @@ -1119,7 +1189,10 @@ public class BluetoothMapContent { } @VisibleForTesting - void setDateTime(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + void setDateTime( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { if ((ap.getParameterMask() & MASK_DATETIME) != 0) { long date = 0; @@ -1153,7 +1226,6 @@ public class BluetoothMapContent { } e.setLastActivity(date); Log.v(TAG, "setDateTime: " + e.getLastActivityString()); - } public static String getTextPartsMms(ContentResolver r, long id) { @@ -1162,8 +1234,9 @@ public class BluetoothMapContent { String uriStr = new String(Mms.CONTENT_URI + "/" + id + "/part"); Uri uriAddress = Uri.parse(uriStr); // TODO: maybe use a projection with only "ct" and "text" - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(r, uriAddress, null, - selection, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(r, uriAddress, null, selection, null, null); try { if (c != null && c.moveToFirst()) { do { @@ -1185,7 +1258,10 @@ public class BluetoothMapContent { return text; } - private void setSubject(BluetoothMapMessageListingElement e, Cursor c, FilterInfo fi, + private void setSubject( + BluetoothMapMessageListingElement e, + Cursor c, + FilterInfo fi, BluetoothMapAppParams ap) { String subject = ""; int subLength = ap.getSubjectLength(); @@ -1198,9 +1274,10 @@ public class BluetoothMapContent { if (Utils.isInstrumentationTestMode()) { isHondaCarkit = false; } else { - isHondaCarkit = DeviceWorkArounds.addressStartsWith( - BluetoothMapService.getRemoteDevice().getAddress(), - DeviceWorkArounds.HONDA_CARKIT); + isHondaCarkit = + DeviceWorkArounds.addressStartsWith( + BluetoothMapService.getRemoteDevice().getAddress(), + DeviceWorkArounds.HONDA_CARKIT); } if (isHondaCarkit || (ap.getParameterMask() & MASK_SUBJECT) != 0) { if (fi.mMsgType == FilterInfo.TYPE_SMS) { @@ -1238,8 +1315,8 @@ public class BluetoothMapContent { e.setHandle(handle); } - private BluetoothMapMessageListingElement element(Cursor c, FilterInfo fi, - BluetoothMapAppParams ap) { + private BluetoothMapMessageListingElement element( + Cursor c, FilterInfo fi, BluetoothMapAppParams ap) { BluetoothMapMessageListingElement e = new BluetoothMapMessageListingElement(); setHandle(e, c, fi); setDateTime(e, c, fi, ap); @@ -1264,7 +1341,7 @@ public class BluetoothMapContent { * caching. */ public static String getContactNameFromPhone(String phone, ContentResolver resolver) { String name = null; - //Handle possible exception for empty phone address + // Handle possible exception for empty phone address if (TextUtils.isEmpty(phone)) { return name; } @@ -1277,8 +1354,10 @@ public class BluetoothMapContent { String orderBy = Contacts.DISPLAY_NAME + " ASC"; Cursor c = null; try { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(resolver, uri, projection, - selection, null, orderBy); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + resolver, uri, projection, selection, null, orderBy); if (c != null) { int colIndex = c.getColumnIndex(Contacts.DISPLAY_NAME); if (c.getCount() >= 1) { @@ -1296,10 +1375,7 @@ public class BluetoothMapContent { private static final String[] RECIPIENT_ID_PROJECTION = {Threads.RECIPIENT_IDS}; - /** - * Get SMS RecipientAddresses for DRAFT folder based on threadId - * - */ + /** Get SMS RecipientAddresses for DRAFT folder based on threadId */ public static String getCanonicalAddressSms(ContentResolver r, int threadId) { /* @@ -1307,7 +1383,7 @@ public class BluetoothMapContent { 2. Get Recipient Address for corresponding Id from canonical-addresses table. */ - //Uri sAllCanonical = Uri.parse("content://mms-sms/canonical-addresses"); + // Uri sAllCanonical = Uri.parse("content://mms-sms/canonical-addresses"); Uri sAllCanonical = MmsSms.CONTENT_URI.buildUpon().appendPath("canonical-addresses").build(); Uri sAllThreadsUri = @@ -1318,13 +1394,25 @@ public class BluetoothMapContent { String whereClause = "_id=" + threadId; Log.v(TAG, "whereClause is " + whereClause); try { - cr = BluetoothMethodProxy.getInstance().contentResolverQuery(r, sAllThreadsUri, - RECIPIENT_ID_PROJECTION, whereClause, null, null); + cr = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + r, + sAllThreadsUri, + RECIPIENT_ID_PROJECTION, + whereClause, + null, + null); if (cr != null && cr.moveToFirst()) { recipientIds = cr.getString(0); - Log.v(TAG, - "cursor.getCount(): " + cr.getCount() + "recipientIds: " + recipientIds - + "selection: " + whereClause); + Log.v( + TAG, + "cursor.getCount(): " + + cr.getCount() + + "recipientIds: " + + recipientIds + + "selection: " + + whereClause); } } finally { if (cr != null) { @@ -1344,11 +1432,13 @@ public class BluetoothMapContent { } Log.v(TAG, "whereClause is " + whereClause); try { - cr = BluetoothMethodProxy.getInstance().contentResolverQuery(r, sAllCanonical, null, - whereClause, null, null); + cr = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + r, sAllCanonical, null, whereClause, null, null); if (cr != null && cr.moveToFirst()) { do { - //TODO: Multiple Recipeints are appended with ";" for now. + // TODO: Multiple Recipeints are appended with ";" for now. if (recipientAddress.length() != 0) { recipientAddress += ";"; } @@ -1375,8 +1465,15 @@ public class BluetoothMapContent { String[] projection = {Mms.Addr.ADDRESS}; Cursor c = null; try { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(r, uriAddress, projection, - selection, null, null); // TODO: Add projection + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + r, + uriAddress, + projection, + selection, + null, + null); // TODO: Add projection int colIndex = c.getColumnIndex(Mms.Addr.ADDRESS); if (c != null) { if (c.moveToFirst()) { @@ -1396,6 +1493,7 @@ public class BluetoothMapContent { /** * Matching functions for originator and recipient for MMS + * * @return true if found a match */ private boolean matchRecipientMms(Cursor c, String recip) { @@ -1570,13 +1668,27 @@ public class BluetoothMapContent { if (BluetoothMapContract.FOLDER_NAME_INBOX.equalsIgnoreCase(folder)) { where = Sms.TYPE + " = 1 AND " + Sms.THREAD_ID + " <> -1"; } else if (BluetoothMapContract.FOLDER_NAME_OUTBOX.equalsIgnoreCase(folder)) { - where = "(" + Sms.TYPE + " = 4 OR " + Sms.TYPE + " = 5 OR " + Sms.TYPE + " = 6) AND " - + Sms.THREAD_ID + " <> -1"; + where = + "(" + + Sms.TYPE + + " = 4 OR " + + Sms.TYPE + + " = 5 OR " + + Sms.TYPE + + " = 6) AND " + + Sms.THREAD_ID + + " <> -1"; } else if (BluetoothMapContract.FOLDER_NAME_SENT.equalsIgnoreCase(folder)) { where = Sms.TYPE + " = 2 AND " + Sms.THREAD_ID + " <> -1"; } else if (BluetoothMapContract.FOLDER_NAME_DRAFT.equalsIgnoreCase(folder)) { - where = Sms.TYPE + " = 3 AND " + "(" + Sms.THREAD_ID + " IS NULL OR " + Sms.THREAD_ID - + " <> -1 )"; + where = + Sms.TYPE + + " = 3 AND " + + "(" + + Sms.THREAD_ID + + " IS NULL OR " + + Sms.THREAD_ID + + " <> -1 )"; } else if (BluetoothMapContract.FOLDER_NAME_DELETED.equalsIgnoreCase(folder)) { where = Sms.THREAD_ID + " = -1"; } @@ -1593,8 +1705,14 @@ public class BluetoothMapContent { } else if (BluetoothMapContract.FOLDER_NAME_SENT.equalsIgnoreCase(folder)) { where = Mms.MESSAGE_BOX + " = 2 AND " + Mms.THREAD_ID + " <> -1"; } else if (BluetoothMapContract.FOLDER_NAME_DRAFT.equalsIgnoreCase(folder)) { - where = Mms.MESSAGE_BOX + " = 3 AND " + "(" + Mms.THREAD_ID + " IS NULL OR " - + Mms.THREAD_ID + " <> -1 )"; + where = + Mms.MESSAGE_BOX + + " = 3 AND " + + "(" + + Mms.THREAD_ID + + " IS NULL OR " + + Mms.THREAD_ID + + " <> -1 )"; } else if (BluetoothMapContract.FOLDER_NAME_DELETED.equalsIgnoreCase(folder)) { where = Mms.THREAD_ID + " = -1"; } @@ -1634,8 +1752,8 @@ public class BluetoothMapContent { return where; } - private String setWhereFilterFolderType(BluetoothMapFolderElement folderElement, - FilterInfo fi) { + private String setWhereFilterFolderType( + BluetoothMapFolderElement folderElement, FilterInfo fi) { String where = "1=1"; if (!folderElement.shouldIgnore()) { if (fi.mMsgType == FilterInfo.TYPE_SMS) { @@ -1692,8 +1810,11 @@ public class BluetoothMapContent { } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { where = " AND " + Mms.DATE + " >= " + (ap.getFilterPeriodBegin() / 1000L); } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL || fi.mMsgType == FilterInfo.TYPE_IM) { - where = " AND " + BluetoothMapContract.MessageColumns.DATE + " >= " - + (ap.getFilterPeriodBegin()); + where = + " AND " + + BluetoothMapContract.MessageColumns.DATE + + " >= " + + (ap.getFilterPeriodBegin()); } } @@ -1703,8 +1824,11 @@ public class BluetoothMapContent { } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { where += " AND " + Mms.DATE + " < " + (ap.getFilterPeriodEnd() / 1000L); } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL || fi.mMsgType == FilterInfo.TYPE_IM) { - where += " AND " + BluetoothMapContract.MessageColumns.DATE + " < " - + (ap.getFilterPeriodEnd()); + where += + " AND " + + BluetoothMapContract.MessageColumns.DATE + + " < " + + (ap.getFilterPeriodEnd()); } } return where; @@ -1717,8 +1841,12 @@ public class BluetoothMapContent { /* Be aware of wild cards in the beginning of string, may not be valid? */ if (orig != null && orig.length() > 0) { orig = orig.replace("*", "%"); - where = " AND " + BluetoothMapContract.MessageColumns.FROM_LIST + " LIKE '%" + orig - + "%'"; + where = + " AND " + + BluetoothMapContract.MessageColumns.FROM_LIST + + " LIKE '%" + + orig + + "%'"; } return where; } @@ -1730,8 +1858,12 @@ public class BluetoothMapContent { /* Be aware of wild cards in the beginning of string, may not be valid? */ if (orig != null && orig.length() > 0) { orig = orig.replace("*", "%"); - where = " AND " + BluetoothMapContract.MessageColumns.FROM_LIST + " LIKE '%" + orig - + "%'"; + where = + " AND " + + BluetoothMapContract.MessageColumns.FROM_LIST + + " LIKE '%" + + orig + + "%'"; } return where; } @@ -1742,8 +1874,11 @@ public class BluetoothMapContent { /*only MMS have priority info */ if (fi.mMsgType == FilterInfo.TYPE_MMS) { if (pri == 0x0002) { - where += " AND " + Mms.PRIORITY + "<=" + Integer.toString( - PduHeaders.PRIORITY_NORMAL); + where += + " AND " + + Mms.PRIORITY + + "<=" + + Integer.toString(PduHeaders.PRIORITY_NORMAL); } else if (pri == 0x0001) { where += " AND " + Mms.PRIORITY + "=" + Integer.toString(PduHeaders.PRIORITY_HIGH); } @@ -1766,10 +1901,20 @@ public class BluetoothMapContent { /* Be aware of wild cards in the beginning of string, may not be valid? */ if (recip != null && recip.length() > 0) { recip = recip.replace("*", "%"); - where = " AND (" + BluetoothMapContract.MessageColumns.TO_LIST + " LIKE '%" + recip - + "%' OR " + BluetoothMapContract.MessageColumns.CC_LIST + " LIKE '%" + recip - + "%' OR " + BluetoothMapContract.MessageColumns.BCC_LIST + " LIKE '%" + recip - + "%' )"; + where = + " AND (" + + BluetoothMapContract.MessageColumns.TO_LIST + + " LIKE '%" + + recip + + "%' OR " + + BluetoothMapContract.MessageColumns.CC_LIST + + " LIKE '%" + + recip + + "%' OR " + + BluetoothMapContract.MessageColumns.BCC_LIST + + " LIKE '%" + + recip + + "%' )"; } return where; } @@ -1815,8 +1960,8 @@ public class BluetoothMapContent { return where; } - private String setWhereFilter(BluetoothMapFolderElement folderElement, FilterInfo fi, - BluetoothMapAppParams ap) { + private String setWhereFilter( + BluetoothMapFolderElement folderElement, FilterInfo fi, BluetoothMapAppParams ap) { String where = ""; where += setWhereFilterFolderType(folderElement, fi); @@ -1842,11 +1987,10 @@ public class BluetoothMapContent { return where; } - /* Used only for SMS/MMS */ @VisibleForTesting - void setConvoWhereFilterSmsMms(StringBuilder selection, FilterInfo fi, - BluetoothMapAppParams ap) { + void setConvoWhereFilterSmsMms( + StringBuilder selection, FilterInfo fi, BluetoothMapAppParams ap) { if (smsSelected(fi, ap) || mmsSelected(ap)) { @@ -1863,13 +2007,15 @@ public class BluetoothMapContent { // Filter time if ((ap.getFilterLastActivityBegin() != BluetoothMapAppParams.INVALID_VALUE_PARAMETER)) { - selection.append(" AND ") + selection + .append(" AND ") .append(Threads.DATE) .append(" >= ") .append(ap.getFilterLastActivityBegin()); } if ((ap.getFilterLastActivityEnd() != BluetoothMapAppParams.INVALID_VALUE_PARAMETER)) { - selection.append(" AND ") + selection + .append(" AND ") .append(Threads.DATE) .append(" <= ") .append(ap.getFilterLastActivityEnd()); @@ -1881,7 +2027,8 @@ public class BluetoothMapContent { convoId = ap.getFilterConvoId().getLeastSignificantBits(); } if (convoId > 0) { - selection.append(" AND ") + selection + .append(" AND ") .append(Threads._ID) .append(" = ") .append(Long.toString(convoId)); @@ -1889,10 +2036,9 @@ public class BluetoothMapContent { } } - /** - * Determine from application parameter if sms should be included. - * The filter mask is set for message types not selected + * Determine from application parameter if sms should be included. The filter mask is set for + * message types not selected * * @return boolean true if sms is selected, false if not */ @@ -1907,18 +2053,20 @@ public class BluetoothMapContent { return true; } - if ((msgType & (BluetoothMapAppParams.FILTER_NO_SMS_CDMA - | BluetoothMapAppParams.FILTER_NO_SMS_GSM)) == 0) { + if ((msgType + & (BluetoothMapAppParams.FILTER_NO_SMS_CDMA + | BluetoothMapAppParams.FILTER_NO_SMS_GSM)) + == 0) { return true; } - if (((msgType & BluetoothMapAppParams.FILTER_NO_SMS_GSM) == 0) && (phoneType - == TelephonyManager.PHONE_TYPE_GSM)) { + if (((msgType & BluetoothMapAppParams.FILTER_NO_SMS_GSM) == 0) + && (phoneType == TelephonyManager.PHONE_TYPE_GSM)) { return true; } - if (((msgType & BluetoothMapAppParams.FILTER_NO_SMS_CDMA) == 0) && (phoneType - == TelephonyManager.PHONE_TYPE_CDMA)) { + if (((msgType & BluetoothMapAppParams.FILTER_NO_SMS_CDMA) == 0) + && (phoneType == TelephonyManager.PHONE_TYPE_CDMA)) { return true; } @@ -1926,8 +2074,8 @@ public class BluetoothMapContent { } /** - * Determine from application parameter if mms should be included. - * The filter mask is set for message types not selected + * Determine from application parameter if mms should be included. The filter mask is set for + * message types not selected * * @return boolean true if mms is selected, false if not */ @@ -1949,8 +2097,8 @@ public class BluetoothMapContent { } /** - * Determine from application parameter if email should be included. - * The filter mask is set for message types not selected + * Determine from application parameter if email should be included. The filter mask is set for + * message types not selected * * @return boolean true if email is selected, false if not */ @@ -1971,8 +2119,8 @@ public class BluetoothMapContent { } /** - * Determine from application parameter if IM should be included. - * The filter mask is set for message types not selected + * Determine from application parameter if IM should be included. The filter mask is set for + * message types not selected * * @return boolean true if im is selected, false if not */ @@ -2003,12 +2151,13 @@ public class BluetoothMapContent { /** * Get a listing of message in folder after applying filter. + * * @param folderElement Must contain a valid folder string != null * @param ap Parameters specifying message content and filters * @return Listing object containing requested messages */ - public BluetoothMapMessageListing msgListing(BluetoothMapFolderElement folderElement, - BluetoothMapAppParams ap) { + public BluetoothMapMessageListing msgListing( + BluetoothMapFolderElement folderElement, BluetoothMapAppParams ap) { Log.d(TAG, "msgListing: messageType = " + ap.getFilterMessageType()); BluetoothMapMessageListing bmList = new BluetoothMapMessageListing(); @@ -2018,12 +2167,20 @@ public class BluetoothMapContent { if (ap.getParameterMask() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER || ap.getParameterMask() == 0) { ap.setParameterMask(PARAMETER_MASK_ALL_ENABLED); - Log.v(TAG, "msgListing(): appParameterMask is zero or not present, " - + "changing to all enabled by default: " + ap.getParameterMask()); - } - Log.v(TAG, "folderElement hasSmsMmsContent = " + folderElement.hasSmsMmsContent() - + " folderElement.hasEmailContent = " + folderElement.hasEmailContent() - + " folderElement.hasImContent = " + folderElement.hasImContent()); + Log.v( + TAG, + "msgListing(): appParameterMask is zero or not present, " + + "changing to all enabled by default: " + + ap.getParameterMask()); + } + Log.v( + TAG, + "folderElement hasSmsMmsContent = " + + folderElement.hasSmsMmsContent() + + " folderElement.hasEmailContent = " + + folderElement.hasEmailContent() + + " folderElement.hasImContent = " + + folderElement.hasImContent()); /* Cache some info used throughout filtering */ FilterInfo fi = new FilterInfo(); @@ -2039,26 +2196,36 @@ public class BluetoothMapContent { } try { if (smsSelected(fi, ap) && folderElement.hasSmsMmsContent()) { - if (ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL - | BluetoothMapAppParams.FILTER_NO_MMS - | BluetoothMapAppParams.FILTER_NO_SMS_GSM - | BluetoothMapAppParams.FILTER_NO_IM) || ap.getFilterMessageType() == ( - BluetoothMapAppParams.FILTER_NO_EMAIL | BluetoothMapAppParams.FILTER_NO_MMS - | BluetoothMapAppParams.FILTER_NO_SMS_CDMA - | BluetoothMapAppParams.FILTER_NO_IM)) { - //set real limit and offset if only this type is used + if (ap.getFilterMessageType() + == (BluetoothMapAppParams.FILTER_NO_EMAIL + | BluetoothMapAppParams.FILTER_NO_MMS + | BluetoothMapAppParams.FILTER_NO_SMS_GSM + | BluetoothMapAppParams.FILTER_NO_IM) + || ap.getFilterMessageType() + == (BluetoothMapAppParams.FILTER_NO_EMAIL + | BluetoothMapAppParams.FILTER_NO_MMS + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + | BluetoothMapAppParams.FILTER_NO_IM)) { + // set real limit and offset if only this type is used // (only if offset/limit is used) limit = " LIMIT " + ap.getMaxListCount() + " OFFSET " + ap.getStartOffset(); Log.d(TAG, "SMS Limit => " + limit); offsetNum = 0; } fi.mMsgType = FilterInfo.TYPE_SMS; - if (ap.getFilterPriority() != 1) { /*SMS cannot have high priority*/ + if (ap.getFilterPriority() != 1) { + /*SMS cannot have high priority*/ String where = setWhereFilter(folderElement, fi, ap); Log.d(TAG, "msgType: " + fi.mMsgType + " where: " + where); - smsCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Sms.CONTENT_URI, SMS_PROJECTION, where, null, - Sms.DATE + " DESC" + limit); + smsCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Sms.CONTENT_URI, + SMS_PROJECTION, + where, + null, + Sms.DATE + " DESC" + limit); if (smsCursor != null) { BluetoothMapMessageListingElement e = null; // store column index so we dont have to look them up anymore (optimization) @@ -2076,12 +2243,13 @@ public class BluetoothMapContent { } if (mmsSelected(ap) && folderElement.hasSmsMmsContent()) { - if (ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL - | BluetoothMapAppParams.FILTER_NO_SMS_CDMA - | BluetoothMapAppParams.FILTER_NO_SMS_GSM - | BluetoothMapAppParams.FILTER_NO_IM)) { - //set real limit and offset if only this type is used - //(only if offset/limit is used) + if (ap.getFilterMessageType() + == (BluetoothMapAppParams.FILTER_NO_EMAIL + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + | BluetoothMapAppParams.FILTER_NO_SMS_GSM + | BluetoothMapAppParams.FILTER_NO_IM)) { + // set real limit and offset if only this type is used + // (only if offset/limit is used) limit = " LIMIT " + ap.getMaxListCount() + " OFFSET " + ap.getStartOffset(); Log.d(TAG, "MMS Limit => " + limit); offsetNum = 0; @@ -2091,9 +2259,15 @@ public class BluetoothMapContent { where += " AND " + INTERESTED_MESSAGE_TYPE_CLAUSE; if (!where.isEmpty()) { Log.d(TAG, "msgType: " + fi.mMsgType + " where: " + where); - mmsCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Mms.CONTENT_URI, MMS_PROJECTION, where, null, - Mms.DATE + " DESC" + limit); + mmsCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Mms.CONTENT_URI, + MMS_PROJECTION, + where, + null, + Mms.DATE + " DESC" + limit); if (mmsCursor != null) { BluetoothMapMessageListingElement e = null; // store column index so we dont have to look them up anymore (optimization) @@ -2111,12 +2285,13 @@ public class BluetoothMapContent { } if (emailSelected(ap) && folderElement.hasEmailContent()) { - if (ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_MMS - | BluetoothMapAppParams.FILTER_NO_SMS_CDMA - | BluetoothMapAppParams.FILTER_NO_SMS_GSM - | BluetoothMapAppParams.FILTER_NO_IM)) { - //set real limit and offset if only this type is used - //(only if offset/limit is used) + if (ap.getFilterMessageType() + == (BluetoothMapAppParams.FILTER_NO_MMS + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + | BluetoothMapAppParams.FILTER_NO_SMS_GSM + | BluetoothMapAppParams.FILTER_NO_IM)) { + // set real limit and offset if only this type is used + // (only if offset/limit is used) limit = " LIMIT " + ap.getMaxListCount() + " OFFSET " + ap.getStartOffset(); Log.d(TAG, "Email Limit => " + limit); offsetNum = 0; @@ -2127,9 +2302,17 @@ public class BluetoothMapContent { if (!where.isEmpty()) { Log.d(TAG, "msgType: " + fi.mMsgType + " where: " + where); Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - emailCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION, where, null, - BluetoothMapContract.MessageColumns.DATE + " DESC" + limit); + emailCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_MESSAGE_PROJECTION, + where, + null, + BluetoothMapContract.MessageColumns.DATE + + " DESC" + + limit); if (emailCursor != null) { BluetoothMapMessageListingElement e = null; // store column index so we dont have to look them up anymore (optimization) @@ -2146,12 +2329,13 @@ public class BluetoothMapContent { } if (imSelected(ap) && folderElement.hasImContent()) { - if (ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_MMS - | BluetoothMapAppParams.FILTER_NO_SMS_CDMA - | BluetoothMapAppParams.FILTER_NO_SMS_GSM - | BluetoothMapAppParams.FILTER_NO_EMAIL)) { - //set real limit and offset if only this type is used - //(only if offset/limit is used) + if (ap.getFilterMessageType() + == (BluetoothMapAppParams.FILTER_NO_MMS + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA + | BluetoothMapAppParams.FILTER_NO_SMS_GSM + | BluetoothMapAppParams.FILTER_NO_EMAIL)) { + // set real limit and offset if only this type is used + // (only if offset/limit is used) limit = " LIMIT " + ap.getMaxListCount() + " OFFSET " + ap.getStartOffset(); Log.d(TAG, "IM Limit => " + limit); offsetNum = 0; @@ -2161,9 +2345,15 @@ public class BluetoothMapContent { Log.d(TAG, "msgType: " + fi.mMsgType + " where: " + where); Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - imCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION, where, null, - BluetoothMapContract.MessageColumns.DATE + " DESC" + limit); + imCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION, + where, + null, + BluetoothMapContract.MessageColumns.DATE + " DESC" + limit); if (imCursor != null) { BluetoothMapMessageListingElement e = null; // store column index so we dont have to look them up anymore (optimization) @@ -2189,8 +2379,8 @@ public class BluetoothMapContent { * then ele.getType() returns "null" even for a valid cursor. * Avoid NullPointerException in equals() check when 'mType' value is "null" */ TYPE tmpType = ele.getType(); - if (smsCursor != null && ((TYPE.SMS_GSM).equals(tmpType) || (TYPE.SMS_CDMA).equals( - tmpType))) { + if (smsCursor != null + && ((TYPE.SMS_GSM).equals(tmpType) || (TYPE.SMS_CDMA).equals(tmpType))) { tmpCursor = smsCursor; fi.mMsgType = FilterInfo.TYPE_SMS; } else if (mmsCursor != null && (TYPE.MMS).equals(tmpType)) { @@ -2240,13 +2430,13 @@ public class BluetoothMapContent { } } - Log.d(TAG, "messagelisting end"); return bmList; } /** * Get the size of the message listing + * * @param folderElement Must contain a valid folder string != null * @param ap Parameters specifying message content and filters * @return Integer equal to message listing size @@ -2262,8 +2452,15 @@ public class BluetoothMapContent { if (smsSelected(fi, ap) && folderElement.hasSmsMmsContent()) { fi.mMsgType = FilterInfo.TYPE_SMS; String where = setWhereFilter(folderElement, fi, ap); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Sms.CONTENT_URI, SMS_PROJECTION, where, null, Sms.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Sms.CONTENT_URI, + SMS_PROJECTION, + where, + null, + Sms.DATE + " DESC"); try { if (c != null) { cnt = c.getCount(); @@ -2278,8 +2475,15 @@ public class BluetoothMapContent { if (mmsSelected(ap) && folderElement.hasSmsMmsContent()) { fi.mMsgType = FilterInfo.TYPE_MMS; String where = setWhereFilter(folderElement, fi, ap); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Mms.CONTENT_URI, MMS_PROJECTION, where, null, Mms.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Mms.CONTENT_URI, + MMS_PROJECTION, + where, + null, + Mms.DATE + " DESC"); try { if (c != null) { cnt += c.getCount(); @@ -2296,9 +2500,15 @@ public class BluetoothMapContent { String where = setWhereFilter(folderElement, fi, ap); if (!where.isEmpty()) { Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION, where, null, - BluetoothMapContract.MessageColumns.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_MESSAGE_PROJECTION, + where, + null, + BluetoothMapContract.MessageColumns.DATE + " DESC"); try { if (c != null) { cnt += c.getCount(); @@ -2316,9 +2526,15 @@ public class BluetoothMapContent { String where = setWhereFilter(folderElement, fi, ap); if (!where.isEmpty()) { Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION, where, null, - BluetoothMapContract.MessageColumns.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION, + where, + null, + BluetoothMapContract.MessageColumns.DATE + " DESC"); try { if (c != null) { cnt += c.getCount(); @@ -2337,12 +2553,13 @@ public class BluetoothMapContent { /** * Return true if there are unread messages in the requested list of messages + * * @param folderElement folder where the message listing should come from * @param ap application parameter object * @return true if unread messages are in the list, else false */ - public boolean msgListingHasUnread(BluetoothMapFolderElement folderElement, - BluetoothMapAppParams ap) { + public boolean msgListingHasUnread( + BluetoothMapFolderElement folderElement, BluetoothMapAppParams ap) { Log.d(TAG, "msgListingHasUnread: folder = " + folderElement.getName()); int cnt = 0; @@ -2355,8 +2572,15 @@ public class BluetoothMapContent { String where = setWhereFilterFolderType(folderElement, fi); where += " AND " + Sms.READ + "=0 "; where += setWhereFilterPeriod(ap, fi); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Sms.CONTENT_URI, SMS_PROJECTION, where, null, Sms.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Sms.CONTENT_URI, + SMS_PROJECTION, + where, + null, + Sms.DATE + " DESC"); try { if (c != null) { cnt = c.getCount(); @@ -2373,8 +2597,15 @@ public class BluetoothMapContent { String where = setWhereFilterFolderType(folderElement, fi); where += " AND " + Mms.READ + "=0 "; where += setWhereFilterPeriod(ap, fi); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Mms.CONTENT_URI, MMS_PROJECTION, where, null, Sms.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Mms.CONTENT_URI, + MMS_PROJECTION, + where, + null, + Sms.DATE + " DESC"); try { if (c != null) { cnt += c.getCount(); @@ -2386,7 +2617,6 @@ public class BluetoothMapContent { } } - if (emailSelected(ap) && folderElement.getFolderId() != -1) { fi.mMsgType = FilterInfo.TYPE_EMAIL; String where = setWhereFilterFolderType(folderElement, fi); @@ -2394,9 +2624,15 @@ public class BluetoothMapContent { where += " AND " + BluetoothMapContract.MessageColumns.FLAG_READ + "=0 "; where += setWhereFilterPeriod(ap, fi); Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION, where, null, - BluetoothMapContract.MessageColumns.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_MESSAGE_PROJECTION, + where, + null, + BluetoothMapContract.MessageColumns.DATE + " DESC"); try { if (c != null) { cnt += c.getCount(); @@ -2416,9 +2652,15 @@ public class BluetoothMapContent { where += " AND " + BluetoothMapContract.MessageColumns.FLAG_READ + "=0 "; where += setWhereFilterPeriod(ap, fi); Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION, where, null, - BluetoothMapContract.MessageColumns.DATE + " DESC"); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_INSTANT_MESSAGE_PROJECTION, + where, + null, + BluetoothMapContract.MessageColumns.DATE + " DESC"); try { if (c != null) { cnt += c.getCount(); @@ -2437,6 +2679,7 @@ public class BluetoothMapContent { /** * Build the conversation listing. + * * @param ap The Application Parameters * @param sizeOnly TRUE: don't populate the list members, only build the list to get the size. * @return the BluetoothMapConvoListing @@ -2451,8 +2694,11 @@ public class BluetoothMapContent { if (ap.getConvoParameterMask() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER || ap.getConvoParameterMask() == 0) { ap.setConvoParameterMask(CONVO_PARAMETER_MASK_DEFAULT); - Log.d(TAG, "convoListing(): appParameterMask is zero or not present, " - + "changing to default: " + ap.getConvoParameterMask()); + Log.d( + TAG, + "convoListing(): appParameterMask is zero or not present, " + + "changing to default: " + + ap.getConvoParameterMask()); } /* Possible filters: @@ -2487,19 +2733,22 @@ public class BluetoothMapContent { ((~ap.getFilterMessageType()) & BluetoothMapAppParams.FILTER_MSG_TYPE_MASK); int maxThreads = ap.getMaxListCount() + ap.getStartOffset(); - try { if (smsSelected(fi, ap) || mmsSelected(ap)) { String limit = ""; - if ((!sizeOnly) && (ap.getMaxListCount() > 0) && (ap.getFilterRecipient() - == null)) { + if ((!sizeOnly) + && (ap.getMaxListCount() > 0) + && (ap.getFilterRecipient() == null)) { /* We can only use limit if we do not have a contacts filter */ limit = " LIMIT " + maxThreads; } StringBuilder sortOrder = new StringBuilder(Threads.DATE + " DESC"); - if ((!sizeOnly) && (((msgTypesInclude & ~(BluetoothMapAppParams.FILTER_NO_SMS_GSM - | BluetoothMapAppParams.FILTER_NO_SMS_CDMA)) - | BluetoothMapAppParams.FILTER_NO_MMS) == 0) + if ((!sizeOnly) + && (((msgTypesInclude + & ~(BluetoothMapAppParams.FILTER_NO_SMS_GSM + | BluetoothMapAppParams.FILTER_NO_SMS_CDMA)) + | BluetoothMapAppParams.FILTER_NO_MMS) + == 0) && ap.getFilterRecipient() == null) { // SMS/MMS messages only and no recipient filter - use optimization. limit = " LIMIT " + ap.getMaxListCount() + " OFFSET " + ap.getStartOffset(); @@ -2509,17 +2758,28 @@ public class BluetoothMapContent { StringBuilder selection = new StringBuilder(120); // This covers most cases selection.append("1=1 "); // just to simplify building the where-clause setConvoWhereFilterSmsMms(selection, fi, ap); - Uri uri = Threads.CONTENT_URI.buildUpon() - .appendQueryParameter("simple", "true") - .build(); + Uri uri = + Threads.CONTENT_URI + .buildUpon() + .appendQueryParameter("simple", "true") + .build(); sortOrder.append(limit); - Log.d(TAG, "Query using selection: " + selection.toString() + " - sortOrder: " - + sortOrder.toString()); + Log.d( + TAG, + "Query using selection: " + + selection.toString() + + " - sortOrder: " + + sortOrder.toString()); // TODO: Optimize: Reduce projection based on convo parameter mask smsMmsCursor = - BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uri, - MMS_SMS_THREAD_PROJECTION, selection.toString(), null, - sortOrder.toString()); + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + uri, + MMS_SMS_THREAD_PROJECTION, + selection.toString(), + null, + sortOrder.toString()); if (smsMmsCursor != null) { // store column index so we don't have to look them up anymore (optimization) Log.d(TAG, "Found " + smsMmsCursor.getCount() + " sms/mms conversations."); @@ -2548,8 +2808,8 @@ public class BluetoothMapContent { // the filter, hence the item is irrelevant // TODO: Perhaps the spec. should be changes to be able to search on // phone number as well? - if (addSmsMmsContacts(convoElement, contacts, idsStr, - ap.getFilterRecipient(), ap)) { + if (addSmsMmsContacts( + convoElement, contacts, idsStr, ap.getFilterRecipient(), ap)) { convoList.add(convoElement); if (!sizeOnly && count >= maxThreads) { break; @@ -2573,20 +2833,31 @@ public class BluetoothMapContent { contentUri = appendConvoListQueryParameters(ap, contentUri); Log.v(TAG, "URI with parameters: " + contentUri.toString()); // TODO: Optimize: Reduce projection based on convo parameter mask - imEmailCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contentUri, BluetoothMapContract.BT_CONVERSATION_PROJECTION, null, null, - BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY - + " DESC, " - + BluetoothMapContract.ConversationColumns.THREAD_ID - + " ASC"); + imEmailCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_CONVERSATION_PROJECTION, + null, + null, + BluetoothMapContract.ConversationColumns + .LAST_THREAD_ACTIVITY + + " DESC, " + + BluetoothMapContract.ConversationColumns.THREAD_ID + + " ASC"); if (imEmailCursor != null) { BluetoothMapConvoListingElement e = null; // store column index so we don't have to look them up anymore (optimization) // Here we rely on only a single account-based message type for each MAS. fi.setEmailImConvoColumns(imEmailCursor); boolean isValid = imEmailCursor.moveToNext(); - Log.d(TAG, "Found " + imEmailCursor.getCount() - + " EMAIL/IM conversations. isValid = " + isValid); + Log.d( + TAG, + "Found " + + imEmailCursor.getCount() + + " EMAIL/IM conversations. isValid = " + + isValid); while (isValid && ((sizeOnly) || (count < maxThreads))) { long threadId = imEmailCursor.getLong(fi.mConvoColConvoId); long nextThreadId; @@ -2596,12 +2867,13 @@ public class BluetoothMapContent { do { nextThreadId = imEmailCursor.getLong(fi.mConvoColConvoId); - Log.v(TAG, " threadId = " + threadId + " newThreadId = " - + nextThreadId); + Log.v( + TAG, + " threadId = " + threadId + " newThreadId = " + nextThreadId); // TODO: This seems rather inefficient in the case where we do not need // to reduce the list. - } while ((nextThreadId == threadId) && (isValid = - imEmailCursor.moveToNext())); + } while ((nextThreadId == threadId) + && (isValid = imEmailCursor.moveToNext())); } } } @@ -2629,13 +2901,14 @@ public class BluetoothMapContent { switch (type) { case SMS_CDMA: case SMS_GSM: - case MMS: { - tmpCursor = null; // SMS/MMS needs special treatment - if (smsMmsCursor != null) { - populateSmsMmsConvoElement(ele, smsMmsCursor, ap, contacts); + case MMS: + { + tmpCursor = null; // SMS/MMS needs special treatment + if (smsMmsCursor != null) { + populateSmsMmsConvoElement(ele, smsMmsCursor, ap, contacts); + } + break; } - break; - } case EMAIL: tmpCursor = imEmailCursor; fi.mMsgType = FilterInfo.TYPE_EMAIL; @@ -2655,8 +2928,10 @@ public class BluetoothMapContent { populateImEmailConvoElement(ele, tmpCursor, ap, fi); } else { // No, it will be for SMS/MMS at the moment - Log.d(TAG, "tmpCursor is Null - something is wrong - or the message is" - + " of type SMS/MMS"); + Log.d( + TAG, + "tmpCursor is Null - something is wrong - or the message is" + + " of type SMS/MMS"); } } } finally { @@ -2671,10 +2946,10 @@ public class BluetoothMapContent { return convoList; } - /** - * Refreshes the entire list of SMS/MMS conversation version counters. Use it to generate a - * new ConvoListVersinoCounter in mSmsMmsConvoListVersion + * Refreshes the entire list of SMS/MMS conversation version counters. Use it to generate a new + * ConvoListVersinoCounter in mSmsMmsConvoListVersion + * * @return true if a list change has been detected */ boolean refreshSmsMmsConvoVersions() { @@ -2756,8 +3031,9 @@ public class BluetoothMapContent { } /** - * Refreshes the entire list of SMS/MMS conversation version counters. Use it to generate a - * new ConvoListVersinoCounter in mSmsMmsConvoListVersion + * Refreshes the entire list of SMS/MMS conversation version counters. Use it to generate a new + * ConvoListVersinoCounter in mSmsMmsConvoListVersion + * * @return true if a list change has been detected */ boolean refreshImEmailConvoVersions() { @@ -2767,9 +3043,16 @@ public class BluetoothMapContent { Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_CONVERSATION); Log.v(TAG, "URI with parameters: " + contentUri.toString()); - Cursor imEmailCursor = mResolver.query(contentUri, CONVO_VERSION_PROJECTION, null, null, - BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY + " DESC, " - + BluetoothMapContract.ConversationColumns.THREAD_ID + " ASC"); + Cursor imEmailCursor = + mResolver.query( + contentUri, + CONVO_VERSION_PROJECTION, + null, + null, + BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY + + " DESC, " + + BluetoothMapContract.ConversationColumns.THREAD_ID + + " ASC"); try { if (imEmailCursor != null) { BluetoothMapConvoListingElement convoElement = null; @@ -2777,8 +3060,12 @@ public class BluetoothMapContent { // Here we rely on only a single account-based message type for each MAS. fi.setEmailImConvoColumns(imEmailCursor); boolean isValid = imEmailCursor.moveToNext(); - Log.v(TAG, "Found " + imEmailCursor.getCount() - + " EMAIL/IM conversations. isValid = " + isValid); + Log.v( + TAG, + "Found " + + imEmailCursor.getCount() + + " EMAIL/IM conversations. isValid = " + + isValid); synchronized (getImEmailConvoList()) { int size = Math.max(getImEmailConvoList().size(), imEmailCursor.getCount()); boolean convoChanged = false; @@ -2852,10 +3139,11 @@ public class BluetoothMapContent { } /** - * Update the convoVersionCounter within the element passed as parameter. - * This function has the side effect to update the ConvoListVersionCounter if needed. - * This function ignores changes to contacts as this shall not change the convoVersionCounter, - * only the convoListVersion counter, which will be updated upon request. + * Update the convoVersionCounter within the element passed as parameter. This function has the + * side effect to update the ConvoListVersionCounter if needed. This function ignores changes to + * contacts as this shall not change the convoVersionCounter, only the convoListVersion counter, + * which will be updated upon request. + * * @param ele Element to update shall not be null. */ private void updateSmsMmsConvoVersion(Cursor cursor, BluetoothMapConvoListingElement ele) { @@ -2895,14 +3183,15 @@ public class BluetoothMapContent { } /** - * Update the convoVersionCounter within the element passed as parameter. - * This function has the side effect to update the ConvoListVersionCounter if needed. - * This function ignores changes to contacts as this shall not change the convoVersionCounter, - * only the convoListVersion counter, which will be updated upon request. + * Update the convoVersionCounter within the element passed as parameter. This function has the + * side effect to update the ConvoListVersionCounter if needed. This function ignores changes to + * contacts as this shall not change the convoVersionCounter, only the convoListVersion counter, + * which will be updated upon request. + * * @param ele Element to update shall not be null. */ - private void updateImEmailConvoVersion(Cursor cursor, FilterInfo fi, - BluetoothMapConvoListingElement ele) { + private void updateImEmailConvoVersion( + Cursor cursor, FilterInfo fi, BluetoothMapConvoListingElement ele) { long id = ele.getCpConvoId(); BluetoothMapConvoListingElement convoElement = getImEmailConvoList().get(id); boolean listChangeDetected = false; @@ -2946,15 +3235,19 @@ public class BluetoothMapContent { ele.setVersionCounter(convoElement.getVersionCounter()); } - private void populateSmsMmsConvoElement(BluetoothMapConvoListingElement ele, - Cursor smsMmsCursor, BluetoothMapAppParams ap, SmsMmsContacts contacts) { + private void populateSmsMmsConvoElement( + BluetoothMapConvoListingElement ele, + Cursor smsMmsCursor, + BluetoothMapAppParams ap, + SmsMmsContacts contacts) { smsMmsCursor.moveToPosition(ele.getCursorIndex()); // TODO: If we ever get beyond 31 bit, change to long int parameterMask = (int) ap.getConvoParameterMask(); // We always set a default value // TODO: How to determine whether the convo-IDs can be used across message // types? - ele.setConvoId(BluetoothMapUtils.CONVO_ID_TYPE_SMS_MMS, + ele.setConvoId( + BluetoothMapUtils.CONVO_ID_TYPE_SMS_MMS, smsMmsCursor.getLong(MMS_SMS_THREAD_COL_ID)); boolean read = smsMmsCursor.getInt(MMS_SMS_THREAD_COL_READ) == 1; @@ -3009,8 +3302,11 @@ public class BluetoothMapContent { } } - private void populateImEmailConvoElement(BluetoothMapConvoListingElement ele, Cursor tmpCursor, - BluetoothMapAppParams ap, FilterInfo fi) { + private void populateImEmailConvoElement( + BluetoothMapConvoListingElement ele, + Cursor tmpCursor, + BluetoothMapAppParams ap, + FilterInfo fi) { tmpCursor.moveToPosition(ele.getCursorIndex()); // TODO: If we ever get beyond 31 bit, change to long int parameterMask = (int) ap.getConvoParameterMask(); // We always set a default value @@ -3037,7 +3333,6 @@ public class BluetoothMapContent { ele.setLastActivity(-1); } - if ((parameterMask & CONVO_PARAM_MASK_CONVO_VERSION_COUNTER) != 0) { updateImEmailConvoVersion(tmpCursor, fi, ele); } @@ -3082,8 +3377,9 @@ public class BluetoothMapContent { } /** - * Extract the ConvoList parameters from appParams and build the matching URI with - * query parameters. + * Extract the ConvoList parameters from appParams and build the matching URI with query + * parameters. + * * @param ap the appParams from the request * @param contentUri the URI to append parameters to * @return the new URI with the appended parameters (if any) @@ -3098,13 +3394,13 @@ public class BluetoothMapContent { } long time = ap.getFilterLastActivityBegin(); if (time > 0) { - newUri.appendQueryParameter(BluetoothMapContract.FILTER_PERIOD_BEGIN, - Long.toString(time)); + newUri.appendQueryParameter( + BluetoothMapContract.FILTER_PERIOD_BEGIN, Long.toString(time)); } time = ap.getFilterLastActivityEnd(); if (time > 0) { - newUri.appendQueryParameter(BluetoothMapContract.FILTER_PERIOD_END, - Long.toString(time)); + newUri.appendQueryParameter( + BluetoothMapContract.FILTER_PERIOD_END, Long.toString(time)); } int readStatus = ap.getFilterReadStatus(); if (readStatus > 0) { @@ -3124,22 +3420,23 @@ public class BluetoothMapContent { convoId = ap.getFilterConvoId().getLeastSignificantBits(); } if (convoId > 0) { - newUri.appendQueryParameter(BluetoothMapContract.FILTER_THREAD_ID, - Long.toString(convoId)); + newUri.appendQueryParameter( + BluetoothMapContract.FILTER_THREAD_ID, Long.toString(convoId)); } return newUri.build(); } /** - * Procedure if we have a filter: - * - loop through all ids to examine if there is a match (this will build the cache) - * - If there is a match loop again to add all contacts. + * Procedure if we have a filter: - loop through all ids to examine if there is a match (this + * will build the cache) - If there is a match loop again to add all contacts. * - * Procedure if we don't have a filter - * - Add all contacts + *

Procedure if we don't have a filter - Add all contacts */ - private boolean addSmsMmsContacts(BluetoothMapConvoListingElement convoElement, - SmsMmsContacts contacts, String idsStr, String recipientFilter, + private boolean addSmsMmsContacts( + BluetoothMapConvoListingElement convoElement, + SmsMmsContacts contacts, + String idsStr, + String recipientFilter, BluetoothMapAppParams ap) { BluetoothMapConvoContactElement contactElement; int parameterMask = (int) ap.getConvoParameterMask(); // We always set a default value @@ -3168,10 +3465,16 @@ public class BluetoothMapContent { } MapContact contact = contacts.getContactNameFromPhone(addr, mResolver, recipientFilter); - Log.d(TAG, "id: " + longId + ", addr: " + addr + ", contact name: " - + (contact != null - ? contact.getName() + ", X-BT-UID: " + contact.getXBtUid() - : "null")); + Log.d( + TAG, + "id: " + + longId + + ", addr: " + + addr + + ", contact name: " + + (contact != null + ? contact.getName() + ", X-BT-UID: " + contact.getXBtUid() + : "null")); if (contact == null) { continue; } @@ -3254,15 +3557,19 @@ public class BluetoothMapContent { return ""; } - public byte[] getMessage(String handle, BluetoothMapAppParams appParams, - BluetoothMapFolderElement folderElement, String version) + public byte[] getMessage( + String handle, + BluetoothMapAppParams appParams, + BluetoothMapFolderElement folderElement, + String version) throws UnsupportedEncodingException { TYPE type = BluetoothMapUtils.getMsgTypeFromHandle(handle); mMessageVersion = version; long id = BluetoothMapUtils.getCpHandle(handle); if (appParams.getFractionRequest() == BluetoothMapAppParams.FRACTION_REQUEST_NEXT) { - throw new IllegalArgumentException("FRACTION_REQUEST_NEXT does not make sence as" - + " we always return the full message."); + throw new IllegalArgumentException( + "FRACTION_REQUEST_NEXT does not make sence as" + + " we always return the full message."); } switch (type) { case SMS_GSM: @@ -3279,11 +3586,11 @@ public class BluetoothMapContent { } } - private String setVCardFromPhoneNumber(BluetoothMapbMessage message, String phone, - boolean incoming) { + private String setVCardFromPhoneNumber( + BluetoothMapbMessage message, String phone, boolean incoming) { String contactId = null, contactName = null; String[] phoneNumbers = new String[1]; - //Handle possible exception for empty phone address + // Handle possible exception for empty phone address if (TextUtils.isEmpty(phone)) { return contactName; } @@ -3303,8 +3610,9 @@ public class BluetoothMapContent { String orderBy = Contacts._ID + " ASC"; // Get the contact _ID and name - p = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uri, projection, - selection, null, orderBy); + p = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(mResolver, uri, projection, selection, null, orderBy); try { if (p != null && p.moveToFirst()) { contactId = p.getString(p.getColumnIndex(Contacts._ID)); @@ -3318,16 +3626,23 @@ public class BluetoothMapContent { Cursor q = null; // Fetch the contact e-mail addresses try { - q = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, - ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", - new String[]{contactId}, null); + q = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + ContactsContract.CommonDataKinds.Email.CONTENT_URI, + null, + ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", + new String[] {contactId}, + null); if (q != null && q.moveToFirst()) { int i = 0; emailAddresses = new String[q.getCount()]; do { - String emailAddress = q.getString( - q.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS)); + String emailAddress = + q.getString( + q.getColumnIndex( + ContactsContract.CommonDataKinds.Email.ADDRESS)); emailAddresses[i++] = emailAddress; } while (q != null && q.moveToNext()); } @@ -3339,13 +3654,13 @@ public class BluetoothMapContent { if (incoming) { Log.v(TAG, "Adding originator for phone:" + phone); // Use version 3.0 as we only have a formatted name - message.addOriginator(contactName, contactName, phoneNumbers, emailAddresses, null, - null); + message.addOriginator( + contactName, contactName, phoneNumbers, emailAddresses, null, null); } else { Log.v(TAG, "Adding recipient for phone:" + phone); // Use version 3.0 as we only have a formatted name - message.addRecipient(contactName, contactName, phoneNumbers, emailAddresses, null, - null); + message.addRecipient( + contactName, contactName, phoneNumbers, emailAddresses, null, null); } return contactName; } @@ -3391,7 +3706,7 @@ public class BluetoothMapContent { String phone = c.getString(c.getColumnIndex(Sms.ADDRESS)); if ((phone == null) && type == Sms.MESSAGE_TYPE_DRAFT) { - //Fetch address for Drafts folder from "canonical_address" table + // Fetch address for Drafts folder from "canonical_address" table phone = getCanonicalAddressSms(mResolver, threadId); } time = c.getLong(c.getColumnIndex(Sms.DATE)); @@ -3401,7 +3716,7 @@ public class BluetoothMapContent { setVCardFromPhoneNumber(message, phone, false); } if (charset == MAP_MESSAGE_CHARSET_NATIVE) { - if (type == 1) { //Inbox + if (type == 1) { // Inbox message.setSmsBodyPdus( BluetoothMapSmsPdu.getDeliverPdus(mContext, msgBody, phone, time)); } else { @@ -3430,8 +3745,10 @@ public class BluetoothMapContent { Uri uriAddress = Uri.parse(uriStr); String contactName = null; - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uriAddress, - projection, selection, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, uriAddress, projection, selection, null, null); try { if (c.moveToFirst()) { do { @@ -3508,6 +3825,7 @@ public class BluetoothMapContent { /** * Read out the mms parts and update the bMessage object provided i {@linkplain message} + * * @param id the content provider ID of the message * @param message the bMessage object to add the information to */ @@ -3518,8 +3836,10 @@ public class BluetoothMapContent { String uriStr = new String(Mms.CONTENT_URI + "/" + id + "/part"); Uri uriAddress = Uri.parse(uriStr); BluetoothMapbMessageMime.MimePart part; - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uriAddress, - projection, selection, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, uriAddress, projection, selection, null, null); try { if (c.moveToFirst()) { do { @@ -3534,11 +3854,28 @@ public class BluetoothMapContent { String cl = c.getString(c.getColumnIndex(Mms.Part.CONTENT_LOCATION)); String cdisp = c.getString(c.getColumnIndex(Mms.Part.CONTENT_DISPOSITION)); - Log.v(TAG, " _id : " + partId + "\n ct : " + contentType - + "\n partname : " + name + "\n charset : " + charset - + "\n filename : " + filename + "\n text : " + text - + "\n fd : " + fd + "\n cid : " + cid + "\n cl : " + cl - + "\n cdisp : " + cdisp); + Log.v( + TAG, + " _id : " + + partId + + "\n ct : " + + contentType + + "\n partname : " + + name + + "\n charset : " + + charset + + "\n filename : " + + filename + + "\n text : " + + text + + "\n fd : " + + fd + + "\n cid : " + + cid + + "\n cl : " + + cl + + "\n cdisp : " + + cdisp); part = message.addMimePart(); part.mContentType = contentType; @@ -3631,12 +3968,11 @@ public class BluetoothMapContent { } /** - * * @param id the content provider id for the message to fetch. * @param appParams The application parameter object received from the client. * @return a byte[] containing the utf-8 encoded bMessage to send to the client. - * @throws UnsupportedEncodingException if UTF-8 is not supported, - * which is guaranteed to be supported on an android device + * @throws UnsupportedEncodingException if UTF-8 is not supported, which is guaranteed to be + * supported on an android device */ public byte[] getMmsMessage(long id, BluetoothMapAppParams appParams) throws UnsupportedEncodingException { @@ -3679,7 +4015,6 @@ public class BluetoothMapContent { // The addresses extractMmsAddresses(id, message); - return message.encode(); } } finally { @@ -3692,21 +4027,25 @@ public class BluetoothMapContent { } /** - * * @param id the content provider id for the message to fetch. * @param appParams The application parameter object received from the client. * @return a byte[] containing the utf-8 encoded bMessage to send to the client. - * @throws UnsupportedEncodingException if UTF-8 is not supported, - * which is guaranteed to be supported on an android device + * @throws UnsupportedEncodingException if UTF-8 is not supported, which is guaranteed to be + * supported on an android device */ - public byte[] getEmailMessage(long id, BluetoothMapAppParams appParams, - BluetoothMapFolderElement currentFolder) throws UnsupportedEncodingException { + public byte[] getEmailMessage( + long id, BluetoothMapAppParams appParams, BluetoothMapFolderElement currentFolder) + throws UnsupportedEncodingException { // Log print out of application parameters set if (appParams != null) { - Log.d(TAG, "TYPE_MESSAGE (GET): Attachment = " + appParams.getAttachment() - + ", Charset = " - + appParams.getCharset() + ", FractionRequest = " - + appParams.getFractionRequest()); + Log.d( + TAG, + "TYPE_MESSAGE (GET): Attachment = " + + appParams.getAttachment() + + ", Charset = " + + appParams.getCharset() + + ", FractionRequest = " + + appParams.getFractionRequest()); } // Throw exception if requester NATIVE charset for Email @@ -3717,8 +4056,15 @@ public class BluetoothMapContent { BluetoothMapbMessageEmail message = new BluetoothMapbMessageEmail(); Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, contentUri, - BluetoothMapContract.BT_MESSAGE_PROJECTION, "_ID = " + id, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_MESSAGE_PROJECTION, + "_ID = " + id, + null, + null); try { if (c != null && c.moveToFirst()) { BluetoothMapFolderElement folderElement; @@ -3730,15 +4076,22 @@ public class BluetoothMapContent { if (fractionRequest != BluetoothMapAppParams.INVALID_VALUE_PARAMETER) { // Fraction requested String fractionStr = (fractionRequest == 0) ? "FIRST" : "NEXT"; - Log.v(TAG, "getEmailMessage - FractionRequest " + fractionStr - + " - send compete message"); + Log.v( + TAG, + "getEmailMessage - FractionRequest " + + fractionStr + + " - send compete message"); // Check if message is complete and if not - request message from server - if (!c.getString(c.getColumnIndex( - BluetoothMapContract.MessageColumns.RECEPTION_STATE)) + if (!c.getString( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .RECEPTION_STATE)) .equalsIgnoreCase(BluetoothMapContract.RECEPTION_STATE_COMPLETE)) { // TODO: request message from server - Log.w(TAG, "getEmailMessage - receptionState not COMPLETE - Not " - + "Implemented!"); + Log.w( + TAG, + "getEmailMessage - receptionState not COMPLETE - Not " + + "Implemented!"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, @@ -3748,8 +4101,10 @@ public class BluetoothMapContent { } } // Set read status: - String read = c.getString( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_READ)); + String read = + c.getString( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FLAG_READ)); if (read != null && read.equalsIgnoreCase("1")) { message.setStatus(true); } else { @@ -3760,14 +4115,17 @@ public class BluetoothMapContent { message.setType(TYPE.EMAIL); message.setVersionString(mMessageVersion); // Set folder: - long folderId = c.getLong( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID)); + long folderId = + c.getLong( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FOLDER_ID)); folderElement = currentFolder.getFolderById(folderId); message.setCompleteFolder(folderElement.getFullPath()); // Set recipient: - String nameEmail = c.getString( - c.getColumnIndex(BluetoothMapContract.MessageColumns.TO_LIST)); + String nameEmail = + c.getString( + c.getColumnIndex(BluetoothMapContract.MessageColumns.TO_LIST)); Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(nameEmail); if (tokens.length != 0) { Log.d(TAG, "Recipient count= " + tokens.length); @@ -3783,8 +4141,10 @@ public class BluetoothMapContent { } // Set originator: - nameEmail = c.getString( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FROM_LIST)); + nameEmail = + c.getString( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FROM_LIST)); tokens = Rfc822Tokenizer.tokenize(nameEmail); if (tokens.length != 0) { Log.d(TAG, "Originator count= " + tokens.length); @@ -3804,23 +4164,27 @@ public class BluetoothMapContent { } } // Find out if we get attachments - String attStr = (appParams.getAttachment() == 0) ? "/" - + BluetoothMapContract.FILE_MSG_NO_ATTACHMENTS : ""; + String attStr = + (appParams.getAttachment() == 0) + ? "/" + BluetoothMapContract.FILE_MSG_NO_ATTACHMENTS + : ""; Uri uri = Uri.parse(contentUri + "/" + id + attStr); // Get email message body content int count = 0; try { - fd = BluetoothMethodProxy.getInstance().contentResolverOpenFileDescriptor( - mResolver, uri, "r"); + fd = + BluetoothMethodProxy.getInstance() + .contentResolverOpenFileDescriptor(mResolver, uri, "r"); is = new FileInputStream(fd.getFileDescriptor()); StringBuilder email = new StringBuilder(""); byte[] buffer = new byte[1024]; while ((count = is.read(buffer)) != -1) { // TODO: Handle breaks within a UTF8 character email.append(new String(buffer, 0, count)); - Log.v(TAG, "Email part = " + new String(buffer, 0, count) + " count=" - + count); + Log.v( + TAG, + "Email part = " + new String(buffer, 0, count) + " count=" + count); } // Set email message body: message.setEmailBody(email.toString()); @@ -3887,15 +4251,15 @@ public class BluetoothMapContent { } /** - * * @param id the content provider id for the message to fetch. * @param appParams The application parameter object received from the client. * @return a byte[] containing the utf-8 encoded bMessage to send to the client. - * @throws UnsupportedEncodingException if UTF-8 is not supported, - * which is guaranteed to be supported on an android device + * @throws UnsupportedEncodingException if UTF-8 is not supported, which is guaranteed to be + * supported on an android device */ - public byte[] getIMMessage(long id, BluetoothMapAppParams appParams, - BluetoothMapFolderElement folderElement) throws UnsupportedEncodingException { + public byte[] getIMMessage( + long id, BluetoothMapAppParams appParams, BluetoothMapFolderElement folderElement) + throws UnsupportedEncodingException { long threadId, folderId; if (appParams.getCharset() == MAP_MESSAGE_CHARSET_NATIVE) { @@ -3905,8 +4269,15 @@ public class BluetoothMapContent { BluetoothMapbMessageMime message = new BluetoothMapbMessageMime(); Uri contentUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, contentUri, - BluetoothMapContract.BT_MESSAGE_PROJECTION, "_ID = " + id, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contentUri, + BluetoothMapContract.BT_MESSAGE_PROJECTION, + "_ID = " + id, + null, + null); Cursor contacts = null; try { if (c != null && c.moveToFirst()) { @@ -3934,9 +4305,12 @@ public class BluetoothMapContent { c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns._ID))); message.setDate( c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns.DATE))); - message.setTextOnly(c.getInt( - c.getColumnIndex(BluetoothMapContract.MessageColumns.ATTACHMENT_SIZE)) - == 0); + message.setTextOnly( + c.getInt( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .ATTACHMENT_SIZE)) + == 0); message.setIncludeAttachments(appParams.getAttachment() != 0); @@ -3945,7 +4319,7 @@ public class BluetoothMapContent { // The parts - //FIXME next few lines are temporary code + // FIXME next few lines are temporary code MimePart part = message.addMimePart(); part.mData = c.getString((c.getColumnIndex(BluetoothMapContract.MessageColumns.BODY))) @@ -3957,24 +4331,39 @@ public class BluetoothMapContent { // FIXME end temp code Uri contactsUri = Uri.parse(mBaseUri + BluetoothMapContract.TABLE_CONVOCONTACT); - contacts = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - contactsUri, BluetoothMapContract.BT_CONTACT_PROJECTION, - BluetoothMapContract.ConvoContactColumns.CONVO_ID + " = " + threadId, null, - null); + contacts = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + contactsUri, + BluetoothMapContract.BT_CONTACT_PROJECTION, + BluetoothMapContract.ConvoContactColumns.CONVO_ID + + " = " + + threadId, + null, + null); // TODO this will not work for group-chats if (contacts != null && contacts.moveToFirst()) { - String name = contacts.getString( - contacts.getColumnIndex(BluetoothMapContract.ConvoContactColumns.NAME)); + String name = + contacts.getString( + contacts.getColumnIndex( + BluetoothMapContract.ConvoContactColumns.NAME)); String[] btUid = new String[1]; - btUid[0] = contacts.getString(contacts.getColumnIndex( - BluetoothMapContract.ConvoContactColumns.X_BT_UID)); - String nickname = contacts.getString(contacts.getColumnIndex( - BluetoothMapContract.ConvoContactColumns.NICKNAME)); + btUid[0] = + contacts.getString( + contacts.getColumnIndex( + BluetoothMapContract.ConvoContactColumns.X_BT_UID)); + String nickname = + contacts.getString( + contacts.getColumnIndex( + BluetoothMapContract.ConvoContactColumns.NICKNAME)); String[] btUci = new String[1]; String[] btOwnUci = new String[1]; btOwnUci[0] = mAccount.getUciFull(); - btUci[0] = contacts.getString( - contacts.getColumnIndex(BluetoothMapContract.ConvoContactColumns.UCI)); + btUci[0] = + contacts.getString( + contacts.getColumnIndex( + BluetoothMapContract.ConvoContactColumns.UCI)); if (folderId == BluetoothMapContract.FOLDER_ID_SENT || folderId == BluetoothMapContract.FOLDER_ID_OUTBOX) { message.addRecipient(nickname, name, null, null, btUid, btUci); @@ -3983,7 +4372,6 @@ public class BluetoothMapContent { } else { message.addOriginator(nickname, name, null, null, btUid, btUci); message.addRecipient(null, btOwnUci); - } } return message.encode(); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index dc8ca5486dd..a8b0493eaad 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -91,35 +91,22 @@ import java.util.concurrent.TimeUnit; public class BluetoothMapContentObserver { private static final String TAG = "BluetoothMapContentObserver"; - // A message older than this will be ignored when notifying a new message. @VisibleForTesting static final Duration NEW_MESSAGE_DURATION_FOR_NOTIFICATION = Duration.ofDays(7); - @VisibleForTesting - static final String EVENT_TYPE_NEW = "NewMessage"; - @VisibleForTesting - static final String EVENT_TYPE_DELETE = "MessageDeleted"; - @VisibleForTesting - static final String EVENT_TYPE_REMOVED = "MessageRemoved"; - @VisibleForTesting - static final String EVENT_TYPE_SHIFT = "MessageShift"; - @VisibleForTesting - static final String EVENT_TYPE_DELEVERY_SUCCESS = "DeliverySuccess"; - @VisibleForTesting - static final String EVENT_TYPE_SENDING_SUCCESS = "SendingSuccess"; - @VisibleForTesting - static final String EVENT_TYPE_SENDING_FAILURE = "SendingFailure"; - @VisibleForTesting - static final String EVENT_TYPE_DELIVERY_FAILURE = "DeliveryFailure"; - @VisibleForTesting - static final String EVENT_TYPE_READ_STATUS = "ReadStatusChanged"; - @VisibleForTesting - static final String EVENT_TYPE_CONVERSATION = "ConversationChanged"; - @VisibleForTesting - static final String EVENT_TYPE_PRESENCE = "ParticipantPresenceChanged"; - @VisibleForTesting - static final String EVENT_TYPE_CHAT_STATE = "ParticipantChatStateChanged"; + @VisibleForTesting static final String EVENT_TYPE_NEW = "NewMessage"; + @VisibleForTesting static final String EVENT_TYPE_DELETE = "MessageDeleted"; + @VisibleForTesting static final String EVENT_TYPE_REMOVED = "MessageRemoved"; + @VisibleForTesting static final String EVENT_TYPE_SHIFT = "MessageShift"; + @VisibleForTesting static final String EVENT_TYPE_DELEVERY_SUCCESS = "DeliverySuccess"; + @VisibleForTesting static final String EVENT_TYPE_SENDING_SUCCESS = "SendingSuccess"; + @VisibleForTesting static final String EVENT_TYPE_SENDING_FAILURE = "SendingFailure"; + @VisibleForTesting static final String EVENT_TYPE_DELIVERY_FAILURE = "DeliveryFailure"; + @VisibleForTesting static final String EVENT_TYPE_READ_STATUS = "ReadStatusChanged"; + @VisibleForTesting static final String EVENT_TYPE_CONVERSATION = "ConversationChanged"; + @VisibleForTesting static final String EVENT_TYPE_PRESENCE = "ParticipantPresenceChanged"; + @VisibleForTesting static final String EVENT_TYPE_CHAT_STATE = "ParticipantChatStateChanged"; private static final long EVENT_FILTER_NEW_MESSAGE = 1L; private static final long EVENT_FILTER_MESSAGE_DELETED = 1L << 1; @@ -143,31 +130,24 @@ public class BluetoothMapContentObserver { private Context mContext; private ContentResolver mResolver; - @VisibleForTesting - ContentProviderClient mProviderClient = null; + @VisibleForTesting ContentProviderClient mProviderClient = null; private BluetoothMnsObexClient mMnsClient; private BluetoothMapMasInstance mMasInstance = null; private int mMasId; private boolean mEnableSmsMms = false; - @VisibleForTesting - boolean mObserverRegistered = false; - @VisibleForTesting - BluetoothMapAccountItem mAccount; - @VisibleForTesting - String mAuthority = null; + @VisibleForTesting boolean mObserverRegistered = false; + @VisibleForTesting BluetoothMapAccountItem mAccount; + @VisibleForTesting String mAuthority = null; // Default supported feature bit mask is 0x1f private int mMapSupportedFeatures = BluetoothMapUtils.MAP_FEATURE_DEFAULT_BITMASK; // Default event report version is 1.0 - @VisibleForTesting - int mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V10; + @VisibleForTesting int mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V10; private BluetoothMapFolderElement mFolders = new BluetoothMapFolderElement("DUMMY", null); // Will be set by the MAS when generated. - @VisibleForTesting - Uri mMessageUri = null; - @VisibleForTesting - Uri mContactUri = null; + @VisibleForTesting Uri mMessageUri = null; + @VisibleForTesting Uri mContactUri = null; private boolean mTransmitEvents = true; @@ -208,74 +188,81 @@ public class BluetoothMapContentObserver { private boolean mStorageUnlocked = false; private boolean mInitialized = false; + static final String[] SMS_PROJECTION = + new String[] { + Sms._ID, + Sms.THREAD_ID, + Sms.ADDRESS, + Sms.BODY, + Sms.DATE, + Sms.READ, + Sms.TYPE, + Sms.STATUS, + Sms.LOCKED, + Sms.ERROR_CODE + }; - static final String[] SMS_PROJECTION = new String[]{ - Sms._ID, - Sms.THREAD_ID, - Sms.ADDRESS, - Sms.BODY, - Sms.DATE, - Sms.READ, - Sms.TYPE, - Sms.STATUS, - Sms.LOCKED, - Sms.ERROR_CODE - }; - - static final String[] SMS_PROJECTION_SHORT = new String[]{ - Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.READ - }; - - static final String[] SMS_PROJECTION_SHORT_EXT = new String[]{ - Sms._ID, Sms.THREAD_ID, Sms.ADDRESS, Sms.BODY, Sms.DATE, Sms.READ, Sms.TYPE, - }; - - static final String[] MMS_PROJECTION_SHORT = new String[]{ - Mms._ID, Mms.THREAD_ID, Mms.MESSAGE_TYPE, Mms.MESSAGE_BOX, Mms.READ - }; - - static final String[] MMS_PROJECTION_SHORT_EXT = new String[]{ - Mms._ID, - Mms.THREAD_ID, - Mms.MESSAGE_TYPE, - Mms.MESSAGE_BOX, - Mms.READ, - Mms.DATE, - Mms.SUBJECT, - Mms.PRIORITY - }; - - static final String[] MSG_PROJECTION_SHORT = new String[]{ - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ - }; - - static final String[] MSG_PROJECTION_SHORT_EXT = new String[]{ - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY - }; - - static final String[] MSG_PROJECTION_SHORT_EXT2 = new String[]{ - BluetoothMapContract.MessageColumns._ID, - BluetoothMapContract.MessageColumns.FOLDER_ID, - BluetoothMapContract.MessageColumns.FLAG_READ, - BluetoothMapContract.MessageColumns.DATE, - BluetoothMapContract.MessageColumns.SUBJECT, - BluetoothMapContract.MessageColumns.FROM_LIST, - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, - BluetoothMapContract.MessageColumns.THREAD_ID, - BluetoothMapContract.MessageColumns.THREAD_NAME - }; - - public BluetoothMapContentObserver(final Context context, BluetoothMnsObexClient mnsClient, - BluetoothMapMasInstance masInstance, BluetoothMapAccountItem account, - boolean enableSmsMms) throws RemoteException { + static final String[] SMS_PROJECTION_SHORT = + new String[] {Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.READ}; + + static final String[] SMS_PROJECTION_SHORT_EXT = + new String[] { + Sms._ID, Sms.THREAD_ID, Sms.ADDRESS, Sms.BODY, Sms.DATE, Sms.READ, Sms.TYPE, + }; + + static final String[] MMS_PROJECTION_SHORT = + new String[] {Mms._ID, Mms.THREAD_ID, Mms.MESSAGE_TYPE, Mms.MESSAGE_BOX, Mms.READ}; + + static final String[] MMS_PROJECTION_SHORT_EXT = + new String[] { + Mms._ID, + Mms.THREAD_ID, + Mms.MESSAGE_TYPE, + Mms.MESSAGE_BOX, + Mms.READ, + Mms.DATE, + Mms.SUBJECT, + Mms.PRIORITY + }; + + static final String[] MSG_PROJECTION_SHORT = + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ + }; + + static final String[] MSG_PROJECTION_SHORT_EXT = + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY + }; + + static final String[] MSG_PROJECTION_SHORT_EXT2 = + new String[] { + BluetoothMapContract.MessageColumns._ID, + BluetoothMapContract.MessageColumns.FOLDER_ID, + BluetoothMapContract.MessageColumns.FLAG_READ, + BluetoothMapContract.MessageColumns.DATE, + BluetoothMapContract.MessageColumns.SUBJECT, + BluetoothMapContract.MessageColumns.FROM_LIST, + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, + BluetoothMapContract.MessageColumns.THREAD_ID, + BluetoothMapContract.MessageColumns.THREAD_NAME + }; + + public BluetoothMapContentObserver( + final Context context, + BluetoothMnsObexClient mnsClient, + BluetoothMapMasInstance masInstance, + BluetoothMapAccountItem account, + boolean enableSmsMms) + throws RemoteException { mContext = context; mResolver = mContext.getContentResolver(); mAccount = account; @@ -287,8 +274,9 @@ public class BluetoothMapContentObserver { mAuthority = Uri.parse(account.mBase_uri).getAuthority(); mMessageUri = Uri.parse(account.mBase_uri + "/" + BluetoothMapContract.TABLE_MESSAGE); if (mAccount.getType() == TYPE.IM) { - mContactUri = Uri.parse( - account.mBase_uri + "/" + BluetoothMapContract.TABLE_CONVOCONTACT); + mContactUri = + Uri.parse( + account.mBase_uri + "/" + BluetoothMapContract.TABLE_CONVOCONTACT); } // TODO: We need to release this again! mProviderClient = mResolver.acquireUnstableContentProviderClient(mAuthority); @@ -332,14 +320,17 @@ public class BluetoothMapContentObserver { } public int getObserverRemoteFeatureMask() { - Log.v(TAG, "getObserverRemoteFeatureMask : " + mMapEventReportVersion - + " mMapSupportedFeatures: " + mMapSupportedFeatures); + Log.v( + TAG, + "getObserverRemoteFeatureMask : " + + mMapEventReportVersion + + " mMapSupportedFeatures: " + + mMapSupportedFeatures); return mMapSupportedFeatures; } public void setObserverRemoteFeatureMask(int remoteSupportedFeatures) { - mMapSupportedFeatures = - remoteSupportedFeatures & BluetoothMapMasInstance.getFeatureMask(); + mMapSupportedFeatures = remoteSupportedFeatures & BluetoothMapMasInstance.getFeatureMask(); if ((BluetoothMapUtils.MAP_FEATURE_EXTENDED_EVENT_REPORT_11_BIT & mMapSupportedFeatures) != 0) { mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; @@ -348,8 +339,9 @@ public class BluetoothMapContentObserver { if ((BluetoothMapUtils.MAP_FEATURE_EVENT_REPORT_V12_BIT & mMapSupportedFeatures) != 0) { mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; } else if (((BluetoothMapUtils.MAP_FEATURE_PARTICIPANT_PRESENCE_CHANGE_BIT - | BluetoothMapUtils.MAP_FEATURE_PARTICIPANT_CHAT_STATE_CHANGE_BIT) - & mMapSupportedFeatures) != 0) { + | BluetoothMapUtils.MAP_FEATURE_PARTICIPANT_CHAT_STATE_CHANGE_BIT) + & mMapSupportedFeatures) + != 0) { // Warning according to page 46/123 of MAP 1.3 spec Log.w( TAG, @@ -363,9 +355,12 @@ public class BluetoothMapContentObserver { BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 0); } - Log.d(TAG, - "setObserverRemoteFeatureMask: mMapEventReportVersion=" + mMapEventReportVersion - + " mMapSupportedFeatures=" + mMapSupportedFeatures); + Log.d( + TAG, + "setObserverRemoteFeatureMask: mMapEventReportVersion=" + + mMapEventReportVersion + + " mMapSupportedFeatures=" + + mMapSupportedFeatures); } @VisibleForTesting @@ -415,15 +410,14 @@ public class BluetoothMapContentObserver { return mContactList; } - /** * Currently we only have data for IM / email contacts * * @param changesDetected that is not chat state changed nor presence state changed. */ @VisibleForTesting - void setContactList(Map contactList, - boolean changesDetected) { + void setContactList( + Map contactList, boolean changesDetected) { mContactList = contactList; if (changesDetected) { mMasInstance.updateImEmailConvoListVersionCounter(); @@ -560,7 +554,6 @@ public class BluetoothMapContentObserver { return "Unknown"; } - private static final HashMap FOLDER_MMS_MAP; static { @@ -585,10 +578,7 @@ public class BluetoothMapContentObserver { return "Unknown"; } - /** - * Set the folder structure to be used for this instance. - * - */ + /** Set the folder structure to be used for this instance. */ void setFolderStructure(BluetoothMapFolderElement folderStructure) { this.mFolders = folderStructure; } @@ -704,8 +694,15 @@ public class BluetoothMapContentObserver { } /* extended event type 1.1 */ - Event(String eventType, long handle, String folder, TYPE msgType, String datetime, - String subject, String senderName, String priority) { + Event( + String eventType, + long handle, + String folder, + TYPE msgType, + String datetime, + String subject, + String senderName, + String priority) { this.eventType = eventType; this.handle = handle; setFolderPath(folder, msgType); @@ -721,8 +718,16 @@ public class BluetoothMapContentObserver { } /* extended event type 1.2 message events */ - Event(String eventType, long handle, String folder, TYPE msgType, String datetime, - String subject, String senderName, String priority, long conversationID, + Event( + String eventType, + long handle, + String folder, + TYPE msgType, + String datetime, + String subject, + String senderName, + String priority, + long conversationID, String conversationName) { this.eventType = eventType; this.handle = handle; @@ -745,9 +750,18 @@ public class BluetoothMapContentObserver { } /* extended event type 1.2 for conversation, presence or chat state changed events */ - Event(String eventType, String uci, TYPE msgType, String name, String priority, - String lastActivity, long conversationID, String conversationName, - int presenceState, String presenceStatus, int chatState) { + Event( + String eventType, + String uci, + TYPE msgType, + String name, + String priority, + String lastActivity, + long conversationID, + String conversationName, + int presenceState, + String presenceStatus, + int chatState) { this.eventType = eventType; this.uci = uci; this.msgType = msgType; @@ -791,12 +805,13 @@ public class BluetoothMapContentObserver { } xmlEvtReport.startTag("", "event"); xmlEvtReport.attribute("", "type", eventType); - if (eventType.equals(EVENT_TYPE_CONVERSATION) || eventType.equals( - EVENT_TYPE_PRESENCE) || eventType.equals(EVENT_TYPE_CHAT_STATE)) { + if (eventType.equals(EVENT_TYPE_CONVERSATION) + || eventType.equals(EVENT_TYPE_PRESENCE) + || eventType.equals(EVENT_TYPE_CHAT_STATE)) { xmlEvtReport.attribute("", "participant_uci", uci); } else { - xmlEvtReport.attribute("", "handle", - BluetoothMapUtils.getMapHandle(handle, msgType)); + xmlEvtReport.attribute( + "", "handle", BluetoothMapUtils.getMapHandle(handle, msgType)); } if (folder != null) { @@ -817,11 +832,15 @@ public class BluetoothMapContentObserver { xmlEvtReport.attribute("", "datetime", datetime); } if (subject != null) { - xmlEvtReport.attribute("", "subject", + xmlEvtReport.attribute( + "", + "subject", subject.substring(0, subject.length() < 256 ? subject.length() : 256)); } if (senderName != null) { - xmlEvtReport.attribute("", "sender_name", + xmlEvtReport.attribute( + "", + "sender_name", senderName.substring( 0, senderName.length() < 256 ? senderName.length() : 255)); } @@ -829,7 +848,7 @@ public class BluetoothMapContentObserver { xmlEvtReport.attribute("", "priority", priority); } - //} + // } /* Include conversation information from event version 1.2 */ if (mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V11) { if (conversationName != null) { @@ -837,14 +856,16 @@ public class BluetoothMapContentObserver { } if (conversationID != -1) { // Convert provider conversation handle to string incl type - xmlEvtReport.attribute("", "conversation_id", + xmlEvtReport.attribute( + "", + "conversation_id", BluetoothMapUtils.getMapConvoHandle(conversationID, msgType)); } if (eventType.equals(EVENT_TYPE_PRESENCE)) { if (presenceState != 0) { // Convert provider conversation handle to string incl type - xmlEvtReport.attribute("", "presence_availability", - String.valueOf(presenceState)); + xmlEvtReport.attribute( + "", "presence_availability", String.valueOf(presenceState)); } if (presenceStatus != null) { // Convert provider conversation handle to string incl type @@ -864,7 +885,6 @@ public class BluetoothMapContentObserver { xmlEvtReport.attribute("", "chat_state", String.valueOf(chatState)); } } - } xmlEvtReport.endTag("", "event"); xmlEvtReport.endTag("", "MAP-event-report"); @@ -900,14 +920,14 @@ public class BluetoothMapContentObserver { static class Msg { public long id; - public int type; // Used as folder for SMS/MMS - public int threadId; // Used for SMS/MMS at delete - public long folderId = -1; // Email folder ID - public long oldFolderId = -1; // Used for email undelete + public int type; // Used as folder for SMS/MMS + public int threadId; // Used for SMS/MMS at delete + public long folderId = -1; // Email folder ID + public long oldFolderId = -1; // Used for email undelete public boolean localInitiatedSend = false; // Used for MMS to filter out events public boolean transparent = false; // Used for EMAIL to delete message sent with transparency - public int flagRead = -1; // Message status read/unread + public int flagRead = -1; // Message status read/unread Msg(long id, int type, int threadId, int readFlag) { this.id = id; @@ -973,7 +993,7 @@ public class BluetoothMapContentObserver { if (mMnsClient.isValidMnsRecord()) { msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION; } else { - //Trigger SDP Search and notificaiton registration , if SDP record not found. + // Trigger SDP Search and notificaiton registration , if SDP record not found. msg.what = BluetoothMnsObexClient.MSG_MNS_SDP_SEARCH_REGISTRATION; if (mMnsClient.mMnsLstRegRqst != null && (mMnsClient.mMnsLstRegRqst.isSearchInProgress())) { @@ -1065,15 +1085,18 @@ public class BluetoothMapContentObserver { /* Use MmsSms Uri since the Sms Uri is not notified on deletes */ if (mEnableSmsMms) { - //this is sms/mms + // this is sms/mms mResolver.registerContentObserver(MmsSms.CONTENT_URI, false, mObserver); mObserverRegistered = true; } if (mAccount != null) { /* For URI's without account ID */ - Uri uri = Uri.parse( - mAccount.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_MESSAGE); + Uri uri = + Uri.parse( + mAccount.mBase_uri_no_account + + "/" + + BluetoothMapContract.TABLE_MESSAGE); Log.d(TAG, "Registering observer for: " + uri); mResolver.registerContentObserver(uri, true, mObserver); @@ -1085,8 +1108,11 @@ public class BluetoothMapContentObserver { if (mAccount.getType() == TYPE.IM) { - uri = Uri.parse(mAccount.mBase_uri_no_account + "/" - + BluetoothMapContract.TABLE_CONVOCONTACT); + uri = + Uri.parse( + mAccount.mBase_uri_no_account + + "/" + + BluetoothMapContract.TABLE_CONVOCONTACT); Log.d(TAG, "Registering observer for: " + uri); mResolver.registerContentObserver(uri, true, mObserver); @@ -1121,10 +1147,10 @@ public class BluetoothMapContentObserver { return; } /* We need to perform the same functionality, as when we receive a notification change, - hence we: - - disable the event transmission - - triggers the code for updates - - enable the event transmission */ + hence we: + - disable the event transmission + - triggers the code for updates + - enable the event transmission */ mTransmitEvents = false; try { if (mEnableSmsMms) { @@ -1141,8 +1167,11 @@ public class BluetoothMapContentObserver { BluetoothStatsLog .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 7); - Log.e(TAG, "Unable to update FolderVersionCounter. - Not fatal, but can cause" - + " undesirable user experience!", e); + Log.e( + TAG, + "Unable to update FolderVersionCounter. - Not fatal, but can cause" + + " undesirable user experience!", + e); } } } finally { @@ -1180,9 +1209,26 @@ public class BluetoothMapContentObserver { return; } - Log.d(TAG, "sendEvent: " + evt.eventType + " " + evt.handle + " " + evt.folder + " " - + evt.oldFolder + " " + evt.msgType + " " + evt.datetime + " " - + evt.subject + " " + evt.senderName + " " + evt.priority); + Log.d( + TAG, + "sendEvent: " + + evt.eventType + + " " + + evt.handle + + " " + + evt.folder + + " " + + evt.oldFolder + + " " + + evt.msgType + + " " + + evt.datetime + + " " + + evt.subject + + " " + + evt.senderName + + " " + + evt.priority); if (mMnsClient == null || !mMnsClient.isConnected()) { Log.d(TAG, "sendEvent: No MNS client registered or connected- don't send event"); @@ -1283,8 +1329,15 @@ public class BluetoothMapContentObserver { Cursor c; try { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Sms.CONTENT_URI, SMS_PROJECTION_SHORT, null, null, null); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Sms.CONTENT_URI, + SMS_PROJECTION_SHORT, + null, + null, + null); } catch (SQLiteException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -1320,8 +1373,15 @@ public class BluetoothMapContentObserver { HashMap msgListMms = new HashMap(); - c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, Mms.CONTENT_URI, - MMS_PROJECTION_SHORT, null, null, null); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Mms.CONTENT_URI, + MMS_PROJECTION_SHORT, + null, + null, + null); try { if (c != null && c.moveToFirst()) { do { @@ -1355,10 +1415,14 @@ public class BluetoothMapContentObserver { if (c != null && c.moveToFirst()) { do { long id = c.getLong(c.getColumnIndex(MessageColumns._ID)); - long folderId = c.getInt( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID)); - int readFlag = c.getInt( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_READ)); + long folderId = + c.getInt( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FOLDER_ID)); + int readFlag = + c.getInt( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FLAG_READ)); Msg msg = new Msg(id, folderId, readFlag); msgList.put(id, msg); } while (c.moveToNext()); @@ -1384,8 +1448,13 @@ public class BluetoothMapContentObserver { return; } Uri uri = mContactUri; - Cursor c = mProviderClient.query(uri, - BluetoothMapContract.BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, null, null, null); + Cursor c = + mProviderClient.query( + uri, + BluetoothMapContract.BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, + null, + null, + null); Map contactList = new HashMap(); try { @@ -1408,9 +1477,16 @@ public class BluetoothMapContentObserver { int priority = c.getInt(cInfo.mContactColPriority); String btUid = c.getString(cInfo.mContactColBtUid); BluetoothMapConvoContactElement contact = - new BluetoothMapConvoContactElement(uci, name, displayName, - presenceStatus, presenceState, lastActivity, chatState, - priority, btUid); + new BluetoothMapConvoContactElement( + uci, + name, + displayName, + presenceStatus, + presenceState, + lastActivity, + chatState, + priority, + btUid); contactList.put(uci, contact); } while (c.moveToNext()); } @@ -1435,11 +1511,25 @@ public class BluetoothMapContentObserver { Cursor c; synchronized (getMsgListSms()) { if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Sms.CONTENT_URI, SMS_PROJECTION_SHORT, null, null, null); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Sms.CONTENT_URI, + SMS_PROJECTION_SHORT, + null, + null, + null); } else { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Sms.CONTENT_URI, SMS_PROJECTION_SHORT_EXT, null, null, null); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Sms.CONTENT_URI, + SMS_PROJECTION_SHORT_EXT, + null, + null, + null); } try { if (c != null && c.moveToFirst()) { @@ -1470,7 +1560,8 @@ public class BluetoothMapContentObserver { msg = new Msg(id, type, threadId, read); msgListSms.put(id, msg); Event evt; - if (mTransmitEvents && // extract contact details only if needed + if (mTransmitEvents + && // extract contact details only if needed mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V10) { long timestamp = c.getLong(c.getColumnIndex(Sms.DATE)); @@ -1494,11 +1585,12 @@ public class BluetoothMapContentObserver { } String name = ""; String phone = ""; - if (type == 1) { //inbox + if (type == 1) { // inbox phone = c.getString(c.getColumnIndex(Sms.ADDRESS)); if (phone != null && !phone.isEmpty()) { - name = BluetoothMapContent.getContactNameFromPhone(phone, - mResolver); + name = + BluetoothMapContent.getContactNameFromPhone( + phone, mResolver); if (name == null || name.isEmpty()) { name = phone; } @@ -1506,8 +1598,8 @@ public class BluetoothMapContentObserver { name = phone; } } else { - TelephonyManager tm = mContext.getSystemService( - TelephonyManager.class); + TelephonyManager tm = + mContext.getSystemService(TelephonyManager.class); if (tm != null) { phone = tm.getLine1Number(); name = phone; @@ -1517,17 +1609,39 @@ public class BluetoothMapContentObserver { /* Incoming message from the network */ if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) { - evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), - mSmsType, date, subject, name, priority); + evt = + new Event( + EVENT_TYPE_NEW, + id, + getSmsFolderName(type), + mSmsType, + date, + subject, + name, + priority); } else { - evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), - mSmsType, date, subject, name, priority, - (long) threadId, null); + evt = + new Event( + EVENT_TYPE_NEW, + id, + getSmsFolderName(type), + mSmsType, + date, + subject, + name, + priority, + (long) threadId, + null); } } else { /* Incoming message from the network */ - evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), null, - mSmsType); + evt = + new Event( + EVENT_TYPE_NEW, + id, + getSmsFolderName(type), + null, + mSmsType); } listChanged = true; sendEvent(evt); @@ -1541,30 +1655,50 @@ public class BluetoothMapContentObserver { // Filter out the intermediate outbox steps if (!oldFolder.equalsIgnoreCase(newFolder)) { Event evt = - new Event(EVENT_TYPE_SHIFT, id, getSmsFolderName(type), - oldFolder, mSmsType); + new Event( + EVENT_TYPE_SHIFT, + id, + getSmsFolderName(type), + oldFolder, + mSmsType); sendEvent(evt); } msg.type = type; } else if (threadId != msg.threadId) { listChanged = true; - Log.d(TAG, "Message delete change: type: " + type + " old type: " - + msg.type + "\n threadId: " + threadId - + " old threadId: " + msg.threadId); + Log.d( + TAG, + "Message delete change: type: " + + type + + " old type: " + + msg.type + + "\n threadId: " + + threadId + + " old threadId: " + + msg.threadId); if (threadId == DELETED_THREAD_ID) { // Message deleted // TODO: // We shall only use the folder attribute, but can't remember // wether to set it to "deleted" or the name of the folder // from which the message have been deleted. // "old_folder" used only for MessageShift event - Event evt = new Event(EVENT_TYPE_DELETE, id, - getSmsFolderName(msg.type), null, mSmsType); + Event evt = + new Event( + EVENT_TYPE_DELETE, + id, + getSmsFolderName(msg.type), + null, + mSmsType); sendEvent(evt); msg.threadId = threadId; } else { // Undelete - Event evt = new Event(EVENT_TYPE_SHIFT, id, - getSmsFolderName(msg.type), - BluetoothMapContract.FOLDER_NAME_DELETED, mSmsType); + Event evt = + new Event( + EVENT_TYPE_SHIFT, + id, + getSmsFolderName(msg.type), + BluetoothMapContract.FOLDER_NAME_DELETED, + mSmsType); sendEvent(evt); msg.threadId = threadId; } @@ -1574,8 +1708,12 @@ public class BluetoothMapContentObserver { msg.flagRead = read; if (mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V10) { - Event evt = new Event(EVENT_TYPE_READ_STATUS, id, - getSmsFolderName(msg.type), mSmsType); + Event evt = + new Event( + EVENT_TYPE_READ_STATUS, + id, + getSmsFolderName(msg.type), + mSmsType); sendEvent(evt); } } @@ -1595,8 +1733,8 @@ public class BluetoothMapContentObserver { eventType = EVENT_TYPE_REMOVED; Log.v(TAG, " sent EVENT_TYPE_REMOVED"); } - Event evt = new Event(eventType, msg.id, getSmsFolderName(msg.type), null, - mSmsType); + Event evt = + new Event(eventType, msg.id, getSmsFolderName(msg.type), null, mSmsType); sendEvent(evt); listChanged = true; } @@ -1614,11 +1752,25 @@ public class BluetoothMapContentObserver { Cursor c; synchronized (getMsgListMms()) { if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Mms.CONTENT_URI, MMS_PROJECTION_SHORT, null, null, null); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Mms.CONTENT_URI, + MMS_PROJECTION_SHORT, + null, + null, + null); } else { - c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - Mms.CONTENT_URI, MMS_PROJECTION_SHORT_EXT, null, null, null); + c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + Mms.CONTENT_URI, + MMS_PROJECTION_SHORT_EXT, + null, + null, + null); } try { @@ -1651,21 +1803,23 @@ public class BluetoothMapContentObserver { if (msg == null) { /* New message - only notify on retrieve conf */ - if (getMmsFolderName(type).equalsIgnoreCase( - BluetoothMapContract.FOLDER_NAME_INBOX) + if (getMmsFolderName(type) + .equalsIgnoreCase( + BluetoothMapContract.FOLDER_NAME_INBOX) && mtype != MESSAGE_TYPE_RETRIEVE_CONF) { continue; } msg = new Msg(id, type, threadId, read); msgListMms.put(id, msg); Event evt; - if (mTransmitEvents && // extract contact details only if needed + if (mTransmitEvents + && // extract contact details only if needed mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10) { // MMS date field is in seconds long timestamp = TimeUnit.SECONDS.toMillis( - c.getLong(c.getColumnIndex(Mms.DATE))); + c.getLong(c.getColumnIndex(Mms.DATE))); String date = BluetoothMapUtils.getDateTimeString(timestamp); if (Flags.mapLimitNotification()) { if (BluetoothMapUtils.isDateTimeOlderThanDuration( @@ -1690,12 +1844,17 @@ public class BluetoothMapContentObserver { } } int tmpPri = c.getInt(c.getColumnIndex(Mms.PRIORITY)); - Log.d(TAG, "TEMP handleMsgListChangesMms, " - + "newMessage 'read' state: " + read + "priority: " - + tmpPri); - - String address = BluetoothMapContent.getAddressMms(mResolver, id, - BluetoothMapContent.MMS_FROM); + Log.d( + TAG, + "TEMP handleMsgListChangesMms, " + + "newMessage 'read' state: " + + read + + "priority: " + + tmpPri); + + String address = + BluetoothMapContent.getAddressMms( + mResolver, id, BluetoothMapContent.MMS_FROM); if (address == null) { address = ""; } @@ -1708,18 +1867,40 @@ public class BluetoothMapContentObserver { /* Incoming message from the network */ if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) { - evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), - TYPE.MMS, date, subject, address, priority); + evt = + new Event( + EVENT_TYPE_NEW, + id, + getMmsFolderName(type), + TYPE.MMS, + date, + subject, + address, + priority); } else { - evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), - TYPE.MMS, date, subject, address, priority, - (long) threadId, null); + evt = + new Event( + EVENT_TYPE_NEW, + id, + getMmsFolderName(type), + TYPE.MMS, + date, + subject, + address, + priority, + (long) threadId, + null); } } else { /* Incoming message from the network */ - evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), null, - TYPE.MMS); + evt = + new Event( + EVENT_TYPE_NEW, + id, + getMmsFolderName(type), + null, + TYPE.MMS); } listChanged = true; @@ -1732,36 +1913,63 @@ public class BluetoothMapContentObserver { listChanged = true; if (!msg.localInitiatedSend) { // Only send events about local initiated changes - evt = new Event(EVENT_TYPE_SHIFT, id, getMmsFolderName(type), - getMmsFolderName(msg.type), TYPE.MMS); + evt = + new Event( + EVENT_TYPE_SHIFT, + id, + getMmsFolderName(type), + getMmsFolderName(msg.type), + TYPE.MMS); sendEvent(evt); } msg.type = type; - if (getMmsFolderName(type).equalsIgnoreCase( - BluetoothMapContract.FOLDER_NAME_SENT) + if (getMmsFolderName(type) + .equalsIgnoreCase( + BluetoothMapContract.FOLDER_NAME_SENT) && msg.localInitiatedSend) { // Stop tracking changes for this message msg.localInitiatedSend = false; - evt = new Event(EVENT_TYPE_SENDING_SUCCESS, id, - getMmsFolderName(type), null, TYPE.MMS); + evt = + new Event( + EVENT_TYPE_SENDING_SUCCESS, + id, + getMmsFolderName(type), + null, + TYPE.MMS); sendEvent(evt); } } else if (threadId != msg.threadId) { - Log.d(TAG, "Message delete change: type: " + type + " old type: " - + msg.type + "\n threadId: " + threadId - + " old threadId: " + msg.threadId); + Log.d( + TAG, + "Message delete change: type: " + + type + + " old type: " + + msg.type + + "\n threadId: " + + threadId + + " old threadId: " + + msg.threadId); listChanged = true; if (threadId == DELETED_THREAD_ID) { // Message deleted // "old_folder" used only for MessageShift event - Event evt = new Event(EVENT_TYPE_DELETE, id, - getMmsFolderName(msg.type), null, TYPE.MMS); + Event evt = + new Event( + EVENT_TYPE_DELETE, + id, + getMmsFolderName(msg.type), + null, + TYPE.MMS); sendEvent(evt); msg.threadId = threadId; } else { // Undelete - Event evt = new Event(EVENT_TYPE_SHIFT, id, - getMmsFolderName(msg.type), - BluetoothMapContract.FOLDER_NAME_DELETED, TYPE.MMS); + Event evt = + new Event( + EVENT_TYPE_SHIFT, + id, + getMmsFolderName(msg.type), + BluetoothMapContract.FOLDER_NAME_DELETED, + TYPE.MMS); sendEvent(evt); msg.threadId = threadId; } @@ -1771,15 +1979,18 @@ public class BluetoothMapContentObserver { msg.flagRead = read; if (mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V10) { - Event evt = new Event(EVENT_TYPE_READ_STATUS, id, - getMmsFolderName(msg.type), TYPE.MMS); + Event evt = + new Event( + EVENT_TYPE_READ_STATUS, + id, + getMmsFolderName(msg.type), + TYPE.MMS); sendEvent(evt); } } msgListMms.put(id, msg); } } while (c.moveToNext()); - } } finally { if (c != null) { @@ -1788,8 +1999,13 @@ public class BluetoothMapContentObserver { } for (Msg msg : getMsgListMms().values()) { // "old_folder" used only for MessageShift event - Event evt = new Event(EVENT_TYPE_DELETE, msg.id, getMmsFolderName(msg.type), null, - TYPE.MMS); + Event evt = + new Event( + EVENT_TYPE_DELETE, + msg.id, + getMmsFolderName(msg.type), + null, + TYPE.MMS); sendEvent(evt); listChanged = true; } @@ -1817,12 +2033,17 @@ public class BluetoothMapContentObserver { try { if (c != null && c.moveToFirst()) { do { - long id = c.getLong( - c.getColumnIndex(BluetoothMapContract.MessageColumns._ID)); - int folderId = c.getInt( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID)); - int readFlag = c.getInt( - c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_READ)); + long id = + c.getLong( + c.getColumnIndex(BluetoothMapContract.MessageColumns._ID)); + int folderId = + c.getInt( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FOLDER_ID)); + int readFlag = + c.getInt( + c.getColumnIndex( + BluetoothMapContract.MessageColumns.FLAG_READ)); Msg msg = getMsgListMsg().remove(id); BluetoothMapFolderElement folderElement = mFolders.getFolderById(folderId); String newFolder; @@ -1842,31 +2063,65 @@ public class BluetoothMapContentObserver { Event evt; /* Incoming message from the network */ if (mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10) { - String date = BluetoothMapUtils.getDateTimeString(c.getLong( - c.getColumnIndex( - BluetoothMapContract.MessageColumns.DATE))); - String subject = c.getString(c.getColumnIndex( - BluetoothMapContract.MessageColumns.SUBJECT)); - String address = c.getString(c.getColumnIndex( - BluetoothMapContract.MessageColumns.FROM_LIST)); + String date = + BluetoothMapUtils.getDateTimeString( + c.getLong( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .DATE))); + String subject = + c.getString( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .SUBJECT)); + String address = + c.getString( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .FROM_LIST)); String priority = "no"; - if (c.getInt(c.getColumnIndex( - BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY)) + if (c.getInt( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .FLAG_HIGH_PRIORITY)) == 1) { priority = "yes"; } if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) { - evt = new Event(EVENT_TYPE_NEW, id, newFolder, - mAccount.getType(), date, subject, address, priority); + evt = + new Event( + EVENT_TYPE_NEW, + id, + newFolder, + mAccount.getType(), + date, + subject, + address, + priority); } else { - long threadId = c.getLong(c.getColumnIndex( - BluetoothMapContract.MessageColumns.THREAD_ID)); - String threadName = c.getString(c.getColumnIndex( - BluetoothMapContract.MessageColumns.THREAD_NAME)); - evt = new Event(EVENT_TYPE_NEW, id, newFolder, - mAccount.getType(), date, subject, address, priority, - threadId, threadName); + long threadId = + c.getLong( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .THREAD_ID)); + String threadName = + c.getString( + c.getColumnIndex( + BluetoothMapContract.MessageColumns + .THREAD_NAME)); + evt = + new Event( + EVENT_TYPE_NEW, + id, + newFolder, + mAccount.getType(), + date, + subject, + address, + priority, + threadId, + threadName); } } else { evt = new Event(EVENT_TYPE_NEW, id, newFolder, null, TYPE.EMAIL); @@ -1875,8 +2130,12 @@ public class BluetoothMapContentObserver { } else { /* Existing message */ if (folderId != msg.folderId && msg.folderId != -1) { - Log.d(TAG, "new folderId: " + folderId + " old folderId: " - + msg.folderId); + Log.d( + TAG, + "new folderId: " + + folderId + + " old folderId: " + + msg.folderId); BluetoothMapFolderElement oldFolderElement = mFolders.getFolderById(msg.folderId); String oldFolder; @@ -1887,10 +2146,12 @@ public class BluetoothMapContentObserver { // This can happen if a new folder is created while connected oldFolder = "unknown"; } - BluetoothMapFolderElement deletedFolder = mFolders.getFolderByName( - BluetoothMapContract.FOLDER_NAME_DELETED); - BluetoothMapFolderElement sentFolder = mFolders.getFolderByName( - BluetoothMapContract.FOLDER_NAME_SENT); + BluetoothMapFolderElement deletedFolder = + mFolders.getFolderByName( + BluetoothMapContract.FOLDER_NAME_DELETED); + BluetoothMapFolderElement sentFolder = + mFolders.getFolderByName( + BluetoothMapContract.FOLDER_NAME_SENT); /* * If the folder is now 'deleted', send a deleted-event in stead of * a shift or if message is sent initiated by MAP Client, then send @@ -1900,27 +2161,43 @@ public class BluetoothMapContentObserver { && deletedFolder.getFolderId() == folderId) { // "old_folder" used only for MessageShift event Event evt = - new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null, + new Event( + EVENT_TYPE_DELETE, + msg.id, + oldFolder, + null, mAccount.getType()); sendEvent(evt); } else if (sentFolder != null && sentFolder.getFolderId() == folderId && msg.localInitiatedSend) { if (msg.transparent) { - BluetoothMethodProxy.getInstance().contentResolverDelete( - mResolver, - ContentUris.withAppendedId(mMessageUri, id), null, - null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + mResolver, + ContentUris.withAppendedId(mMessageUri, id), + null, + null); } else { msg.localInitiatedSend = false; - Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msg.id, - oldFolder, null, mAccount.getType()); + Event evt = + new Event( + EVENT_TYPE_SENDING_SUCCESS, + msg.id, + oldFolder, + null, + mAccount.getType()); sendEvent(evt); } } else { if (!oldFolder.equalsIgnoreCase("root")) { - Event evt = new Event(EVENT_TYPE_SHIFT, id, newFolder, - oldFolder, mAccount.getType()); + Event evt = + new Event( + EVENT_TYPE_SHIFT, + id, + newFolder, + oldFolder, + mAccount.getType()); sendEvent(evt); } } @@ -1931,8 +2208,12 @@ public class BluetoothMapContentObserver { if (mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V10) { - Event evt = new Event(EVENT_TYPE_READ_STATUS, id, newFolder, - mAccount.getType()); + Event evt = + new Event( + EVENT_TYPE_READ_STATUS, + id, + newFolder, + mAccount.getType()); sendEvent(evt); msg.flagRead = readFlag; } @@ -1967,8 +2248,13 @@ public class BluetoothMapContentObserver { if (msg.transparent) { oldFolder = null; } - Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msg.id, oldFolder, null, - mAccount.getType()); + Event evt = + new Event( + EVENT_TYPE_SENDING_SUCCESS, + msg.id, + oldFolder, + null, + mAccount.getType()); sendEvent(evt); } /* As this message deleted is only send on a real delete - don't set folder. @@ -1977,8 +2263,9 @@ public class BluetoothMapContentObserver { if (!msg.transparent) { // "old_folder" used only for MessageShift event - Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null, - mAccount.getType()); + Event evt = + new Event( + EVENT_TYPE_DELETE, msg.id, oldFolder, null, mAccount.getType()); sendEvent(evt); } } @@ -1989,8 +2276,7 @@ public class BluetoothMapContentObserver { private void handleMsgListChanges(Uri uri) { if (uri.getAuthority().equals(mAuthority)) { try { - Log.d(TAG, "handleMsgListChanges: account type = " + mAccount.getType() - .toString()); + Log.d(TAG, "handleMsgListChanges: account type = " + mAccount.getType().toString()); handleMsgListChangesMsg(uri); } catch (RemoteException e) { ContentProfileErrorReportUtils.report( @@ -1999,10 +2285,12 @@ public class BluetoothMapContentObserver { BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 12); mMasInstance.restartObexServerSession(); - Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " + mMasId - + " restaring ObexServerSession"); + Log.w( + TAG, + "Problems contacting the ContentProvider in mas Instance " + + mMasId + + " restaring ObexServerSession"); } - } // TODO: check to see if there could be problem with IM and SMS in one instance if (mEnableSmsMms) { @@ -2023,13 +2311,20 @@ public class BluetoothMapContentObserver { if (mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10 && mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V11) { - c = mProviderClient.query(mContactUri, - BluetoothMapContract.BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, - null, null, null); + c = + mProviderClient.query( + mContactUri, + BluetoothMapContract + .BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, + null, + null, + null); cInfo.setConvoColunms(c); } else { - Log.v(TAG, "handleContactListChanges MAP version does not" - + "support convocontact notifications"); + Log.v( + TAG, + "handleContactListChanges MAP version does not" + + "support convocontact notifications"); return; } @@ -2064,9 +2359,9 @@ public class BluetoothMapContentObserver { * tracked here */ if (mMapEventReportVersion - != BluetoothMapUtils.MAP_EVENT_REPORT_V10 + != BluetoothMapUtils.MAP_EVENT_REPORT_V10 && mMapEventReportVersion - != BluetoothMapUtils.MAP_EVENT_REPORT_V11) { + != BluetoothMapUtils.MAP_EVENT_REPORT_V11) { Event evt; String name = c.getString(cInfo.mContactColName); String displayName = c.getString(cInfo.mContactColNickname); @@ -2081,67 +2376,107 @@ public class BluetoothMapContentObserver { // Get Conversation information for // event -// Uri convoUri = Uri -// .parse(mAccount.mBase_uri -// + "/" -// + BluetoothMapContract -// .TABLE_CONVERSATION); -// String whereClause = "contacts._id = " -// + convoId; -// Cursor cConvo = mProviderClient -// .query(convoUri, -// BluetoothMapContract -// .BT_CONVERSATION_PROJECTION, -// whereClause, null, null); + // Uri convoUri = Uri + // + // .parse(mAccount.mBase_uri + // + + // "/" + // + + // BluetoothMapContract + // .TABLE_CONVERSATION); + // String whereClause + // = "contacts._id = " + // + convoId; + // Cursor cConvo = + // mProviderClient + // + // .query(convoUri, + // + // BluetoothMapContract + // .BT_CONVERSATION_PROJECTION, + // + // whereClause, null, null); // TODO: will move out of the loop when merged with CB's // changes make sure to look up col index out side loop String convoName = null; -// if (cConvo != null -// && cConvo.moveToFirst()) { -// convoName = cConvo -// .getString(cConvo -// .getColumnIndex -// (BluetoothMapContract.ConvoContactColumns.NAME)); -// } - - contact = new BluetoothMapConvoContactElement(uci, name, - displayName, presenceStatus, presenceState, - lastActivity, chatState, priority, btUid); + // if (cConvo != null + // && + // cConvo.moveToFirst()) { + // convoName = + // cConvo + // + // .getString(cConvo + // + // .getColumnIndex + // (BluetoothMapContract.ConvoContactColumns.NAME)); + // } + + contact = + new BluetoothMapConvoContactElement( + uci, + name, + displayName, + presenceStatus, + presenceState, + lastActivity, + chatState, + priority, + btUid); contactList.put(uci, contact); - evt = new Event(EVENT_TYPE_CONVERSATION, uci, - mAccount.getType(), name, String.valueOf(priority), - BluetoothMapUtils.getDateTimeString(lastActivity), - convoId, convoName, presenceState, presenceStatus, - chatState); + evt = + new Event( + EVENT_TYPE_CONVERSATION, + uci, + mAccount.getType(), + name, + String.valueOf(priority), + BluetoothMapUtils.getDateTimeString( + lastActivity), + convoId, + convoName, + presenceState, + presenceStatus, + chatState); sendEvent(evt); } } else { // Not new - compare updated content -// Uri convoUri = Uri -// .parse(mAccount.mBase_uri -// + "/" -// + BluetoothMapContract.TABLE_CONVERSATION); + // Uri convoUri = Uri + // + // .parse(mAccount.mBase_uri + // + "/" + // + + // BluetoothMapContract.TABLE_CONVERSATION); // TODO: Should be changed to own provider interface name -// String whereClause = "contacts._id = " -// + convoId; -// Cursor cConvo = mProviderClient -// .query(convoUri, -// BluetoothMapContract -// .BT_CONVERSATION_PROJECTION, -// whereClause, null, null); -// // TODO: will move out of the loop when merged with CB's -// // changes make sure to look up col index out side loop + // String whereClause = + // "contacts._id = " + // + convoId; + // Cursor cConvo = + // mProviderClient + // .query(convoUri, + // + // BluetoothMapContract + // .BT_CONVERSATION_PROJECTION, + // + // whereClause, null, null); + // // TODO: will move out of + // the loop when merged with CB's + // // changes make sure to + // look up col index out side loop String convoName = null; -// if (cConvo != null && cConvo.moveToFirst()) { -// convoName = cConvo -// .getString(cConvo -// .getColumnIndex(BluetoothMapContract -// .ConvoContactColumns.NAME)); -// } + // if (cConvo != null && + // cConvo.moveToFirst()) { + // convoName = cConvo + // + // .getString(cConvo + // + // .getColumnIndex(BluetoothMapContract + // .ConvoContactColumns.NAME)); + // } // Check if presence is updated int presenceState = c.getInt(cInfo.mContactColPresenceState); @@ -2149,8 +2484,8 @@ public class BluetoothMapContentObserver { c.getString(cInfo.mContactColPresenceText); String currentPresenceStatus = contact.getPresenceStatus(); if (contact.getPresenceAvailability() != presenceState - || !Objects.equals(currentPresenceStatus, - presenceStatus)) { + || !Objects.equals( + currentPresenceStatus, presenceStatus)) { long lastOnline = c.getLong(cInfo.mContactColLastOnline); contact.setPresenceAvailability(presenceState); contact.setLastActivity(lastOnline); @@ -2158,12 +2493,20 @@ public class BluetoothMapContentObserver { && !currentPresenceStatus.equals(presenceStatus)) { contact.setPresenceStatus(presenceStatus); } - Event evt = new Event(EVENT_TYPE_PRESENCE, uci, - mAccount.getType(), contact.getName(), - String.valueOf(contact.getPriority()), - BluetoothMapUtils.getDateTimeString(lastOnline), - convoId, convoName, presenceState, presenceStatus, - 0); + Event evt = + new Event( + EVENT_TYPE_PRESENCE, + uci, + mAccount.getType(), + contact.getName(), + String.valueOf(contact.getPriority()), + BluetoothMapUtils.getDateTimeString( + lastOnline), + convoId, + convoName, + presenceState, + presenceStatus, + 0); sendEvent(evt); } @@ -2174,11 +2517,20 @@ public class BluetoothMapContentObserver { long lastActivity = c.getLong(cInfo.mContactColLastActive); contact.setLastActivity(lastActivity); contact.setChatState(chatState); - Event evt = new Event(EVENT_TYPE_CHAT_STATE, uci, - mAccount.getType(), contact.getName(), - String.valueOf(contact.getPriority()), - BluetoothMapUtils.getDateTimeString(lastActivity), - convoId, convoName, 0, null, chatState); + Event evt = + new Event( + EVENT_TYPE_CHAT_STATE, + uci, + mAccount.getType(), + contact.getName(), + String.valueOf(contact.getPriority()), + BluetoothMapUtils.getDateTimeString( + lastActivity), + convoId, + convoName, + 0, + null, + chatState); sendEvent(evt); } contactList.put(uci, contact); @@ -2204,17 +2556,19 @@ public class BluetoothMapContentObserver { BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 13); mMasInstance.restartObexServerSession(); - Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " + mMasId - + " restaring ObexServerSession"); + Log.w( + TAG, + "Problems contacting the ContentProvider in mas Instance " + + mMasId + + " restaring ObexServerSession"); } - } // TODO: conversation contact updates if IM and SMS(MMS in one instance } @VisibleForTesting - boolean setEmailMessageStatusDelete(BluetoothMapFolderElement mCurrentFolder, - String uriStr, long handle, int status) { + boolean setEmailMessageStatusDelete( + BluetoothMapFolderElement mCurrentFolder, String uriStr, long handle, int status) { boolean res = false; Uri uri = Uri.parse(uriStr + BluetoothMapContract.TABLE_MESSAGE); @@ -2232,8 +2586,9 @@ public class BluetoothMapContentObserver { folderId = deleteFolder.getFolderId(); } contentValues.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId); - updateCount = BluetoothMethodProxy.getInstance().contentResolverUpdate( - mResolver, uri, contentValues, null, null); + updateCount = + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(mResolver, uri, contentValues, null, null); /* The race between updating the value in our cached values and the database * is handled by the synchronized statement. */ if (updateCount > 0) { @@ -2246,8 +2601,14 @@ public class BluetoothMapContentObserver { } Log.d(TAG, "Deleted MSG: " + handle + " from folderId: " + folderId); } else { - Log.w(TAG, "Msg: " + handle + " - Set delete status " + status - + " failed for folderId " + folderId); + Log.w( + TAG, + "Msg: " + + handle + + " - Set delete status " + + status + + " failed for folderId " + + folderId); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, @@ -2258,7 +2619,8 @@ public class BluetoothMapContentObserver { } else if (status == BluetoothMapAppParams.STATUS_VALUE_NO) { /* Undelete message. move to old folder if we know it, * else move to inbox - as dictated by the spec. */ - if (msg != null && deleteFolder != null + if (msg != null + && deleteFolder != null && msg.folderId == deleteFolder.getFolderId()) { /* Only modify messages in the 'Deleted' folder */ long folderId = -1; @@ -2270,12 +2632,16 @@ public class BluetoothMapContentObserver { if (inboxFolder != null) { folderId = inboxFolder.getFolderId(); } - Log.d(TAG, "We did not delete the message, hence the old folder " - + "is unknown. Moving to inbox."); + Log.d( + TAG, + "We did not delete the message, hence the old folder " + + "is unknown. Moving to inbox."); } contentValues.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId); - updateCount = BluetoothMethodProxy.getInstance().contentResolverUpdate( - mResolver, uri, contentValues, null, null); + updateCount = + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mResolver, uri, contentValues, null, null); if (updateCount > 0) { res = true; /* Update the folder ID to avoid triggering an event for MCE @@ -2290,14 +2656,22 @@ public class BluetoothMapContentObserver { msg.folderId = folderId; } } else { - Log.d(TAG, "We did not delete the message, hence the old folder " - + "is unknown. Moving to inbox."); + Log.d( + TAG, + "We did not delete the message, hence the old folder " + + "is unknown. Moving to inbox."); } } } - Log.v(TAG, "setEmailMessageStatusDelete: " + handle + " from " - + mCurrentFolder.getFolderById(msg.folderId) + " status: " + status); + Log.v( + TAG, + "setEmailMessageStatusDelete: " + + handle + + " from " + + mCurrentFolder.getFolderById(msg.folderId) + + " status: " + + status); } if (!res) { Log.w(TAG, "Set delete status " + status + " failed."); @@ -2313,16 +2687,17 @@ public class BluetoothMapContentObserver { private void updateThreadId(Uri uri, String valueString, long threadId) { ContentValues contentValues = new ContentValues(); contentValues.put(valueString, threadId); - BluetoothMethodProxy.getInstance().contentResolverUpdate(mResolver, uri, contentValues, - null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(mResolver, uri, contentValues, null, null); } @VisibleForTesting boolean deleteMessageMms(long handle) { boolean res = false; Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uri, null, - null, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(mResolver, uri, null, null, null, null); try { if (c != null && c.moveToFirst()) { /* Move to deleted folder, or delete if already in deleted folder */ @@ -2342,8 +2717,8 @@ public class BluetoothMapContentObserver { getMsgListMms().remove(handle); } /* Delete message */ - BluetoothMethodProxy.getInstance().contentResolverDelete(mResolver, uri, null, - null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete(mResolver, uri, null, null); } res = true; } @@ -2360,8 +2735,9 @@ public class BluetoothMapContentObserver { boolean unDeleteMessageMms(long handle) { boolean res = false; Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uri, null, - null, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(mResolver, uri, null, null, null, null); try { if (c != null && c.moveToFirst()) { int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); @@ -2372,17 +2748,19 @@ public class BluetoothMapContentObserver { long id = c.getLong(c.getColumnIndex(Mms._ID)); int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); if (msgBox == Mms.MESSAGE_BOX_INBOX) { - address = BluetoothMapContent.getAddressMms(mResolver, id, - BluetoothMapContent.MMS_FROM); + address = + BluetoothMapContent.getAddressMms( + mResolver, id, BluetoothMapContent.MMS_FROM); } else { - address = BluetoothMapContent.getAddressMms(mResolver, id, - BluetoothMapContent.MMS_TO); + address = + BluetoothMapContent.getAddressMms( + mResolver, id, BluetoothMapContent.MMS_TO); } Set recipients = new HashSet(); recipients.addAll(Arrays.asList(address)); Long oldThreadId = - BluetoothMethodProxy.getInstance().telephonyGetOrCreateThreadId( - mContext, recipients); + BluetoothMethodProxy.getInstance() + .telephonyGetOrCreateThreadId(mContext, recipients); synchronized (getMsgListMms()) { Msg msg = getMsgListMms().get(handle); if (msg != null) { // This will always be the case @@ -2398,8 +2776,12 @@ public class BluetoothMapContentObserver { } updateThreadId(uri, Mms.THREAD_ID, oldThreadId); } else { - Log.d(TAG, "Message not in deleted folder: handle " + handle + " threadId " - + threadId); + Log.d( + TAG, + "Message not in deleted folder: handle " + + handle + + " threadId " + + threadId); } res = true; } @@ -2415,8 +2797,9 @@ public class BluetoothMapContentObserver { boolean deleteMessageSms(long handle) { boolean res = false; Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uri, null, - null, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(mResolver, uri, null, null, null, null); try { if (c != null && c.moveToFirst()) { /* Move to deleted folder, or delete if already in deleted folder */ @@ -2436,8 +2819,8 @@ public class BluetoothMapContentObserver { getMsgListSms().remove(handle); } /* Delete message */ - BluetoothMethodProxy.getInstance().contentResolverDelete(mResolver, uri, null, - null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete(mResolver, uri, null, null); } res = true; } @@ -2453,8 +2836,9 @@ public class BluetoothMapContentObserver { boolean unDeleteMessageSms(long handle) { boolean res = false; Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, uri, null, - null, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(mResolver, uri, null, null, null, null); try { if (c != null && c.moveToFirst()) { int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); @@ -2463,8 +2847,8 @@ public class BluetoothMapContentObserver { Set recipients = new HashSet(); recipients.addAll(Arrays.asList(address)); Long oldThreadId = - BluetoothMethodProxy.getInstance().telephonyGetOrCreateThreadId( - mContext, recipients); + BluetoothMethodProxy.getInstance() + .telephonyGetOrCreateThreadId(mContext, recipients); synchronized (getMsgListSms()) { Msg msg = getMsgListSms().get(handle); if (msg != null) { @@ -2486,8 +2870,12 @@ public class BluetoothMapContentObserver { } updateThreadId(uri, Sms.THREAD_ID, oldThreadId); } else { - Log.d(TAG, "Message not in deleted folder: handle " + handle + " threadId " - + threadId); + Log.d( + TAG, + "Message not in deleted folder: handle " + + handle + + " threadId " + + threadId); } res = true; } @@ -2502,11 +2890,21 @@ public class BluetoothMapContentObserver { /** * @return true is success */ - boolean setMessageStatusDeleted(long handle, TYPE type, - BluetoothMapFolderElement mCurrentFolder, String uriStr, int statusValue) { + boolean setMessageStatusDeleted( + long handle, + TYPE type, + BluetoothMapFolderElement mCurrentFolder, + String uriStr, + int statusValue) { boolean res = false; - Log.d(TAG, "setMessageStatusDeleted: handle " + handle + " type " + type + " value " - + statusValue); + Log.d( + TAG, + "setMessageStatusDeleted: handle " + + handle + + " type " + + type + + " value " + + statusValue); if (type == TYPE.EMAIL) { res = setEmailMessageStatusDelete(mCurrentFolder, uriStr, handle, statusValue); @@ -2538,8 +2936,14 @@ public class BluetoothMapContentObserver { throws RemoteException { int count = 0; - Log.d(TAG, "setMessageStatusRead: handle " + handle + " type " + type + " value " - + statusValue); + Log.d( + TAG, + "setMessageStatusRead: handle " + + handle + + " type " + + type + + " value " + + statusValue); /* Approved MAP spec errata 3445 states that read status initiated * by the MCE shall change the MSE read status. */ @@ -2556,8 +2960,9 @@ public class BluetoothMapContentObserver { msg.flagRead = statusValue; } } - count = BluetoothMethodProxy.getInstance().contentResolverUpdate(mResolver, uri, - contentValues, null, null); + count = + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(mResolver, uri, contentValues, null, null); Log.d(TAG, " -> " + count + " rows updated!"); } else if (type == TYPE.MMS) { @@ -2571,8 +2976,9 @@ public class BluetoothMapContentObserver { msg.flagRead = statusValue; } } - count = BluetoothMethodProxy.getInstance().contentResolverUpdate(mResolver, uri, - contentValues, null, null); + count = + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(mResolver, uri, contentValues, null, null); Log.d(TAG, " -> " + count + " rows updated!"); } else if (type == TYPE.EMAIL || type == TYPE.IM) { Uri uri = mMessageUri; @@ -2619,7 +3025,6 @@ public class BluetoothMapContentObserver { this.statusDelivered = 0; /* Assume success */ this.timestamp = 0; } - ; } @@ -2661,13 +3066,18 @@ public class BluetoothMapContentObserver { return resolver.insert(uri, values); } - public long pushMessage(BluetoothMapbMessage msg, BluetoothMapFolderElement folderElement, - BluetoothMapAppParams ap, String emailBaseUri) + public long pushMessage( + BluetoothMapbMessage msg, + BluetoothMapFolderElement folderElement, + BluetoothMapAppParams ap, + String emailBaseUri) throws IllegalArgumentException, RemoteException, IOException { Log.d(TAG, "pushMessage"); ArrayList recipientList = msg.getRecipients(); - int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? 0 - : ap.getTransparent(); + int transparent = + (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) + ? 0 + : ap.getTransparent(); int retry = ap.getRetry(); long handle = -1; long folderId = -1; @@ -2710,8 +3120,12 @@ public class BluetoothMapContentObserver { FileOutputStream os = null; ParcelFileDescriptor fdOut = null; Uri uriInsert = Uri.parse(emailBaseUri + BluetoothMapContract.TABLE_MESSAGE); - Log.d(TAG, "pushMessage - uriInsert= " + uriInsert.toString() + ", intoFolder id=" - + folderElement.getFolderId()); + Log.d( + TAG, + "pushMessage - uriInsert= " + + uriInsert.toString() + + ", intoFolder id=" + + folderElement.getFolderId()); synchronized (getMsgListMsg()) { // Now insert the empty message into folder @@ -2779,8 +3193,10 @@ public class BluetoothMapContentObserver { /*TODO: We need to add the new 1.1 parameter as well:-) e.g. read*/ Msg newMsg = new Msg(handle, folderId, 1); // TODO: Create define for read-state newMsg.transparent = transparent == 1; - if (folderId == folderElement.getFolderByName( - BluetoothMapContract.FOLDER_NAME_OUTBOX).getFolderId()) { + if (folderId + == folderElement + .getFolderByName(BluetoothMapContract.FOLDER_NAME_OUTBOX) + .getFolderId()) { newMsg.localInitiatedSend = true; } getMsgListMsg().put(handle, newMsg); @@ -2797,8 +3213,13 @@ public class BluetoothMapContentObserver { } } // Send message if folder is outbox else just store in draft - handle = sendMmsMessage(folder, telNums.toArray(new String[telNums.size()]), - (BluetoothMapbMessageMime) msg, transparent, retry); + handle = + sendMmsMessage( + folder, + telNums.toArray(new String[telNums.size()]), + (BluetoothMapbMessageMime) msg, + transparent, + retry); } else { // type SMS_* (single or mass text) or single MMS for (BluetoothMapbMessage.VCard recipient : recipientList) { // Only send the message to the top level recipient @@ -2818,23 +3239,30 @@ public class BluetoothMapContentObserver { ArrayList parts = smsMng.divideMessage(msgBody); int smsParts = parts.size(); if (smsParts <= CONVERT_MMS_TO_SMS_PART_COUNT) { - Log.d(TAG, "pushMessage - converting MMS to SMS, sms parts=" - + smsParts); + Log.d( + TAG, + "pushMessage - converting MMS to SMS, sms parts=" + smsParts); msg.setType(mSmsType); } else { - Log.d(TAG, "pushMessage - MMS text only but to big to " - + "convert to SMS"); + Log.d( + TAG, + "pushMessage - MMS text only but to big to " + + "convert to SMS"); msgBody = null; } - } if (msg.getType().equals(TYPE.MMS)) { /* Send message if folder is outbox else just store in draft*/ - handle = sendMmsMessage(folder, new String[] {phone}, - (BluetoothMapbMessageMime) msg, transparent, retry); - } else if (msg.getType().equals(TYPE.SMS_GSM) || msg.getType() - .equals(TYPE.SMS_CDMA)) { + handle = + sendMmsMessage( + folder, + new String[] {phone}, + (BluetoothMapbMessageMime) msg, + transparent, + retry); + } else if (msg.getType().equals(TYPE.SMS_GSM) + || msg.getType().equals(TYPE.SMS_CDMA)) { /* Add the message to the database */ if (msgBody == null) { msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody(); @@ -2850,8 +3278,14 @@ public class BluetoothMapContentObserver { Uri contentUri = Uri.parse(Sms.CONTENT_URI + "/" + folder); Uri uri; synchronized (getMsgListSms()) { - uri = addMessageToUri(mResolver, contentUri, phone, msgBody, "", - System.currentTimeMillis()); + uri = + addMessageToUri( + mResolver, + contentUri, + phone, + msgBody, + "", + System.currentTimeMillis()); Log.v(TAG, "Sms.addMessageToUri() returned: " + uri); if (uri == null) { @@ -2868,9 +3302,17 @@ public class BluetoothMapContentObserver { int type = c.getInt(c.getColumnIndex(Sms.TYPE)); int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); int readFlag = c.getInt(c.getColumnIndex(Sms.READ)); - Log.v(TAG, "add message with id=" + id + " type=" + type - + " threadId=" + threadId + " readFlag=" + readFlag - + "to mMsgListSms"); + Log.v( + TAG, + "add message with id=" + + id + + " type=" + + type + + " threadId=" + + threadId + + " readFlag=" + + readFlag + + "to mMsgListSms"); Msg newMsg = new Msg(id, type, threadId, readFlag); getMsgListSms().put(id, newMsg); c.close(); @@ -2918,8 +3360,12 @@ public class BluetoothMapContentObserver { return handle; } - public long sendMmsMessage(String folder, String[] toAddress, BluetoothMapbMessageMime msg, - int transparent, int retry) { + public long sendMmsMessage( + String folder, + String[] toAddress, + BluetoothMapbMessageMime msg, + int transparent, + int retry) { /* *strategy: *1) parse message into parts @@ -2931,16 +3377,19 @@ public class BluetoothMapContentObserver { *else if folder !outbox: *1) push message to folder * */ - if (folder != null && (folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX) - || folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT))) { + if (folder != null + && (folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX) + || folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT))) { long handle = pushMmsToFolder(Mms.MESSAGE_BOX_DRAFTS, toAddress, msg); /* if invalid handle (-1) then just return the handle * - else continue sending (if folder is outbox) */ - if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle && folder.equalsIgnoreCase( - BluetoothMapContract.FOLDER_NAME_OUTBOX)) { - Uri btMmsUri = MmsFileProvider.CONTENT_URI.buildUpon() - .appendPath(Long.toString(handle)) - .build(); + if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle + && folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX)) { + Uri btMmsUri = + MmsFileProvider.CONTENT_URI + .buildUpon() + .appendPath(Long.toString(handle)) + .build(); Intent sentIntent = new Intent(ACTION_MESSAGE_SENT); // TODO: update the mmsMsgList <- done in pushMmsToFolder() but check sentIntent.setType("message/" + Long.toString(handle)); @@ -2948,13 +3397,16 @@ public class BluetoothMapContentObserver { sentIntent.putExtra(EXTRA_MESSAGE_SENT_HANDLE, handle); // needed for notification sentIntent.putExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, transparent); sentIntent.putExtra(EXTRA_MESSAGE_SENT_RETRY, retry); - //sentIntent.setDataAndNormalize(btMmsUri); + // sentIntent.setDataAndNormalize(btMmsUri); PendingIntent pendingSendIntent = - PendingIntent.getBroadcast(mContext, 0, sentIntent, - PendingIntent.FLAG_IMMUTABLE); + PendingIntent.getBroadcast( + mContext, 0, sentIntent, PendingIntent.FLAG_IMMUTABLE); SmsManager.getDefault() - .sendMultimediaMessage(mContext, btMmsUri, null/*locationUrl*/, - null/*configOverrides*/, + .sendMultimediaMessage( + mContext, + btMmsUri, + null /*locationUrl*/, + null /*configOverrides*/, pendingSendIntent); } return handle; @@ -2967,6 +3419,7 @@ public class BluetoothMapContentObserver { /** * Move a MMS to another folder. + * * @param handle the CP handle of the message to move * @param resolver the ContentResolver to use * @param folder the destination folder - use Mms.MESSAGE_BOX_xxx @@ -2986,8 +3439,8 @@ public class BluetoothMapContentObserver { ContentValues data = new ContentValues(); /* set folder to be outbox */ data.put(Mms.MESSAGE_BOX, folder); - BluetoothMethodProxy.getInstance().contentResolverUpdate(resolver, uri, - data, whereClause, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(resolver, uri, data, whereClause, null); Log.d(TAG, "moved MMS message to " + getMmsFolderName(folder)); } } else { @@ -3060,8 +3513,8 @@ public class BluetoothMapContentObserver { return -1; } /* As we already have all the values we need, we could skip the query, but - doing the query ensures we get any changes made by the content provider - at insert. */ + doing the query ensures we get any changes made by the content provider + at insert. */ Cursor c = mResolver.query(uri, MMS_PROJECTION_SHORT, null, null, null); try { if (c != null && c.moveToFirst()) { @@ -3144,8 +3597,8 @@ public class BluetoothMapContentObserver { uri = mResolver.insert(uri, values); Log.v(TAG, "Added TEXT part"); - } else if (part.mContentType != null && part.mContentType.toUpperCase() - .contains("SMIL")) { + } else if (part.mContentType != null + && part.mContentType.toUpperCase().contains("SMIL")) { values.put(Mms.Part.SEQ, -1); values.put(Mms.Part.CONTENT_TYPE, "application/smil"); if (part.mContentId != null) { @@ -3175,8 +3628,12 @@ public class BluetoothMapContentObserver { Log.v(TAG, "Added OTHER part"); } if (uri != null) { - Log.v(TAG, "Added part with content-type: " + part.mContentType - + " to Uri: " + uri.toString()); + Log.v( + TAG, + "Added part with content-type: " + + part.mContentType + + " to Uri: " + + uri.toString()); } } } @@ -3223,7 +3680,6 @@ public class BluetoothMapContentObserver { return handle; } - private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException { ContentValues values = new ContentValues(); values.put(Mms.Part.MSG_ID, handle); @@ -3276,7 +3732,6 @@ public class BluetoothMapContentObserver { os.close(); } - public void sendMessage(PushMsgInfo msgInfo, String msgBody) { SmsManager smsMng = SmsManager.getDefault(); ArrayList parts = smsMng.divideMessage(msgBody); @@ -3310,7 +3765,10 @@ public class BluetoothMapContentObserver { intentDelivery.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id); intentDelivery.putExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, msgInfo.timestamp); PendingIntent pendingIntentDelivery = - PendingIntent.getBroadcast(mContext, 0, intentDelivery, + PendingIntent.getBroadcast( + mContext, + 0, + intentDelivery, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); intentSent = new Intent(ACTION_MESSAGE_SENT, null); @@ -3325,7 +3783,10 @@ public class BluetoothMapContentObserver { intentSent.putExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, msgInfo.transparent); PendingIntent pendingIntentSent = - PendingIntent.getBroadcast(mContext, 0, intentSent, + PendingIntent.getBroadcast( + mContext, + 0, + intentSent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); // We use the same pending intent for all parts, but do not set the one shot flag. @@ -3343,8 +3804,8 @@ public class BluetoothMapContentObserver { sentIntents.get(0), deliveryIntents.get(0)); } else { - smsMng.sendMultipartTextMessageWithoutPersisting(msgInfo.phone, null, parts, - sentIntents, deliveryIntents); + smsMng.sendMultipartTextMessageWithoutPersisting( + msgInfo.phone, null, parts, sentIntents, deliveryIntents); } } } @@ -3406,8 +3867,14 @@ public class BluetoothMapContentObserver { */ msgInfo.failedSent = true; } - Log.d(TAG, "onReceive: msgInfo.partsSent = " + msgInfo.partsSent - + ", msgInfo.parts = " + msgInfo.parts + " result = " + result); + Log.d( + TAG, + "onReceive: msgInfo.partsSent = " + + msgInfo.partsSent + + ", msgInfo.parts = " + + msgInfo.parts + + " result = " + + result); if (msgInfo.partsSent == msgInfo.parts) { actionMessageSent(context, msgInfo, handle); @@ -3448,8 +3915,13 @@ public class BluetoothMapContentObserver { delete = true; } - Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msgInfo.id, - getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType); + Event evt = + new Event( + EVENT_TYPE_SENDING_SUCCESS, + msgInfo.id, + getSmsFolderName(Sms.MESSAGE_TYPE_SENT), + null, + mSmsType); sendEvent(evt); } else { @@ -3458,8 +3930,13 @@ public class BluetoothMapContentObserver { msgInfo.resend = true; msgInfo.partsSent = 0; // Reset counter for the retry msgInfo.failedSent = false; - Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, msgInfo.id, - getSmsFolderName(Sms.MESSAGE_TYPE_OUTBOX), null, mSmsType); + Event evt = + new Event( + EVENT_TYPE_SENDING_FAILURE, + msgInfo.id, + getSmsFolderName(Sms.MESSAGE_TYPE_OUTBOX), + null, + mSmsType); sendEvent(evt); } else { if (msgInfo.transparent == 0) { @@ -3476,8 +3953,13 @@ public class BluetoothMapContentObserver { delete = true; } - Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, msgInfo.id, - getSmsFolderName(Sms.MESSAGE_TYPE_FAILED), null, mSmsType); + Event evt = + new Event( + EVENT_TYPE_SENDING_FAILURE, + msgInfo.id, + getSmsFolderName(Sms.MESSAGE_TYPE_FAILED), + null, + mSmsType); sendEvent(evt); } } @@ -3560,12 +4042,13 @@ public class BluetoothMapContentObserver { /** * Handle MMS sent intents in disconnected(MNS) state, where we do not need to send any * notifications. + * * @param context The context to use for provider operations * @param intent The intent received * @param result The result */ - public static void actionMmsSent(Context context, Intent intent, int result, - Map mmsMsgList) { + public static void actionMmsSent( + Context context, Intent intent, int result, Map mmsMsgList) { /* * if transparent: * delete message and send notification(regardless of result) @@ -3623,8 +4106,9 @@ public class BluetoothMapContentObserver { } public static void actionMessageSentDisconnected(Context context, Intent intent, int result) { - TYPE type = TYPE.fromOrdinal( - intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal())); + TYPE type = + TYPE.fromOrdinal( + intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal())); if (type == TYPE.MMS) { actionMmsSent(context, intent, result, null); } else { @@ -3646,7 +4130,7 @@ public class BluetoothMapContentObserver { } boolean delete = false; - //int retry = intent.getIntExtra(EXTRA_MESSAGE_SENT_RETRY, 0); + // int retry = intent.getIntExtra(EXTRA_MESSAGE_SENT_RETRY, 0); int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0); String uriString = intent.getStringExtra(EXTRA_MESSAGE_SENT_URI); if (uriString == null) { @@ -3732,8 +4216,6 @@ public class BluetoothMapContentObserver { c.close(); } } - - } private void failPendingMessages() { @@ -3756,7 +4238,6 @@ public class BluetoothMapContentObserver { c.close(); } } - } private void removeDeletedMessages() { @@ -3774,15 +4255,16 @@ public class BluetoothMapContentObserver { } } - private PhoneStateListener mPhoneListener = new PhoneStateListener() { - @Override - public void onServiceStateChanged(ServiceState serviceState) { - Log.d(TAG, "Phone service state change: " + serviceState.getState()); - if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { - resendPendingMessages(); - } - } - }; + private PhoneStateListener mPhoneListener = + new PhoneStateListener() { + @Override + public void onServiceStateChanged(ServiceState serviceState) { + Log.d(TAG, "Phone service state change: " + serviceState.getState()); + if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { + resendPendingMessages(); + } + } + }; public void init() { if (mSmsBroadcastReceiver != null) { @@ -3811,8 +4293,9 @@ public class BluetoothMapContentObserver { } public boolean handleSmsSendIntent(Context context, Intent intent) { - TYPE type = TYPE.fromOrdinal( - intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal())); + TYPE type = + TYPE.fromOrdinal( + intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal())); if (type == TYPE.MMS) { return handleMmsSendIntent(context, intent); } else { @@ -3850,21 +4333,30 @@ public class BluetoothMapContentObserver { } if (result != Activity.RESULT_OK) { if (mObserverRegistered) { - Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, handle, - getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), null, TYPE.MMS); + Event evt = + new Event( + EVENT_TYPE_SENDING_FAILURE, + handle, + getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), + null, + TYPE.MMS); sendEvent(evt); } } else { int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0); if (transparent != 0) { if (mObserverRegistered) { - Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, handle, - getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), null, TYPE.MMS); + Event evt = + new Event( + EVENT_TYPE_SENDING_SUCCESS, + handle, + getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), + null, + TYPE.MMS); sendEvent(evt); } } } return true; } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java index a73082171cf..3dcb6141aca 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -62,8 +62,8 @@ public class BluetoothMapConvoContactElement private SignedLongLong mBtUid = null; private int mChatState = -1; - public static BluetoothMapConvoContactElement createFromMapContact(MapContact contact, - String address) { + public static BluetoothMapConvoContactElement createFromMapContact( + MapContact contact, String address) { BluetoothMapConvoContactElement newElement = new BluetoothMapConvoContactElement(); newElement.mUci = address; // TODO: For now we use the ID as BT-UID @@ -72,9 +72,16 @@ public class BluetoothMapConvoContactElement return newElement; } - public BluetoothMapConvoContactElement(String uci, String name, String displayName, - String presenceStatus, int presenceAvailability, long lastActivity, int chatState, - int priority, String btUid) { + public BluetoothMapConvoContactElement( + String uci, + String name, + String displayName, + String presenceStatus, + int presenceAvailability, + long lastActivity, + int chatState, + int priority, + String btUid) { this.mUci = uci; this.mName = name; this.mDisplayName = displayName; @@ -162,7 +169,6 @@ public class BluetoothMapConvoContactElement this.mChatState = Integer.valueOf(chatState); } - public String getLastActivityString() { SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); Date date = new Date(mLastActivity); @@ -209,12 +215,12 @@ public class BluetoothMapConvoContactElement xmlConvoElement.attribute(null, XML_ATT_UCI, mUci); } if (mDisplayName != null) { - xmlConvoElement.attribute(null, XML_ATT_DISPLAY_NAME, - BluetoothMapUtils.stripInvalidChars(mDisplayName)); + xmlConvoElement.attribute( + null, XML_ATT_DISPLAY_NAME, BluetoothMapUtils.stripInvalidChars(mDisplayName)); } if (mName != null) { - xmlConvoElement.attribute(null, XML_ATT_NAME, - BluetoothMapUtils.stripInvalidChars(mName)); + xmlConvoElement.attribute( + null, XML_ATT_NAME, BluetoothMapUtils.stripInvalidChars(mName)); } if (mChatState != -1) { xmlConvoElement.attribute(null, XML_ATT_CHAT_STATE, String.valueOf(mChatState)); @@ -226,8 +232,8 @@ public class BluetoothMapConvoContactElement xmlConvoElement.attribute(null, XML_ATT_X_BT_UID, mBtUid.toHexString()); } if (mPresenceAvailability != -1) { - xmlConvoElement.attribute(null, XML_ATT_PRESENCE_AVAILABILITY, - String.valueOf(mPresenceAvailability)); + xmlConvoElement.attribute( + null, XML_ATT_PRESENCE_AVAILABILITY, String.valueOf(mPresenceAvailability)); } if (mPresenceStatus != null) { xmlConvoElement.attribute(null, XML_ATT_PRESENCE_STATUS, mPresenceStatus); @@ -239,9 +245,9 @@ public class BluetoothMapConvoContactElement xmlConvoElement.endTag(null, XML_TAG_CONVOCONTACT); } - /** * Call this function to create a BluetoothMapConvoContactElement. Will consume the end-tag. + * * @param parser must point into XML_TAG_CONVERSATION tag, hence attributes can be read. * @return * @throws IOException @@ -297,14 +303,14 @@ public class BluetoothMapConvoContactElement return false; } BluetoothMapConvoContactElement other = (BluetoothMapConvoContactElement) obj; -/* As we use equals only for test, we don't compare auto assigned values - * if (mBtUid == null) { - if (other.mBtUid != null) { - return false; - } - } else if (!mBtUid.equals(other.mBtUid)) { - return false; - }*/ + /* As we use equals only for test, we don't compare auto assigned values + * if (mBtUid == null) { + if (other.mBtUid != null) { + return false; + } + } else if (!mBtUid.equals(other.mBtUid)) { + return false; + }*/ if (mChatState != other.mChatState) { return false; } @@ -315,14 +321,14 @@ public class BluetoothMapConvoContactElement } else if (!mDisplayName.equals(other.mDisplayName)) { return false; } -/* As we use equals only for test, we don't compare auto assigned values - * if (mId == null) { - if (other.mId != null) { - return false; - } - } else if (!mId.equals(other.mId)) { - return false; - }*/ + /* As we use equals only for test, we don't compare auto assigned values + * if (mId == null) { + if (other.mId != null) { + return false; + } + } else if (!mId.equals(other.mId)) { + return false; + }*/ if (mLastActivity != other.mLastActivity) { return false; } @@ -348,7 +354,4 @@ public class BluetoothMapConvoContactElement } return true; } - } - - diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java index 16536b205f1..fa1a8077f13 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -58,6 +58,7 @@ public class BluetoothMapConvoListing { /** * Used to fetch the number of BluetoothMapConvoListingElement elements in the list. + * * @return the number of elements in the list. */ public int getCount() { @@ -69,15 +70,16 @@ public class BluetoothMapConvoListing { /** * does the list contain any unread messages + * * @return true if unread messages have been added to the list, else false */ public boolean hasUnread() { return mHasUnread; } - /** - * returns the entire list as a list + * returns the entire list as a list + * * @return list */ public List getList() { @@ -85,12 +87,11 @@ public class BluetoothMapConvoListing { } /** - * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8 - * formatted XML-string in a trimmed byte array + * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8 formatted XML-string in + * a trimmed byte array * * @return a reference to the encoded byte array. - * @throws UnsupportedEncodingException - * if UTF-8 encoding is unsupported on the platform. + * @throws UnsupportedEncodingException if UTF-8 encoding is unsupported on the platform. */ public byte[] encode() throws UnsupportedEncodingException { StringWriter sw = new StringWriter(); @@ -98,8 +99,8 @@ public class BluetoothMapConvoListing { try { xmlConvoElement.setOutput(sw); xmlConvoElement.startDocument("UTF-8", true); - xmlConvoElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", - true); + xmlConvoElement.setFeature( + "http://xmlpull.org/v1/doc/features.html#indent-output", true); xmlConvoElement.startTag(null, XML_TAG); xmlConvoElement.attribute(null, "version", "1.0"); // Do the XML encoding of list @@ -183,6 +184,7 @@ public class BluetoothMapConvoListing { /** * Parses folder elements, and add to mSubFolders. + * * @param parser the Xml Parser currently pointing to an folder-listing tag. * @throws XmlPullParserException * @throws IOException @@ -211,7 +213,6 @@ public class BluetoothMapConvoListing { } } - @Override public boolean equals(Object obj) { if (this == obj) { @@ -236,5 +237,4 @@ public class BluetoothMapConvoListing { } return true; } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java index 69cf98f6534..5a3b87b0d34 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -50,7 +50,7 @@ public class BluetoothMapConvoListingElement private static final String TAG = "BluetoothMapConvoListingElement"; private SignedLongLong mId = null; - private String mName = ""; //title of the conversation #REQUIRED, but allowed empty + private String mName = ""; // title of the conversation #REQUIRED, but allowed empty private long mLastActivity = -1; private boolean mRead = false; private boolean mReportRead = false; // TODO: Is this needed? - false means UNKNOWN @@ -140,7 +140,6 @@ public class BluetoothMapConvoListingElement mContacts.remove(index); } - public long getLastActivity() { return mLastActivity; } @@ -191,8 +190,9 @@ public class BluetoothMapConvoListingElement /** * Set the conversation ID - * @param type 0 if the thread ID is valid across all message types in the instance - else - * use one of the CONVO_ID_xxx types. + * + * @param type 0 if the thread ID is valid across all message types in the instance - else use + * one of the CONVO_ID_xxx types. * @param threadId the conversation ID */ public void setConvoId(long type, long threadId) { @@ -263,8 +263,8 @@ public class BluetoothMapConvoListingElement xmlConvoElement.startTag(null, XML_TAG_CONVERSATION); xmlConvoElement.attribute(null, XML_ATT_ID, mId.toHexString()); if (mName != null) { - xmlConvoElement.attribute(null, XML_ATT_NAME, - BluetoothMapUtils.stripInvalidChars(mName)); + xmlConvoElement.attribute( + null, XML_ATT_NAME, BluetoothMapUtils.stripInvalidChars(mName)); } if (mLastActivity != -1) { xmlConvoElement.attribute(null, XML_ATT_LAST_ACTIVITY, getLastActivityString()); @@ -274,8 +274,8 @@ public class BluetoothMapConvoListingElement xmlConvoElement.attribute(null, XML_ATT_READ, getRead()); } if (mVersionCounter != -1) { - xmlConvoElement.attribute(null, XML_ATT_VERSION_COUNTER, - Long.toString(getVersionCounter())); + xmlConvoElement.attribute( + null, XML_ATT_VERSION_COUNTER, Long.toString(getVersionCounter())); } if (mSummary != null) { xmlConvoElement.attribute(null, XML_ATT_SUMMARY, getSummary()); @@ -286,12 +286,12 @@ public class BluetoothMapConvoListingElement } } xmlConvoElement.endTag(null, XML_TAG_CONVERSATION); - } /** * Consumes a conversation tag. It is expected that the parser is beyond the start-tag event, * with the name "conversation". + * * @param parser * @return * @throws XmlPullParserException @@ -390,7 +390,7 @@ public class BluetoothMapConvoListingElement return true; } -/* @Override + /* @Override public boolean equals(Object o) { return true; @@ -398,5 +398,3 @@ public class BluetoothMapConvoListingElement */ } - - diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java index 4c80870d50c..6c1deeb4071 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -48,7 +48,6 @@ public class BluetoothMapFolderElement implements Comparable mSubFolders; - private static final String TAG = "BluetoothMapFolderElement"; public BluetoothMapFolderElement(String name, BluetoothMapFolderElement parrent) { @@ -103,6 +102,7 @@ public class BluetoothMapFolderElement implements Comparable= 0 && nativeInterface.isAvailable()) { - verbose("Removing SDP record for MAS instance: " + mMasInstanceId - + " Object reference: " + this + ", SDP handle: " + mSdpHandle); + verbose( + "Removing SDP record for MAS instance: " + + mMasInstanceId + + " Object reference: " + + this + + ", SDP handle: " + + mSdpHandle); boolean status = nativeInterface.removeSdpRecord(mSdpHandle); debug("RemoveSDPrecord returns " + status); mSdpHandle = -1; @@ -159,32 +168,29 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } /** - * The data base identifier is used by connecting MCE devices to evaluate if cached data - * is still valid, hence only update this value when something actually invalidates the data. - * Situations where this must be called: - * - MAS ID's vs. server channels are scrambled (As neither MAS ID, name or server channels) - * can be used by a client to uniquely identify a specific message database - except MAS id 0 - * we should change this value if the server channel is changed. - * - If a MAS instance folderVersionCounter roles over - will not happen before a long - * is too small to hold a unix time-stamp, hence is not handled. + * The data base identifier is used by connecting MCE devices to evaluate if cached data is + * still valid, hence only update this value when something actually invalidates the data. + * Situations where this must be called: - MAS ID's vs. server channels are scrambled (As + * neither MAS ID, name or server channels) can be used by a client to uniquely identify a + * specific message database - except MAS id 0 we should change this value if the server channel + * is changed. - If a MAS instance folderVersionCounter roles over - will not happen before a + * long is too small to hold a unix time-stamp, hence is not handled. */ private void updateDbIdentifier() { mDbIndetifier.set(Calendar.getInstance().getTime().getTime()); } /** - * update the time stamp used for FOLDER version counter. - * Call once when a content provider notification caused applicable changes to the - * list of messages. + * update the time stamp used for FOLDER version counter. Call once when a content provider + * notification caused applicable changes to the list of messages. */ /* package */ void updateFolderVersionCounter() { mFolderVersionCounter.incrementAndGet(); } /** - * update the CONVO LIST version counter. - * Call once when a content provider notification caused applicable changes to the - * list of contacts, or when an update is manually triggered. + * update the CONVO LIST version counter. Call once when a content provider notification caused + * applicable changes to the list of contacts, or when an update is manually triggered. */ /* package */ void updateSmsMmsConvoListVersionCounter() { mSmsMmsConvoListVersionCounter.incrementAndGet(); @@ -264,9 +270,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { return combinedVersionCounter; } - /** - * Start Obex Server Sockets and create the SDP record. - */ + /** Start Obex Server Sockets and create the SDP record. */ public synchronized void startSocketListeners() { debug("Map Service startSocketListeners"); @@ -301,17 +305,24 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { return; } removeSdpRecord(); - mSdpHandle = createMasSdpRecord(mServerSockets.getRfcommChannel(), - mServerSockets.getL2capPsm()); + mSdpHandle = + createMasSdpRecord( + mServerSockets.getRfcommChannel(), mServerSockets.getL2capPsm()); // Here we might have changed crucial data, hence reset DB identifier - verbose("Creating new SDP record for MAS instance: " + mMasInstanceId - + " Object reference: " + this + ", SDP handle: " + mSdpHandle); + verbose( + "Creating new SDP record for MAS instance: " + + mMasInstanceId + + " Object reference: " + + this + + ", SDP handle: " + + mSdpHandle); updateDbIdentifier(); } } /** * Create the MAS SDP record with the information stored in the instance. + * * @param rfcommChannel the rfcomm channel ID * @param l2capPsm the l2capPsm - set to -1 to exclude */ @@ -388,12 +399,13 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } mMnsClient = mnsClient; - mObserver = new BluetoothMapContentObserver(mContext, mMnsClient, this, mAccount, - mEnableSmsMms); + mObserver = + new BluetoothMapContentObserver( + mContext, mMnsClient, this, mAccount, mEnableSmsMms); mObserver.init(); mMapServer = - new BluetoothMapObexServer(mServiceHandler, mContext, mObserver, this, mAccount, - mEnableSmsMms); + new BluetoothMapObexServer( + mServiceHandler, mContext, mObserver, this, mAccount, mEnableSmsMms); mMapServer.setRemoteFeatureMask(mRemoteFeatureMask); // setup transport BluetoothObexTransport transport = new BluetoothObexTransport(mConnSocket); @@ -415,6 +427,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { /** * Check if this instance is started. + * * @return true if started */ public boolean isStarted() { @@ -441,15 +454,12 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { closeServerSockets(false); } - /** - * Signal to the ServerSockets handler that a new connection may be accepted. - */ + /** Signal to the ServerSockets handler that a new connection may be accepted. */ public void restartObexServerSession() { debug("MAP Service restartObexServerSession()"); startSocketListeners(); } - private synchronized void closeServerSockets(boolean block) { // exit SocketAcceptThread early ObexServerSockets sockets = mServerSockets; diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java index 67a485d79ac..562cc8db5a4 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -54,6 +54,7 @@ public class BluetoothMapMessageListing { /** * Used to fetch the number of BluetoothMapMessageListingElement elements in the list. + * * @return the number of elements in the list. */ public int getCount() { @@ -65,15 +66,16 @@ public class BluetoothMapMessageListing { /** * does the list contain any unread messages + * * @return true if unread messages have been added to the list, else false */ public boolean hasUnread() { return mHasUnread; } - /** - * returns the entire list as a list + * returns the entire list as a list + * * @return list */ public List getList() { @@ -81,15 +83,13 @@ public class BluetoothMapMessageListing { } /** - * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8 - * formatted XML-string in a trimmed byte array + * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8 formatted XML-string in + * a trimmed byte array * - * @param version the version as a string. - * Set the listing version to e.g. "1.0" or "1.1". - * To make this future proof, no check is added to validate the value, hence be careful. + * @param version the version as a string. Set the listing version to e.g. "1.0" or "1.1". To + * make this future proof, no check is added to validate the value, hence be careful. * @return a reference to the encoded byte array. - * @throws UnsupportedEncodingException - * if UTF-8 encoding is unsupported on the platform. + * @throws UnsupportedEncodingException if UTF-8 encoding is unsupported on the platform. */ // TODO: Remove includeThreadId when MAP-IM is adopted public byte[] encode(boolean includeThreadId, String version) @@ -100,16 +100,16 @@ public class BluetoothMapMessageListing { if (Utils.isInstrumentationTestMode()) { isBenzCarkit = false; } else { - isBenzCarkit = DeviceWorkArounds.addressStartsWith( - BluetoothMapService.getRemoteDevice().getAddress(), - DeviceWorkArounds.MERCEDES_BENZ_CARKIT); + isBenzCarkit = + DeviceWorkArounds.addressStartsWith( + BluetoothMapService.getRemoteDevice().getAddress(), + DeviceWorkArounds.MERCEDES_BENZ_CARKIT); } try { XmlSerializer xmlMsgElement = Xml.newSerializer(); xmlMsgElement.setOutput(sw); if (isBenzCarkit) { - Log.d(TAG, "java_interop: Remote is Mercedes Benz, " - + "using Xml Workaround."); + Log.d(TAG, "java_interop: Remote is Mercedes Benz, " + "using Xml Workaround."); xmlMsgElement.text("\n"); } else { xmlMsgElement.startDocument("UTF-8", true); @@ -147,9 +147,10 @@ public class BluetoothMapMessageListing { Log.w(TAG, e); } /* Fix IOT issue to replace '&' by '&', < by < and '> by '>' in MessageListing */ - if (!Utils.isInstrumentationTestMode() && DeviceWorkArounds.addressStartsWith( - BluetoothMapService.getRemoteDevice().getAddress(), - DeviceWorkArounds.BREZZA_ZDI_CARKIT)) { + if (!Utils.isInstrumentationTestMode() + && DeviceWorkArounds.addressStartsWith( + BluetoothMapService.getRemoteDevice().getAddress(), + DeviceWorkArounds.BREZZA_ZDI_CARKIT)) { return sw.toString() .replaceAll("&", "&") .replaceAll("<", "<") diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java index dd500d6223b..9b4ea1f5731 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import com.android.bluetooth.DeviceWorkArounds; @@ -272,26 +272,28 @@ public class BluetoothMapMessageListingElement if (mSubject != null) { String stripped = BluetoothMapUtils.stripInvalidChars(mSubject); - if (DeviceWorkArounds.addressStartsWith(BluetoothMapService - .getRemoteDevice().getAddress(), DeviceWorkArounds - .MERCEDES_BENZ_CARKIT)) { + if (DeviceWorkArounds.addressStartsWith( + BluetoothMapService.getRemoteDevice().getAddress(), + DeviceWorkArounds.MERCEDES_BENZ_CARKIT)) { stripped = stripped.replaceAll("[\\P{ASCII}&\"><]", ""); if (stripped.isEmpty()) { stripped = "---"; } } - xmlMsgElement.attribute(null, "subject", + xmlMsgElement.attribute( + null, + "subject", stripped.substring(0, stripped.length() < 256 ? stripped.length() : 256)); } if (mDateTime != 0) { - xmlMsgElement.attribute(null, "datetime", - BluetoothMapUtils.getDateTimeString(this.getDateTime())); + xmlMsgElement.attribute( + null, "datetime", BluetoothMapUtils.getDateTimeString(this.getDateTime())); } if (mSenderName != null) { - xmlMsgElement.attribute(null, "sender_name", - BluetoothMapUtils.stripInvalidChars(mSenderName)); + xmlMsgElement.attribute( + null, "sender_name", BluetoothMapUtils.stripInvalidChars(mSenderName)); } if (mSenderAddressing != null) { xmlMsgElement.attribute(null, "sender_addressing", mSenderAddressing); @@ -300,13 +302,13 @@ public class BluetoothMapMessageListingElement xmlMsgElement.attribute(null, "replyto_addressing", mReplytoAddressing); } if (mRecipientName != null) { - xmlMsgElement.attribute(null, "recipient_name", - BluetoothMapUtils.stripInvalidChars(mRecipientName)); + xmlMsgElement.attribute( + null, "recipient_name", BluetoothMapUtils.stripInvalidChars(mRecipientName)); } if (mRecipientAddressing != null) { xmlMsgElement.attribute(null, "recipient_addressing", mRecipientAddressing); } - /* Avoid NPE for possible "null" value of mType */ + /* Avoid NPE for possible "null" value of mType */ if (mMsgTypeAppParamSet && mType != null) { xmlMsgElement.attribute(null, "type", mType.name()); } @@ -350,8 +352,5 @@ public class BluetoothMapMessageListingElement xmlMsgElement.attribute(null, "folder_type", mFolderType); } xmlMsgElement.endTag(null, "msg"); - } } - - diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java index dd1ec9e9f58..4c503bd0e1b 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -55,7 +55,6 @@ public class BluetoothMapObexServer extends ServerRequestHandler { private static final String TAG = "BluetoothMapObexServer"; - private static final int UUID_LENGTH = 16; private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS; @@ -65,24 +64,25 @@ public class BluetoothMapObexServer extends ServerRequestHandler { private static final long THREAD_MAIL_KEY = 0x534c5349; // 128 bit UUID for MAP - private static final byte[] MAP_TARGET = new byte[]{ - (byte) 0xBB, - (byte) 0x58, - (byte) 0x2B, - (byte) 0x40, - (byte) 0x42, - (byte) 0x0C, - (byte) 0x11, - (byte) 0xDB, - (byte) 0xB0, - (byte) 0xDE, - (byte) 0x08, - (byte) 0x00, - (byte) 0x20, - (byte) 0x0C, - (byte) 0x9A, - (byte) 0x66 - }; + private static final byte[] MAP_TARGET = + new byte[] { + (byte) 0xBB, + (byte) 0x58, + (byte) 0x2B, + (byte) 0x40, + (byte) 0x42, + (byte) 0x0C, + (byte) 0x11, + (byte) 0xDB, + (byte) 0xB0, + (byte) 0xDE, + (byte) 0x08, + (byte) 0x00, + (byte) 0x20, + (byte) 0x0C, + (byte) 0x9A, + (byte) 0x66 + }; public static final ParcelUuid MAP = ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB"); public static final ParcelUuid MNS = @@ -126,9 +126,14 @@ public class BluetoothMapObexServer extends ServerRequestHandler { private ContentResolver mResolver; private ContentProviderClient mProviderClient = null; - public BluetoothMapObexServer(Handler callback, Context context, - BluetoothMapContentObserver observer, BluetoothMapMasInstance mas, - BluetoothMapAccountItem account, boolean enableSmsMms) throws RemoteException { + public BluetoothMapObexServer( + Handler callback, + Context context, + BluetoothMapContentObserver observer, + BluetoothMapMasInstance mas, + BluetoothMapAccountItem account, + boolean enableSmsMms) + throws RemoteException { super(); mCallback = callback; mContext = context; @@ -155,19 +160,17 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } buildFolderStructure(); /* Build the default folder structure, and set - mCurrentFolder to root folder */ + mCurrentFolder to root folder */ mObserver.setFolderStructure(mCurrentFolder.getRoot()); mOutContent = new BluetoothMapContent(mContext, mAccount, mMasInstance); - } - /** - * - */ + /** */ private ContentProviderClient acquireUnstableContentProviderOrThrow() throws RemoteException { - ContentProviderClient providerClient = BluetoothMethodProxy.getInstance() - .contentResolverAcquireUnstableContentProviderClient(mResolver, mAuthority); + ContentProviderClient providerClient = + BluetoothMethodProxy.getInstance() + .contentResolverAcquireUnstableContentProviderClient(mResolver, mAuthority); if (providerClient == null) { throw new RemoteException("Failed to acquire provider for " + mAuthority); } @@ -175,11 +178,9 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return providerClient; } - /** - * Build the default minimal folder structure, as defined in the MAP specification. - */ + /** Build the default minimal folder structure, as defined in the MAP specification. */ private void buildFolderStructure() throws RemoteException { - //This will be the root element + // This will be the root element mCurrentFolder = new BluetoothMapFolderElement("root", null); mCurrentFolder.setHasSmsMmsContent(mEnableSmsMms); boolean hasIM = false; @@ -201,7 +202,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { tmpFolder.setHasImContent(hasIM); tmpFolder.setHasEmailContent(hasEmail); - tmpFolder = tmpFolder.addFolder("msg"); // root/telecom/msg + tmpFolder = tmpFolder.addFolder("msg"); // root/telecom/msg tmpFolder.setHasSmsMmsContent(mEnableSmsMms); tmpFolder.setHasImContent(hasIM); tmpFolder.setHasEmailContent(hasEmail); @@ -220,65 +221,67 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } - /** - * Add base (Inbox/Outbox/Sent/Deleted) - */ + /** Add base (Inbox/Outbox/Sent/Deleted) */ private void addBaseFolders(BluetoothMapFolderElement root) { - root.addFolder(BluetoothMapContract.FOLDER_NAME_INBOX); // root/telecom/msg/inbox + root.addFolder(BluetoothMapContract.FOLDER_NAME_INBOX); // root/telecom/msg/inbox root.addFolder(BluetoothMapContract.FOLDER_NAME_OUTBOX); root.addFolder(BluetoothMapContract.FOLDER_NAME_SENT); root.addFolder(BluetoothMapContract.FOLDER_NAME_DELETED); } - /** - * Add SMS / MMS Base folders - */ + /** Add SMS / MMS Base folders */ private void addSmsMmsFolders(BluetoothMapFolderElement root) { - root.addSmsMmsFolder(BluetoothMapContract.FOLDER_NAME_INBOX); // root/telecom/msg/inbox + root.addSmsMmsFolder(BluetoothMapContract.FOLDER_NAME_INBOX); // root/telecom/msg/inbox root.addSmsMmsFolder(BluetoothMapContract.FOLDER_NAME_OUTBOX); root.addSmsMmsFolder(BluetoothMapContract.FOLDER_NAME_SENT); root.addSmsMmsFolder(BluetoothMapContract.FOLDER_NAME_DELETED); root.addSmsMmsFolder(BluetoothMapContract.FOLDER_NAME_DRAFT); } - private void addImFolders(BluetoothMapFolderElement root) throws RemoteException { // Select all parent folders - root.addImFolder(BluetoothMapContract.FOLDER_NAME_INBOX, - BluetoothMapContract.FOLDER_ID_INBOX); // root/telecom/msg/inbox - root.addImFolder(BluetoothMapContract.FOLDER_NAME_OUTBOX, - BluetoothMapContract.FOLDER_ID_OUTBOX); - root.addImFolder(BluetoothMapContract.FOLDER_NAME_SENT, - BluetoothMapContract.FOLDER_ID_SENT); - root.addImFolder(BluetoothMapContract.FOLDER_NAME_DELETED, - BluetoothMapContract.FOLDER_ID_DELETED); - root.addImFolder(BluetoothMapContract.FOLDER_NAME_DRAFT, - BluetoothMapContract.FOLDER_ID_DRAFT); + root.addImFolder( + BluetoothMapContract.FOLDER_NAME_INBOX, + BluetoothMapContract.FOLDER_ID_INBOX); // root/telecom/msg/inbox + root.addImFolder( + BluetoothMapContract.FOLDER_NAME_OUTBOX, BluetoothMapContract.FOLDER_ID_OUTBOX); + root.addImFolder( + BluetoothMapContract.FOLDER_NAME_SENT, BluetoothMapContract.FOLDER_ID_SENT); + root.addImFolder( + BluetoothMapContract.FOLDER_NAME_DELETED, BluetoothMapContract.FOLDER_ID_DELETED); + root.addImFolder( + BluetoothMapContract.FOLDER_NAME_DRAFT, BluetoothMapContract.FOLDER_ID_DRAFT); } /** - * Recursively adds folders based on the folders in the email content provider. - * Add a content observer? - to refresh the folder list if any change occurs. - * Consider simply deleting the entire table, and then rebuild using - * buildFolderStructure() - * WARNING: there is no way to notify the client about these changes - hence - * we need to either keep the folder structure constant, disconnect or fail anything - * referring to currentFolder. - * It is unclear what to set as current folder to be able to go one level up... - * The best solution would be to keep the folder structure constant during a connection. + * Recursively adds folders based on the folders in the email content provider. Add a content + * observer? - to refresh the folder list if any change occurs. Consider simply deleting the + * entire table, and then rebuild using buildFolderStructure() WARNING: there is no way to + * notify the client about these changes - hence we need to either keep the folder structure + * constant, disconnect or fail anything referring to currentFolder. It is unclear what to set + * as current folder to be able to go one level up... The best solution would be to keep the + * folder structure constant during a connection. + * * @param parentFolder the parent folder to which subFolders needs to be added. The - * folder.getFolderId() will be used to query sub-folders. - * Use a parentFolder with id -1 to get all folders from root. + * folder.getFolderId() will be used to query sub-folders. Use a parentFolder with id -1 to + * get all folders from root. */ @VisibleForTesting void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException { // Select all parent folders BluetoothMapFolderElement newFolder; - String where = BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + " = " - + parentFolder.getFolderId(); - Cursor c = mProviderClient.query(mEmailFolderUri, BluetoothMapContract.BT_FOLDER_PROJECTION, - where, null, null); + String where = + BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + + " = " + + parentFolder.getFolderId(); + Cursor c = + mProviderClient.query( + mEmailFolderUri, + BluetoothMapContract.BT_FOLDER_PROJECTION, + where, + null, + null); try { if (c != null) { c.moveToPosition(-1); @@ -326,7 +329,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { Log.d(TAG, "onConnect():"); logHeader(request); mThreadIdSupport = false; // Always assume not supported at new connect. - //always assume version 1.0 to start with + // always assume version 1.0 to start with mMessageVersion = BluetoothMapUtils.MAP_V10_STR; notifyUpdateWakeLock(); Long threadedMailKey = null; @@ -466,12 +469,16 @@ public class BluetoothMapObexServer extends ServerRequestHandler { Log.v(TAG, "TYPE_MESSAGE_UPDATE:"); return updateInbox(); } else if (type.equals(TYPE_SET_NOTIFICATION_REGISTRATION)) { - Log.v(TAG, "TYPE_SET_NOTIFICATION_REGISTRATION: NotificationStatus: " - + appParams.getNotificationStatus()); + Log.v( + TAG, + "TYPE_SET_NOTIFICATION_REGISTRATION: NotificationStatus: " + + appParams.getNotificationStatus()); return mObserver.setNotificationRegistration(appParams.getNotificationStatus()); } else if (type.equals(TYPE_SET_NOTIFICATION_FILTER)) { - Log.v(TAG, "TYPE_SET_NOTIFICATION_FILTER: NotificationFilter: " - + appParams.getNotificationFilter()); + Log.v( + TAG, + "TYPE_SET_NOTIFICATION_FILTER: NotificationFilter: " + + appParams.getNotificationFilter()); if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); ContentProfileErrorReportUtils.report( @@ -525,12 +532,19 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } return pushMessage(op, name, appParams, mMessageVersion); } else if (type.equals(TYPE_SET_OWNER_STATUS)) { - Log.v(TAG, "TYPE_SET_OWNER_STATUS:" + " PresenceAvailability " - + appParams.getPresenceAvailability() + ", PresenceStatus: " + appParams - .getPresenceStatus() + ", LastActivity: " - + appParams.getLastActivityString() + ", ChatStatus: " - + appParams.getChatState() + ", ChatStatusConvoId: " - + appParams.getChatStateConvoIdString()); + Log.v( + TAG, + "TYPE_SET_OWNER_STATUS:" + + " PresenceAvailability " + + appParams.getPresenceAvailability() + + ", PresenceStatus: " + + appParams.getPresenceStatus() + + ", LastActivity: " + + appParams.getLastActivityString() + + ", ChatStatus: " + + appParams.getChatState() + + ", ChatStatusConvoId: " + + appParams.getChatStateConvoIdString()); return setOwnerStatus(appParams); } @@ -540,7 +554,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 7); - //reload the providerClient and return error + // reload the providerClient and return error try { mProviderClient = acquireUnstableContentProviderOrThrow(); } catch (RemoteException e2) { @@ -549,7 +563,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 8); - //should not happen + // should not happen } return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } catch (Exception e) { @@ -574,8 +588,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { mCurrentFolder.getFolderByName(BluetoothMapContract.FOLDER_NAME_INBOX); if (inboxFolder != null) { long accountId = mAccountId; - Log.d(TAG, "updateInbox inbox=" + inboxFolder.getName() + "id=" - + inboxFolder.getFolderId()); + Log.d( + TAG, + "updateInbox inbox=" + + inboxFolder.getName() + + "id=" + + inboxFolder.getFolderId()); final Bundle extras = new Bundle(2); if (accountId != -1) { @@ -595,8 +613,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { Log.d(TAG, "updateInbox call()..."); Bundle myBundle = - mProviderClient.call(BluetoothMapContract.METHOD_UPDATE_FOLDER, null, - extras); + mProviderClient.call( + BluetoothMapContract.METHOD_UPDATE_FOLDER, null, extras); if (myBundle != null) { return ResponseCodes.OBEX_HTTP_OK; } else { @@ -643,23 +661,35 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (folderName == null || folderName.trim().isEmpty()) { folderElement = mCurrentFolder; - Log.d(TAG, "no folder name supplied, setting folder to current: " - + folderElement.getName()); + Log.d( + TAG, + "no folder name supplied, setting folder to current: " + + folderElement.getName()); } else { folderElement = mCurrentFolder.getSubFolder(folderName); if (folderElement != null) { - Log.d(TAG, "Folder name: " + folderName + " resulted in this element: " - + folderElement.getName()); + Log.d( + TAG, + "Folder name: " + + folderName + + " resulted in this element: " + + folderElement.getName()); } } return folderElement; } - private int pushMessage(final Operation op, String folderName, BluetoothMapAppParams appParams, + private int pushMessage( + final Operation op, + String folderName, + BluetoothMapAppParams appParams, String messageVersion) { if (appParams.getCharset() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) { - Log.d(TAG, "pushMessage: Missing charset - unable to decode message content. " - + "appParams.getCharset() = " + appParams.getCharset()); + Log.d( + TAG, + "pushMessage: Missing charset - unable to decode message content. " + + "appParams.getCharset() = " + + appParams.getCharset()); return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } InputStream bMsgStream = null; @@ -678,8 +708,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } if (!folderName.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX) && !folderName.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT)) { - Log.d(TAG, "pushMessage: Is only allowed to outbox and draft. " + "folderName=" - + folderName); + Log.d( + TAG, + "pushMessage: Is only allowed to outbox and draft. " + + "folderName=" + + folderName); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } @@ -692,8 +725,15 @@ public class BluetoothMapObexServer extends ServerRequestHandler { // Decode the messageBody message = BluetoothMapbMessage.parse(bMsgStream, appParams.getCharset()); message.setVersionString(messageVersion); - Log.d(TAG, "pushMessage: charset" + appParams.getCharset() + "folderId: " - + folderElement.getFolderId() + "Name: " + folderName + "TYPE: " + Log.d( + TAG, + "pushMessage: charset" + + appParams.getCharset() + + "folderId: " + + folderElement.getFolderId() + + "Name: " + + folderName + + "TYPE: " + message.getType()); if (message.getType().equals(TYPE.SMS_GSM) || message.getType().equals(TYPE.SMS_CDMA)) { // Convert messages to the default network type. @@ -754,7 +794,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 17); - //reload the providerClient and return error + // reload the providerClient and return error try { mProviderClient = acquireUnstableContentProviderOrThrow(); } catch (RemoteException e2) { @@ -825,7 +865,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (msgHandle == null) { return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } else if ((indicator == BluetoothMapAppParams.INVALID_VALUE_PARAMETER - || value == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) + || value == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) && extendedData == null) { return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } @@ -862,8 +902,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } if (indicator == BluetoothMapAppParams.STATUS_INDICATOR_DELETED) { - if (!mObserver.setMessageStatusDeleted(handle, msgType, mCurrentFolder, mBaseUriString, - value)) { + if (!mObserver.setMessageStatusDeleted( + handle, msgType, mCurrentFolder, mBaseUriString, value)) { Log.w(TAG, "setMessageStatusDeleted failed"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -898,8 +938,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } @VisibleForTesting - int setOwnerStatus(BluetoothMapAppParams appParams) - throws RemoteException { + int setOwnerStatus(BluetoothMapAppParams appParams) throws RemoteException { // This does only work for IM if (mAccount != null && mAccount.getType() == BluetoothMapUtils.TYPE.IM) { final Bundle extras = new Bundle(5); @@ -938,8 +977,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { Log.d(TAG, "setOwnerStatus call()..."); Bundle myBundle = - mProviderClient.call(BluetoothMapContract.METHOD_SET_OWNER_STATUS, null, - extras); + mProviderClient.call( + BluetoothMapContract.METHOD_SET_OWNER_STATUS, null, extras); if (myBundle != null) { return ResponseCodes.OBEX_HTTP_OK; } else { @@ -976,7 +1015,10 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } @Override - public int onSetPath(final HeaderSet request, final HeaderSet reply, final boolean backup, + public int onSetPath( + final HeaderSet request, + final HeaderSet reply, + final boolean backup, final boolean create) { String folderName; BluetoothMapFolderElement folder; @@ -994,8 +1036,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } logHeader(request); - Log.d(TAG, "onSetPath name is " + folderName + " backup: " + backup + " create: " - + create); + Log.d(TAG, "onSetPath name is " + folderName + " backup: " + backup + " create: " + create); if (backup) { if (mCurrentFolder.getParent() != null) { @@ -1029,7 +1070,6 @@ public class BluetoothMapObexServer extends ServerRequestHandler { msg.arg1 = mMasId; msg.sendToTarget(); Log.d(TAG, "onClose(): msg MSG_SERVERSESSION_CLOSE sent out."); - } if (mProviderClient != null) { mProviderClient.close(); @@ -1065,34 +1105,63 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (type.equals(TYPE_GET_FOLDER_LISTING)) { if (appParams != null) { - Log.v(TAG, "TYPE_GET_FOLDER_LISTING: MaxListCount = " - + appParams.getMaxListCount() + ", ListStartOffset = " - + appParams.getStartOffset()); + Log.v( + TAG, + "TYPE_GET_FOLDER_LISTING: MaxListCount = " + + appParams.getMaxListCount() + + ", ListStartOffset = " + + appParams.getStartOffset()); } // Block until all packets have been send. return sendFolderListingRsp(op, appParams); } else if (type.equals(TYPE_GET_MESSAGE_LISTING)) { name = (String) request.getHeader(HeaderSet.NAME); if (appParams != null) { - Log.v(TAG, "TYPE_GET_MESSAGE_LISTING: folder name is: " + name - + ", MaxListCount = " + appParams.getMaxListCount() - + ", ListStartOffset = " + appParams.getStartOffset()); - Log.v(TAG, "SubjectLength = " + appParams.getSubjectLength() - + ", ParameterMask = " + appParams.getParameterMask()); + Log.v( + TAG, + "TYPE_GET_MESSAGE_LISTING: folder name is: " + + name + + ", MaxListCount = " + + appParams.getMaxListCount() + + ", ListStartOffset = " + + appParams.getStartOffset()); + Log.v( + TAG, + "SubjectLength = " + + appParams.getSubjectLength() + + ", ParameterMask = " + + appParams.getParameterMask()); Log.v(TAG, "FilterMessageType = " + appParams.getFilterMessageType()); - Log.v(TAG, "FilterPeriodBegin = " + appParams.getFilterPeriodBeginString() - + ", FilterPeriodEnd = " + appParams.getFilterPeriodEndString() - + ", FilterReadStatus = " + appParams.getFilterReadStatus()); - Log.v(TAG, "FilterRecipient = " + appParams.getFilterRecipient() - + ", FilterOriginator = " + appParams.getFilterOriginator()); + Log.v( + TAG, + "FilterPeriodBegin = " + + appParams.getFilterPeriodBeginString() + + ", FilterPeriodEnd = " + + appParams.getFilterPeriodEndString() + + ", FilterReadStatus = " + + appParams.getFilterReadStatus()); + Log.v( + TAG, + "FilterRecipient = " + + appParams.getFilterRecipient() + + ", FilterOriginator = " + + appParams.getFilterOriginator()); Log.v(TAG, "FilterPriority = " + appParams.getFilterPriority()); long tmpLong = appParams.getFilterMsgHandle(); - Log.v(TAG, "FilterMsgHandle = " + ( - (tmpLong == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? "" - : Long.toHexString(tmpLong))); + Log.v( + TAG, + "FilterMsgHandle = " + + ((tmpLong == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) + ? "" + : Long.toHexString(tmpLong))); SignedLongLong tmpLongLong = appParams.getFilterConvoId(); - Log.v(TAG, "FilterConvoId = " + ((tmpLongLong == null) ? "" - : Long.toHexString(tmpLongLong.getLeastSignificantBits()))); + Log.v( + TAG, + "FilterConvoId = " + + ((tmpLongLong == null) + ? "" + : Long.toHexString( + tmpLongLong.getLeastSignificantBits()))); } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); @@ -1110,13 +1179,18 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } else if (type.equals(TYPE_GET_CONVO_LISTING)) { name = (String) request.getHeader(HeaderSet.NAME); if (appParams != null) { - Log.v(TAG, "TYPE_GET_CONVO_LISTING: name is" + name + ", MaxListCount = " - + appParams.getMaxListCount() + ", ListStartOffset = " - + appParams.getStartOffset()); - Log.v(TAG, "FilterLastActivityBegin = " - + appParams.getFilterLastActivityBegin()); - Log.v(TAG, "FilterLastActivityEnd = " - + appParams.getFilterLastActivityEnd()); + Log.v( + TAG, + "TYPE_GET_CONVO_LISTING: name is" + + name + + ", MaxListCount = " + + appParams.getMaxListCount() + + ", ListStartOffset = " + + appParams.getStartOffset()); + Log.v( + TAG, + "FilterLastActivityBegin = " + appParams.getFilterLastActivityBegin()); + Log.v(TAG, "FilterLastActivityEnd = " + appParams.getFilterLastActivityEnd()); Log.v(TAG, "FilterReadStatus = " + appParams.getFilterReadStatus()); Log.v(TAG, "FilterRecipient = " + appParams.getFilterRecipient()); } @@ -1134,18 +1208,25 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return sendConvoListingRsp(op, appParams); } else if (type.equals(TYPE_GET_MAS_INSTANCE_INFORMATION)) { if (appParams != null) { - Log.v(TAG, "TYPE_MESSAGE (GET): MASInstandeId = " - + appParams.getMasInstanceId()); + Log.v( + TAG, + "TYPE_MESSAGE (GET): MASInstandeId = " + appParams.getMasInstanceId()); } // Block until all packets have been send. return sendMASInstanceInformationRsp(op, appParams); } else if (type.equals(TYPE_MESSAGE)) { name = (String) request.getHeader(HeaderSet.NAME); if (appParams != null) { - Log.v(TAG, "TYPE_MESSAGE (GET): name is" + name + ", Attachment = " - + appParams.getAttachment() + ", Charset = " - + appParams.getCharset() + ", FractionRequest = " - + appParams.getFractionRequest()); + Log.v( + TAG, + "TYPE_MESSAGE (GET): name is" + + name + + ", Attachment = " + + appParams.getAttachment() + + ", Charset = " + + appParams.getCharset() + + ", FractionRequest = " + + appParams.getFractionRequest()); } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); @@ -1245,8 +1326,10 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } else { folderToList = getFolderElementFromName(folderName); if (folderToList == null) { - Log.w(TAG, "sendMessageListingRsp: folderToList == " - + "null-sending OBEX_HTTP_BAD_REQUEST"); + Log.w( + TAG, + "sendMessageListingRsp: folderToList == " + + "null-sending OBEX_HTTP_BAD_REQUEST"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, @@ -1254,9 +1337,14 @@ public class BluetoothMapObexServer extends ServerRequestHandler { 40); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } - Log.v(TAG, "sendMessageListingRsp: has sms " + folderToList.hasSmsMmsContent() - + ", has email " + folderToList.hasEmailContent() + ", has IM " - + folderToList.hasImContent()); + Log.v( + TAG, + "sendMessageListingRsp: has sms " + + folderToList.hasSmsMmsContent() + + ", has email " + + folderToList.hasEmailContent() + + ", has IM " + + folderToList.hasImContent()); } try { @@ -1274,8 +1362,9 @@ public class BluetoothMapObexServer extends ServerRequestHandler { // Generate the byte stream outAppParams.setMessageListingSize(outList.getCount()); String version; - if (0 < (mRemoteFeatureMask - & BluetoothMapUtils.MAP_FEATURE_MESSAGE_LISTING_FORMAT_V11_BIT)) { + if (0 + < (mRemoteFeatureMask + & BluetoothMapUtils.MAP_FEATURE_MESSAGE_LISTING_FORMAT_V11_BIT)) { version = BluetoothMapUtils.MAP_V11_STR; } else { version = BluetoothMapUtils.MAP_V10_STR; @@ -1346,8 +1435,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 43); - Log.w(TAG, "sendMessageListingRsp: IllegalArgumentException" - + " - sending OBEX_HTTP_BAD_REQUEST", e); + Log.w( + TAG, + "sendMessageListingRsp: IllegalArgumentException" + + " - sending OBEX_HTTP_BAD_REQUEST", + e); if (outStream != null) { try { outStream.close(); @@ -1396,8 +1488,10 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } if (bytesWritten != outBytes.length && !mIsAborted) { - Log.w(TAG, "sendMessageListingRsp: bytesWritten != outBytes.length" - + " - sending OBEX_HTTP_BAD_REQUEST"); + Log.w( + TAG, + "sendMessageListingRsp: bytesWritten != outBytes.length" + + " - sending OBEX_HTTP_BAD_REQUEST"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, @@ -1464,23 +1558,20 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } /** - * Generate and send the Conversation listing response based on an application - * parameter header. This function call will block until complete or aborted - * by the peer. Fragmentation of packets larger than the obex packet size - * will be handled by this function. + * Generate and send the Conversation listing response based on an application parameter header. + * This function call will block until complete or aborted by the peer. Fragmentation of packets + * larger than the obex packet size will be handled by this function. * - * @param op - * The OBEX operation. - * @param appParams - * The application parameter header - * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or - * {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. + * @param op The OBEX operation. + * @param appParams The application parameter header + * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or {@link + * ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. */ private int sendConvoListingRsp(Operation op, BluetoothMapAppParams appParams) { OutputStream outStream = null; byte[] outBytes = null; int maxChunkSize, bytesToWrite, bytesWritten = 0; - //boolean hasUnread = false; + // boolean hasUnread = false; HeaderSet replyHeaders = new HeaderSet(); BluetoothMapAppParams outAppParams = new BluetoothMapAppParams(); BluetoothMapConvoListing outList; @@ -1520,15 +1611,20 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } // Force update of version counter if needed mObserver.refreshConvoListVersionCounter(); - if (0 < (mRemoteFeatureMask - & BluetoothMapUtils.MAP_FEATURE_CONVERSATION_VERSION_COUNTER_BIT)) { + if (0 + < (mRemoteFeatureMask + & BluetoothMapUtils.MAP_FEATURE_CONVERSATION_VERSION_COUNTER_BIT)) { outAppParams.setConvoListingVerCounter( mMasInstance.getCombinedConvoListVersionCounter(), 0); } op.noBodyHeader(); } - Log.d(TAG, "outList size:" + outList.getCount() + " MaxListCount: " - + appParams.getMaxListCount()); + Log.d( + TAG, + "outList size:" + + outList.getCount() + + " MaxListCount: " + + appParams.getMaxListCount()); outList = null; // We don't need it anymore - we might as well give it up for GC outAppParams.setDatabaseIdentifier(0, mMasInstance.getDbIdentifier()); @@ -1572,8 +1668,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 51); - Log.w(TAG, "sendConvoListingRsp: IllegalArgumentException" - + " - sending OBEX_HTTP_BAD_REQUEST", e); + Log.w( + TAG, + "sendConvoListingRsp: IllegalArgumentException" + + " - sending OBEX_HTTP_BAD_REQUEST", + e); if (outStream != null) { try { outStream.close(); @@ -1616,8 +1715,10 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } if (bytesWritten != outBytes.length && !mIsAborted) { - Log.w(TAG, "sendConvoListingRsp: bytesWritten != outBytes.length" - + " - sending OBEX_HTTP_BAD_REQUEST"); + Log.w( + TAG, + "sendConvoListingRsp: bytesWritten != outBytes.length" + + " - sending OBEX_HTTP_BAD_REQUEST"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, @@ -1700,8 +1801,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 56); - Log.w(TAG, "sendFolderListingRsp: IOException" - + " - sending OBEX_HTTP_BAD_REQUEST Exception:", e1); + Log.w( + TAG, + "sendFolderListingRsp: IOException" + + " - sending OBEX_HTTP_BAD_REQUEST Exception:", + e1); if (outStream != null) { try { outStream.close(); @@ -1727,8 +1831,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 58); - Log.w(TAG, "sendFolderListingRsp: IllegalArgumentException" - + " - sending OBEX_HTTP_BAD_REQUEST Exception:", e1); + Log.w( + TAG, + "sendFolderListingRsp: IllegalArgumentException" + + " - sending OBEX_HTTP_BAD_REQUEST Exception:", + e1); if (outStream != null) { try { outStream.close(); @@ -1776,8 +1883,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } } - Log.v(TAG, - "sendFolderList sent " + bytesWritten + " bytes out of " + outBytes.length); + Log.v(TAG, "sendFolderList sent " + bytesWritten + " bytes out of " + outBytes.length); if (bytesWritten == outBytes.length || mIsAborted) { return ResponseCodes.OBEX_HTTP_OK; } else { @@ -1807,8 +1913,10 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (mMasId == appParams.getMasInstanceId()) { if (mAccount != null) { if (mAccount.getType() == TYPE.EMAIL) { - outString = (mAccount.getName() != null) ? mAccount.getName() - : BluetoothMapMasInstance.TYPE_EMAIL_STR; + outString = + (mAccount.getName() != null) + ? mAccount.getName() + : BluetoothMapMasInstance.TYPE_EMAIL_STR; } else if (mAccount.getType() == TYPE.IM) { outString = mAccount.getUciFull(); if (outString == null) { @@ -1838,8 +1946,9 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } /* Ensure byte array max length is 200 containing valid UTF-8 characters */ - outBytes = BluetoothMapUtils.truncateUtf8StringToBytearray(outString, - MAS_INSTANCE_INFORMATION_LENGTH); + outBytes = + BluetoothMapUtils.truncateUtf8StringToBytearray( + outString, MAS_INSTANCE_INFORMATION_LENGTH); // Open the OBEX body stream outStream = op.openOutputStream(); @@ -1850,8 +1959,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 62); - Log.w(TAG, "sendMASInstanceInformationRsp: IOException" - + " - sending OBEX_HTTP_BAD_REQUEST", e); + Log.w( + TAG, + "sendMASInstanceInformationRsp: IOException" + + " - sending OBEX_HTTP_BAD_REQUEST", + e); if (mIsAborted) { Log.d(TAG, "sendMASInstanceInformationRsp Operation Aborted"); return ResponseCodes.OBEX_HTTP_OK; @@ -1891,8 +2003,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } } - Log.v(TAG, "sendMASInstanceInformationRsp sent " + bytesWritten + " bytes out of " - + outBytes.length); + Log.v( + TAG, + "sendMASInstanceInformationRsp sent " + + bytesWritten + + " bytes out of " + + outBytes.length); if (bytesWritten == outBytes.length || mIsAborted) { return ResponseCodes.OBEX_HTTP_OK; } else { @@ -1903,22 +2019,18 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } /** - * Generate and send the get message response based on an application - * parameter header and a handle. + * Generate and send the get message response based on an application parameter header and a + * handle. * - * @param op - * The OBEX operation. - * @param handle - * The handle of the requested message - * @param appParams - * The application parameter header - * @param version - * The string representation of the version number(i.e. "1.0") - * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or - * {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. + * @param op The OBEX operation. + * @param handle The handle of the requested message + * @param appParams The application parameter header + * @param version The string representation of the version number(i.e. "1.0") + * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or {@link + * ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. */ - private int sendGetMessageRsp(Operation op, String handle, BluetoothMapAppParams appParams, - String version) { + private int sendGetMessageRsp( + Operation op, String handle, BluetoothMapAppParams appParams, String version) { OutputStream outStream = null; byte[] outBytes = null; int maxChunkSize, bytesToWrite, bytesWritten = 0; @@ -1928,18 +2040,20 @@ public class BluetoothMapObexServer extends ServerRequestHandler { // If it is a fraction request of Email message, set header before responding if ((BluetoothMapUtils.getMsgTypeFromHandle(handle).equals(TYPE.EMAIL) - || (BluetoothMapUtils.getMsgTypeFromHandle(handle).equals(TYPE.IM))) && ( - appParams.getFractionRequest() + || (BluetoothMapUtils.getMsgTypeFromHandle(handle).equals(TYPE.IM))) + && (appParams.getFractionRequest() == BluetoothMapAppParams.FRACTION_REQUEST_FIRST)) { BluetoothMapAppParams outAppParams = new BluetoothMapAppParams(); HeaderSet replyHeaders = new HeaderSet(); outAppParams.setFractionDeliver(BluetoothMapAppParams.FRACTION_DELIVER_LAST); // Build and set the application parameter header - replyHeaders.setHeader(HeaderSet.APPLICATION_PARAMETER, - outAppParams.encodeParams()); + replyHeaders.setHeader( + HeaderSet.APPLICATION_PARAMETER, outAppParams.encodeParams()); op.sendHeaders(replyHeaders); - Log.v(TAG, "sendGetMessageRsp fractionRequest - " - + "set FRACTION_DELIVER_LAST header"); + Log.v( + TAG, + "sendGetMessageRsp fractionRequest - " + + "set FRACTION_DELIVER_LAST header"); } outStream = op.openOutputStream(); @@ -1975,8 +2089,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 67); - Log.w(TAG, "sendGetMessageRsp: IllegalArgumentException (e.g. invalid handle) - " - + "sending OBEX_HTTP_BAD_REQUEST", e); + Log.w( + TAG, + "sendGetMessageRsp: IllegalArgumentException (e.g. invalid handle) - " + + "sending OBEX_HTTP_BAD_REQUEST", + e); if (outStream != null) { try { outStream.close(); @@ -2057,17 +2174,26 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } Log.d(TAG, "type = " + type + ", name = " + name); if (type.equals(TYPE_SET_NOTIFICATION_FILTER)) { - Log.v(TAG, "TYPE_SET_NOTIFICATION_FILTER: NotificationFilter: " - + appParams.getNotificationFilter()); + Log.v( + TAG, + "TYPE_SET_NOTIFICATION_FILTER: NotificationFilter: " + + appParams.getNotificationFilter()); mObserver.setNotificationFilter(appParams.getNotificationFilter()); return ResponseCodes.OBEX_HTTP_OK; } else if (type.equals(TYPE_SET_OWNER_STATUS)) { - Log.v(TAG, "TYPE_SET_OWNER_STATUS:" + " PresenceAvailability " - + appParams.getPresenceAvailability() + ", PresenceStatus: " + appParams - .getPresenceStatus() + ", LastActivity: " - + appParams.getLastActivityString() + ", ChatStatus: " - + appParams.getChatState() + ", ChatStatusConvoId: " - + appParams.getChatStateConvoIdString()); + Log.v( + TAG, + "TYPE_SET_OWNER_STATUS:" + + " PresenceAvailability " + + appParams.getPresenceAvailability() + + ", PresenceStatus: " + + appParams.getPresenceStatus() + + ", LastActivity: " + + appParams.getLastActivityString() + + ", ChatStatus: " + + appParams.getChatState() + + ", ChatStatusConvoId: " + + appParams.getChatStateConvoIdString()); return setOwnerStatus(appParams); } @@ -2077,7 +2203,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 71); - //reload the providerClient and return error + // reload the providerClient and return error try { mProviderClient = acquireUnstableContentProviderOrThrow(); } catch (RemoteException e2) { @@ -2086,7 +2212,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 72); - //should not happen + // should not happen } return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } catch (Exception e) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java index 33d7b04272e..fc2c241dec3 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; @@ -74,27 +74,21 @@ public class BluetoothMapService extends ProfileService { private static final String TAG = "BluetoothMapService"; /** - * To enable MAP DEBUG/VERBOSE logging - run below cmd in adb shell, and - * restart com.android.bluetooth process. only enable DEBUG log: - * "setprop log.tag.BluetoothMapService DEBUG"; enable both VERBOSE and - * DEBUG log: "setprop log.tag.BluetoothMapService VERBOSE" + * To enable MAP DEBUG/VERBOSE logging - run below cmd in adb shell, and restart + * com.android.bluetooth process. only enable DEBUG log: "setprop log.tag.BluetoothMapService + * DEBUG"; enable both VERBOSE and DEBUG log: "setprop log.tag.BluetoothMapService VERBOSE" */ - - - /** - * The component names for the owned provider and activity - */ + /** The component names for the owned provider and activity */ private static final String MAP_SETTINGS_ACTIVITY = BluetoothMapSettings.class.getCanonicalName(); + private static final String MAP_FILE_PROVIDER = MmsFileProvider.class.getCanonicalName(); - /** - * Intent indicating timeout for user confirmation, which is sent to - * BluetoothMapActivity - */ + /** Intent indicating timeout for user confirmation, which is sent to BluetoothMapActivity */ public static final String USER_CONFIRM_TIMEOUT_ACTION = "com.android.bluetooth.map.USER_CONFIRM_TIMEOUT"; + private static final int USER_CONFIRM_TIMEOUT_VALUE = 25000; static final int MSG_SERVERSESSION_CLOSE = 5000; @@ -108,12 +102,10 @@ public class BluetoothMapService extends ProfileService { static final int MSG_OBSERVER_REGISTRATION = 5008; private static final int START_LISTENER = 1; - @VisibleForTesting - static final int USER_TIMEOUT = 2; + @VisibleForTesting static final int USER_TIMEOUT = 2; private static final int DISCONNECT_MAP = 3; private static final int SHUTDOWN = 4; - @VisibleForTesting - static final int UPDATE_MAS_INSTANCES = 5; + @VisibleForTesting static final int UPDATE_MAS_INSTANCES = 5; private static final int RELEASE_WAKE_LOCK_DELAY = 10000; private PowerManager.WakeLock mWakeLock = null; @@ -154,8 +146,7 @@ public class BluetoothMapService extends ProfileService { private boolean mAccountChanged = false; private boolean mSdpSearchInitiated = false; private SdpMnsRecord mMnsRecord = null; - @VisibleForTesting - Handler mSessionStatusHandler; + @VisibleForTesting Handler mSessionStatusHandler; private boolean mServiceStarted = false; private static BluetoothMapService sBluetoothMapService; @@ -163,7 +154,7 @@ public class BluetoothMapService extends ProfileService { private boolean mSmsCapable = true; private static final ParcelUuid[] MAP_UUIDS = { - BluetoothUuid.MAP, BluetoothUuid.MNS, + BluetoothUuid.MAP, BluetoothUuid.MNS, }; public static boolean isEnabled() { @@ -216,9 +207,7 @@ public class BluetoothMapService extends ProfileService { Log.v(TAG, "MAP Service closeService out"); } - /** - * Starts the Socket listener threads for each MAS - */ + /** Starts the Socket listener threads for each MAS */ private void startSocketListeners(int masId) { if (masId == -1) { for (int i = 0, c = mMasInstances.size(); i < c; i++) { @@ -239,9 +228,7 @@ public class BluetoothMapService extends ProfileService { } } - /** - * Start a MAS instance for SMS/MMS and each e-mail account. - */ + /** Start a MAS instance for SMS/MMS and each e-mail account. */ private void startObexServerSessions() { Log.d(TAG, "Map Service START ObexServerSessions()"); @@ -272,8 +259,11 @@ public class BluetoothMapService extends ProfileService { BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 1); - Log.w(TAG, "IOException occured while starting an obexServerSession restarting" - + " the listener", e); + Log.w( + TAG, + "IOException occured while starting an obexServerSession restarting" + + " the listener", + e); mMasInstances.valueAt(i).restartObexServerSession(); } catch (RemoteException e) { ContentProfileErrorReportUtils.report( @@ -281,8 +271,11 @@ public class BluetoothMapService extends ProfileService { BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 2); - Log.w(TAG, "RemoteException occured while starting an obexServerSession restarting" - + " the listener", e); + Log.w( + TAG, + "RemoteException occured while starting an obexServerSession restarting" + + " the listener", + e); mMasInstances.valueAt(i).restartObexServerSession(); } } @@ -304,6 +297,7 @@ public class BluetoothMapService extends ProfileService { /** * Restart a MAS instances. + * * @param masId use -1 to stop all instances */ private void stopObexServerSessions(int masId) { @@ -383,11 +377,13 @@ public class BluetoothMapService extends ProfileService { case USER_TIMEOUT: if (mIsWaitingAuthorization) { Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); - intent.setPackage(SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - getString(R.string.pairing_ui_package))); + intent.setPackage( + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, + getString(R.string.pairing_ui_package))); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, sRemoteDevice); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS); BluetoothMapService.this.sendBroadcast( intent, @@ -418,8 +414,10 @@ public class BluetoothMapService extends ProfileService { Log.v(TAG, "Acquire Wake Lock request message"); if (mWakeLock == null) { PowerManager pm = getSystemService(PowerManager.class); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "StartingObexMapTransaction"); + mWakeLock = + pm.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, + "StartingObexMapTransaction"); mWakeLock.setReferenceCounted(false); } if (!mWakeLock.isHeld()) { @@ -453,8 +451,12 @@ public class BluetoothMapService extends ProfileService { } break; case MSG_OBSERVER_REGISTRATION: - Log.d(TAG, "ContentObserver Registration MASID: " + msg.arg1 + " Enable: " - + msg.arg2); + Log.d( + TAG, + "ContentObserver Registration MASID: " + + msg.arg1 + + " Enable: " + + msg.arg2); BluetoothMapMasInstance masInst = mMasInstances.get(msg.arg1); if (masInst != null && masInst.mObserver != null) { try { @@ -489,8 +491,11 @@ public class BluetoothMapService extends ProfileService { Log.d(TAG, "mPermission = " + mPermission); if (mPermission == BluetoothDevice.ACCESS_ALLOWED) { try { - Log.v(TAG, "incoming connection accepted from: " + sRemoteDeviceName - + " automatically as trusted device"); + Log.v( + TAG, + "incoming connection accepted from: " + + sRemoteDeviceName + + " automatically as trusted device"); if (mBluetoothMnsObexClient != null && masInst != null) { masInst.startObexServerSession(mBluetoothMnsObexClient); } else { @@ -604,12 +609,13 @@ public class BluetoothMapService extends ProfileService { * Gets the connection state of MAP with the passed in device. * * @param device is the device whose connection state we are querying - * @return {@link BluetoothProfile#STATE_CONNECTED} if MAP is connected to this device, - * {@link BluetoothProfile#STATE_DISCONNECTED} otherwise + * @return {@link BluetoothProfile#STATE_CONNECTED} if MAP is connected to this device, {@link + * BluetoothProfile#STATE_DISCONNECTED} otherwise */ public int getConnectionState(BluetoothDevice device) { synchronized (this) { - if (getState() == BluetoothMap.STATE_CONNECTED && getRemoteDevice() != null + if (getState() == BluetoothMap.STATE_CONNECTED + && getRemoteDevice() != null && getRemoteDevice().equals(device)) { return BluetoothProfile.STATE_CONNECTED; } else { @@ -619,14 +625,13 @@ public class BluetoothMapService extends ProfileService { } /** - * Set connection policy of the profile and tries to disconnect it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and tries to disconnect it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -634,12 +639,12 @@ public class BluetoothMapService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.v(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.MAP, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.MAP, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { @@ -651,20 +656,18 @@ public class BluetoothMapService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) int getConnectionPolicy(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.MAP); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.MAP); } @Override @@ -676,8 +679,10 @@ public class BluetoothMapService extends ProfileService { public void start() { Log.d(TAG, "start()"); - mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), - "DatabaseManager cannot be null when MapService starts"); + mDatabaseManager = + Objects.requireNonNull( + AdapterService.getAdapterService().getDatabase(), + "DatabaseManager cannot be null when MapService starts"); setComponentAvailable(MAP_SETTINGS_ACTIVITY, true); setComponentAvailable(MAP_FILE_PROVIDER, true); @@ -718,7 +723,7 @@ public class BluetoothMapService extends ProfileService { mSmsCapable = tm.isSmsCapable(); mEnabledAccounts = mAppObserver.getEnabledAccountItems(); - createMasInstances(); // Uses mEnabledAccounts + createMasInstances(); // Uses mEnabledAccounts sendStartListenerMessage(-1); setBluetoothMapService(this); @@ -759,29 +764,22 @@ public class BluetoothMapService extends ProfileService { } /** - * Call this to trigger an update of the MAS instance list. - * No changes will be applied unless in disconnected state + * Call this to trigger an update of the MAS instance list. No changes will be applied unless in + * disconnected state */ void updateMasInstances(int action) { mSessionStatusHandler.obtainMessage(UPDATE_MAS_INSTANCES, action, 0).sendToTarget(); } /** - * Update the active MAS Instances according the difference between mEnabledDevices - * and the current list of accounts. - * Will only make changes if state is disconnected. + * Update the active MAS Instances according the difference between mEnabledDevices and the + * current list of accounts. Will only make changes if state is disconnected. * - * How it works: - * 1) Build two lists of accounts - * newAccountList - all accounts from mAppObserver - * newAccounts - accounts that have been enabled since mEnabledAccounts - * was last updated. - * mEnabledAccounts - The accounts which are left - * 2) Stop and remove all MasInstances in mEnabledAccounts - * 3) Add and start MAS instances for accounts on the new list. - * Called at: - * - Each change in accounts - * - Each disconnect - before MasInstances restart. + *

How it works: 1) Build two lists of accounts newAccountList - all accounts from + * mAppObserver newAccounts - accounts that have been enabled since mEnabledAccounts was last + * updated. mEnabledAccounts - The accounts which are left 2) Stop and remove all MasInstances + * in mEnabledAccounts 3) Add and start MAS instances for accounts on the new list. Called at: - + * Each change in accounts - Each disconnect - before MasInstances restart. */ private void updateMasInstancesHandler() { Log.d(TAG, "updateMasInstancesHandler() state = " + getState()); @@ -846,8 +844,9 @@ public class BluetoothMapService extends ProfileService { } /** - * Return a free key greater than the largest key in use. - * If the key 255 is in use, the first free masId will be returned. + * Return a free key greater than the largest key in use. If the key 255 is in use, the first + * free masId will be returned. + * * @return a free MasId */ @VisibleForTesting @@ -949,8 +948,12 @@ public class BluetoothMapService extends ProfileService { mSdpSearchInitiated = true; } } else if (!sRemoteDevice.equals(remoteDevice)) { - Log.w(TAG, "Unexpected connection from a second Remote Device received. name: " + ( - (remoteDevice == null) ? "unknown" : Utils.getName(remoteDevice))); + Log.w( + TAG, + "Unexpected connection from a second Remote Device received. name: " + + ((remoteDevice == null) + ? "unknown" + : Utils.getName(remoteDevice))); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, @@ -958,16 +961,16 @@ public class BluetoothMapService extends ProfileService { 10); return false; } // Else second connection to same device, just continue - } if (sendIntent) { // This will trigger Settings app's dialog. Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); - intent.setPackage(SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - getString(R.string.pairing_ui_package))); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + intent.setPackage( + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, getString(R.string.pairing_ui_package))); + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, sRemoteDevice); sendOrderedBroadcast( @@ -981,8 +984,8 @@ public class BluetoothMapService extends ProfileService { null); Log.v(TAG, "waiting for authorization for connection from: " + sRemoteDeviceName); - //Queue USER_TIMEOUT to disconnect MAP OBEX session. If user doesn't - //accept or reject authorization request + // Queue USER_TIMEOUT to disconnect MAP OBEX session. If user doesn't + // accept or reject authorization request } else if (cancelConnection) { sendConnectCancelMessage(); } else if (mPermission == BluetoothDevice.ACCESS_ALLOWED) { @@ -1000,17 +1003,19 @@ public class BluetoothMapService extends ProfileService { } mRemoveTimeoutMsg = true; Intent timeoutIntent = new Intent(USER_CONFIRM_TIMEOUT_ACTION); - PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, timeoutIntent, - PendingIntent.FLAG_IMMUTABLE); - mAlarmManager.set(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + USER_CONFIRM_TIMEOUT_VALUE, pIntent); + PendingIntent pIntent = + PendingIntent.getBroadcast(this, 0, timeoutIntent, PendingIntent.FLAG_IMMUTABLE); + mAlarmManager.set( + AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + USER_CONFIRM_TIMEOUT_VALUE, + pIntent); } private void cancelUserTimeoutAlarm() { Log.d(TAG, "cancelUserTimeOutAlarm()"); Intent timeoutIntent = new Intent(USER_CONFIRM_TIMEOUT_ACTION); - PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, timeoutIntent, - PendingIntent.FLAG_IMMUTABLE); + PendingIntent pIntent = + PendingIntent.getBroadcast(this, 0, timeoutIntent, PendingIntent.FLAG_IMMUTABLE); pIntent.cancel(); AlarmManager alarmManager = this.getSystemService(AlarmManager.class); @@ -1020,6 +1025,7 @@ public class BluetoothMapService extends ProfileService { /** * Start the incoming connection listeners for a MAS ID + * * @param masId the MasID to start. Use -1 to start all listeners. */ void sendStartListenerMessage(int masId) { @@ -1114,13 +1120,19 @@ public class BluetoothMapService extends ProfileService { sendConnectTimeoutMessage(); } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) { - int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, - BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); - - Log.d(TAG, "Received ACTION_CONNECTION_ACCESS_REPLY:" + requestType - + "isWaitingAuthorization:" + mIsWaitingAuthorization); - if ((!mIsWaitingAuthorization) || (requestType - != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS)) { + int requestType = + intent.getIntExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); + + Log.d( + TAG, + "Received ACTION_CONNECTION_ACCESS_REPLY:" + + requestType + + "isWaitingAuthorization:" + + mIsWaitingAuthorization); + if ((!mIsWaitingAuthorization) + || (requestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS)) { return; } @@ -1131,16 +1143,17 @@ public class BluetoothMapService extends ProfileService { setState(BluetoothMap.STATE_DISCONNECTED); } - if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, - BluetoothDevice.CONNECTION_ACCESS_NO) + if (intent.getIntExtra( + BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, + BluetoothDevice.CONNECTION_ACCESS_NO) == BluetoothDevice.CONNECTION_ACCESS_YES) { // Bluetooth connection accepted by user mPermission = BluetoothDevice.ACCESS_ALLOWED; if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { - boolean result = sRemoteDevice.setMessageAccessPermission( - BluetoothDevice.ACCESS_ALLOWED); - Log.d(TAG, - "setMessageAccessPermission(ACCESS_ALLOWED) result=" + result); + boolean result = + sRemoteDevice.setMessageAccessPermission( + BluetoothDevice.ACCESS_ALLOWED); + Log.d(TAG, "setMessageAccessPermission(ACCESS_ALLOWED) result=" + result); } sRemoteDevice.sdpSearch(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS); @@ -1150,10 +1163,10 @@ public class BluetoothMapService extends ProfileService { // call stop anyway to restart listener. mPermission = BluetoothDevice.ACCESS_REJECTED; if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { - boolean result = sRemoteDevice.setMessageAccessPermission( - BluetoothDevice.ACCESS_REJECTED); - Log.d(TAG, - "setMessageAccessPermission(ACCESS_REJECTED) result=" + result); + boolean result = + sRemoteDevice.setMessageAccessPermission( + BluetoothDevice.ACCESS_REJECTED); + Log.d(TAG, "setMessageAccessPermission(ACCESS_REJECTED) result=" + result); } sendConnectCancelMessage(); } @@ -1163,15 +1176,15 @@ public class BluetoothMapService extends ProfileService { if (mSmsCapable && mMasInstances != null) { BluetoothMapMasInstance masInst = mMasInstances.get(MAS_ID_SMS_MMS); if (masInst != null) { - intent.putExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, - result); + intent.putExtra( + BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, result); handled = masInst.handleSmsSendIntent(context, intent); } } if (!handled) { // Move the SMS to the correct folder. - BluetoothMapContentObserver.actionMessageSentDisconnected(context, intent, - result); + BluetoothMapContentObserver.actionMessageSentDisconnected( + context, intent, result); } } } @@ -1211,9 +1224,7 @@ public class BluetoothMapService extends ProfileService { private void handleSdpSearchRecordReceived(int status, Parcelable record, ParcelUuid uuid) { Log.d(TAG, "Received ACTION_SDP_RECORD."); Log.v(TAG, "Received UUID: " + uuid.toString()); - Log.v( - TAG, - "expected UUID: " + BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS.toString()); + Log.v(TAG, "expected UUID: " + BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS.toString()); if (uuid.equals(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS)) { mMnsRecord = (SdpMnsRecord) record; Log.v(TAG, " -> MNS Record:" + mMnsRecord); @@ -1235,15 +1246,14 @@ public class BluetoothMapService extends ProfileService { } } - //Binder object: Must be static class or memory leak may occur + // Binder object: Must be static class or memory leak may occur /** * This class implements the IBluetoothMap interface - or actually it validates the * preconditions for calling the actual functionality in the MapService, and calls it. */ @VisibleForTesting - static class BluetoothMapBinder extends IBluetoothMap.Stub - implements IProfileServiceBinder { + static class BluetoothMapBinder extends IBluetoothMap.Stub implements IProfileServiceBinder { private BluetoothMapService mService; @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java index e7e5be2e2f2..e8509cc564b 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; @@ -41,16 +41,13 @@ public class BluetoothMapSettings extends Activity { /* create structure for list of groups + items*/ mGroups = mLoader.parsePackages(true); - /* update expandable listview with correct items */ ExpandableListView listView = (ExpandableListView) findViewById(R.id.bluetooth_map_settings_list_view); BluetoothMapSettingsAdapter adapter = - new BluetoothMapSettingsAdapter(this, listView, mGroups, - mLoader.getAccountsEnabledCount()); + new BluetoothMapSettingsAdapter( + this, listView, mGroups, mLoader.getAccountsEnabledCount()); listView.setAdapter(adapter); } - - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java index 02e7936d4c8..1d931ca4203 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; @@ -55,8 +55,9 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { /* number of accounts possible to share */ private int mSlotsLeft = 10; - - public BluetoothMapSettingsAdapter(Activity act, ExpandableListView listView, + public BluetoothMapSettingsAdapter( + Activity act, + ExpandableListView listView, LinkedHashMap> groupsList, int enabledAccountsCounts) { mActivity = act; @@ -65,21 +66,20 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { mGroupStatus = new int[groupsList.size()]; mSlotsLeft = mSlotsLeft - enabledAccountsCounts; - listView.setOnGroupExpandListener(new OnGroupExpandListener() { - - @Override - public void onGroupExpand(int groupPosition) { - BluetoothMapAccountItem group = mMainGroup.get(groupPosition); - if (mProupList.get(group).size() > 0) { - mGroupStatus[groupPosition] = 1; - } + listView.setOnGroupExpandListener( + new OnGroupExpandListener() { - } - }); + @Override + public void onGroupExpand(int groupPosition) { + BluetoothMapAccountItem group = mMainGroup.get(groupPosition); + if (mProupList.get(group).size() > 0) { + mGroupStatus[groupPosition] = 1; + } + } + }); mMainGroup = new ArrayList(); for (Map.Entry> mapEntry : - mProupList - .entrySet()) { + mProupList.entrySet()) { mMainGroup.add(mapEntry.getKey()); } } @@ -100,9 +100,12 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { } @Override - public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, - View convertView, ViewGroup parent) { - + public View getChildView( + final int groupPosition, + final int childPosition, + boolean isLastChild, + View convertView, + ViewGroup parent) { final ChildHolder holder; if (convertView == null) { @@ -116,77 +119,77 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { holder = (ChildHolder) convertView.getTag(); } final BluetoothMapAccountItem child = getChild(groupPosition, childPosition); - holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - BluetoothMapAccountItem parentGroup = - (BluetoothMapAccountItem) getGroup(groupPosition); - boolean oldIsChecked = child.mIsChecked; // needed to prevent updates on UI redraw - child.mIsChecked = isChecked; - if (isChecked) { - ArrayList childList = getChild(parentGroup); - int childIndex = childList.indexOf(child); - boolean isAllChildClicked = true; - if (mSlotsLeft - childList.size() >= 0) { - - for (int i = 0; i < childList.size(); i++) { - if (i != childIndex) { - BluetoothMapAccountItem siblings = childList.get(i); - if (!siblings.mIsChecked) { - isAllChildClicked = false; + holder.cb.setOnCheckedChangeListener( + new OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + BluetoothMapAccountItem parentGroup = + (BluetoothMapAccountItem) getGroup(groupPosition); + boolean oldIsChecked = + child.mIsChecked; // needed to prevent updates on UI redraw + child.mIsChecked = isChecked; + if (isChecked) { + ArrayList childList = getChild(parentGroup); + int childIndex = childList.indexOf(child); + boolean isAllChildClicked = true; + if (mSlotsLeft - childList.size() >= 0) { + + for (int i = 0; i < childList.size(); i++) { + if (i != childIndex) { + BluetoothMapAccountItem siblings = childList.get(i); + if (!siblings.mIsChecked) { + isAllChildClicked = false; + BluetoothMapSettingsDataHolder.sCheckedChilds.put( + child.getName(), parentGroup.getName()); + break; + } + } + } + } else { + showWarning( + mActivity.getString( + R.string + .bluetooth_map_settings_no_account_slots_left)); + isAllChildClicked = false; + child.mIsChecked = false; + } + if (isAllChildClicked) { + parentGroup.mIsChecked = true; + if (!(BluetoothMapSettingsDataHolder.sCheckedChilds.containsKey( + child.getName()))) { BluetoothMapSettingsDataHolder.sCheckedChilds.put( child.getName(), parentGroup.getName()); - break; - } + mCheckAll = false; + } + + } else { + if (parentGroup.mIsChecked) { + parentGroup.mIsChecked = false; + mCheckAll = false; + BluetoothMapSettingsDataHolder.sCheckedChilds.remove( + child.getName()); + } else { + mCheckAll = true; + BluetoothMapSettingsDataHolder.sCheckedChilds.remove( + child.getName()); } + // child.isChecked =false; } - } else { - showWarning(mActivity.getString( - R.string.bluetooth_map_settings_no_account_slots_left)); - isAllChildClicked = false; - child.mIsChecked = false; - } - if (isAllChildClicked) { - parentGroup.mIsChecked = true; - if (!(BluetoothMapSettingsDataHolder.sCheckedChilds.containsKey( - child.getName()))) { - BluetoothMapSettingsDataHolder.sCheckedChilds.put(child.getName(), - parentGroup.getName()); + notifyDataSetChanged(); + if (child.mIsChecked != oldIsChecked) { + updateAccount(child); } - mCheckAll = false; } - - - } else { - if (parentGroup.mIsChecked) { - parentGroup.mIsChecked = false; - mCheckAll = false; - BluetoothMapSettingsDataHolder.sCheckedChilds.remove(child.getName()); - } else { - mCheckAll = true; - BluetoothMapSettingsDataHolder.sCheckedChilds.remove(child.getName()); - } - // child.isChecked =false; - } - notifyDataSetChanged(); - if (child.mIsChecked != oldIsChecked) { - updateAccount(child); - } - - } - - }); + }); holder.cb.setChecked(child.mIsChecked); holder.title.setText(child.getName()); Log.v("children are", BluetoothMapSettingsDataHolder.sCheckedChilds.toString()); return convertView; - } - @Override public int getChildrenCount(int groupPosition) { BluetoothMapAccountItem item = mMainGroup.get(groupPosition); @@ -219,8 +222,8 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { } @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, - ViewGroup parent) { + public View getGroupView( + int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { final GroupHolder holder; @@ -231,8 +234,9 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { (CheckBox) convertView.findViewById(R.id.bluetooth_map_settings_group_checkbox); holder.imageView = (ImageView) convertView.findViewById(R.id.bluetooth_map_settings_group_icon); - holder.title = (TextView) convertView.findViewById( - R.id.bluetooth_map_settings_group_text_view); + holder.title = + (TextView) + convertView.findViewById(R.id.bluetooth_map_settings_group_text_view); convertView.setTag(holder); } else { holder = (GroupHolder) convertView.getTag(); @@ -241,47 +245,49 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { final BluetoothMapAccountItem groupItem = getGroup(groupPosition); holder.imageView.setImageDrawable(groupItem.getIcon()); - holder.title.setText(groupItem.getName()); - holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (mCheckAll) { - ArrayList childItem = getChild(groupItem); - for (BluetoothMapAccountItem children : childItem) { - boolean oldIsChecked = children.mIsChecked; - if (mSlotsLeft > 0) { - children.mIsChecked = isChecked; - if (oldIsChecked != children.mIsChecked) { - updateAccount(children); - } - } else { - showWarning(mActivity.getString( - R.string.bluetooth_map_settings_no_account_slots_left)); - isChecked = false; - } - } - } - groupItem.mIsChecked = isChecked; - notifyDataSetChanged(); - new Handler().postDelayed(new Runnable() { + holder.cb.setOnCheckedChangeListener( + new OnCheckedChangeListener() { @Override - public void run() { - if (!mCheckAll) { - mCheckAll = true; + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (mCheckAll) { + ArrayList childItem = getChild(groupItem); + for (BluetoothMapAccountItem children : childItem) { + boolean oldIsChecked = children.mIsChecked; + if (mSlotsLeft > 0) { + children.mIsChecked = isChecked; + if (oldIsChecked != children.mIsChecked) { + updateAccount(children); + } + } else { + showWarning( + mActivity.getString( + R.string + .bluetooth_map_settings_no_account_slots_left)); + isChecked = false; + } + } } + groupItem.mIsChecked = isChecked; + notifyDataSetChanged(); + new Handler() + .postDelayed( + new Runnable() { + + @Override + public void run() { + if (!mCheckAll) { + mCheckAll = true; + } + } + }, + 50); } - }, 50); - - } - - }); + }); holder.cb.setChecked(groupItem.mIsChecked); return convertView; - } @Override @@ -298,7 +304,6 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { public ImageView imageView; public CheckBox cb; public TextView title; - } private class ChildHolder { @@ -308,8 +313,12 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { public void updateAccount(BluetoothMapAccountItem account) { updateSlotCounter(account.mIsChecked); - Log.d(TAG, "Updating account settings for " + account.getName() + ". Value is:" - + account.mIsChecked); + Log.d( + TAG, + "Updating account settings for " + + account.getName() + + ". Value is:" + + account.mIsChecked); ContentResolver mResolver = mActivity.getContentResolver(); Uri uri = Uri.parse(account.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_ACCOUNT); @@ -317,7 +326,6 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, ((account.mIsChecked) ? 1 : 0)); values.put(BluetoothMapContract.AccountColumns._ID, account.getId()); // get title mResolver.update(uri, values, null, null); - } private void updateSlotCounter(boolean isChecked) { @@ -331,8 +339,10 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { if (mSlotsLeft <= 0) { text = mActivity.getString(R.string.bluetooth_map_settings_no_account_slots_left); } else { - text = mActivity.getString(R.string.bluetooth_map_settings_count) + " " - + String.valueOf(mSlotsLeft); + text = + mActivity.getString(R.string.bluetooth_map_settings_count) + + " " + + String.valueOf(mSlotsLeft); } int duration = Toast.LENGTH_SHORT; @@ -346,8 +356,5 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { Toast toast = Toast.makeText(mActivity, text, duration); toast.show(); - } - - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsDataHolder.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsDataHolder.java index f256b1ccb93..4c2220303ad 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsDataHolder.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsDataHolder.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; @@ -20,4 +20,3 @@ import java.util.HashMap; public class BluetoothMapSettingsDataHolder { public static HashMap sCheckedChilds = new HashMap(); } - diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java index 3caf39f05d2..ca1d4aec143 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; @@ -47,29 +47,22 @@ public class BluetoothMapSmsPdu { public static final int SMS_TYPE_GSM = 1; public static final int SMS_TYPE_CDMA = 2; - /** - * from SMS user data header information element identifiers. - * (see TS 23.040 9.2.3.24) - */ - private static final int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24; - private static final int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25; + /** from SMS user data header information element identifiers. (see TS 23.040 9.2.3.24) */ + private static final int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24; - /** - * Supported message types for CDMA SMS messages - * (See 3GPP2 C.S0015-B, v2.0, table 4.5.1-1) - */ + private static final int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25; + + /** Supported message types for CDMA SMS messages (See 3GPP2 C.S0015-B, v2.0, table 4.5.1-1) */ private static final int MESSAGE_TYPE_DELIVER = 0x01; /** - * We need to handle the SC-address mentioned in errata 4335. - * Since the definition could be read in three different ways, I have asked - * the car working group for clarification, and are awaiting confirmation that - * this clarification will go into the MAP spec: - * The native format should be where is <1..10 octet - * of address> coded according to 24.011. The IEI is not to be used, as the fixed order of - * the data makes a type 4 LV information element sufficient. is a single octet - * which value is the length of the value-field in octets including both the and the - *

. + * We need to handle the SC-address mentioned in errata 4335. Since the definition could be read + * in three different ways, I have asked the car working group for clarification, and are + * awaiting confirmation that this clarification will go into the MAP spec: The native format + * should be where is <1..10 octet of address> coded + * according to 24.011. The IEI is not to be used, as the fixed order of the data makes a type 4 + * LV information element sufficient. is a single octet which value is the length of + * the value-field in octets including both the and the
. */ public static class SmsPdu { private byte[] mData; @@ -96,6 +89,7 @@ public class BluetoothMapSmsPdu { /** * Create a pdu instance based on the data generated on this device. + * * @param data * @param encoding * @param type @@ -153,7 +147,6 @@ public class BluetoothMapSmsPdu { return mMsgSeptetCount; } - /* PDU parsing/modification functionality */ private static final byte ORIGINATING_ADDRESS = 0x02; private static final byte ORIGINATING_SUB_ADDRESS = 0x03; @@ -163,10 +156,11 @@ public class BluetoothMapSmsPdu { /** * Find and return the offset to the specified parameter ID + * * @param parameterId The parameter ID to find - * @return the offset in number of bytes to the parameterID entry in the pdu data. - * The byte at the offset contains the parameter ID, the byte following contains the - * parameter length, and offset + 2 is the first byte of the parameter data. + * @return the offset in number of bytes to the parameterID entry in the pdu data. The byte + * at the offset contains the parameter ID, the byte following contains the parameter + * length, and offset + 2 is the first byte of the parameter data. */ private int cdmaGetParameterOffset(byte parameterId) { ByteArrayInputStream pdu = new ByteArrayInputStream(mData); @@ -245,7 +239,6 @@ public class BluetoothMapSmsPdu { } } - public void cdmaChangeToDeliverPdu(long date) { /* Things to change: * - Message Type in bearer data (Not the overall point-to-point type) @@ -271,8 +264,9 @@ public class BluetoothMapSmsPdu { offset = cdmaGetSubParameterOffset(BEARER_DATA_MSG_ID); if (mData.length > (2 + offset)) { - int tmp = mData[offset + 2] - & 0xff; // Skip the subParam ID and length, and read the first byte. + int tmp = + mData[offset + 2] + & 0xff; // Skip the subParam ID and length, and read the first byte. // Mask out the type tmp &= 0x0f; // Set the new type @@ -283,12 +277,12 @@ public class BluetoothMapSmsPdu { } else { throw new IllegalArgumentException("Unable to convert PDU to Deliver type"); } - /* TODO: Do we need to change anything in the user data? Not sure if the user - data is - * just encoded using GSM encoding, or it is an actual GSM submit PDU - * embedded - * in the user data? - */ + /* TODO: Do we need to change anything in the user data? Not sure if the user + data is + * just encoded using GSM encoding, or it is an actual GSM submit PDU + * embedded + * in the user data? + */ } private static final byte TP_MIT_DELIVER = 0x00; // bit 0 and 1 @@ -374,8 +368,10 @@ public class BluetoothMapSmsPdu { mUserDataSeptetPadding = (headerSeptets * 7) - headerBits; mMsgSeptetCount = userDataLength - headerSeptets; } - mUserDataMsgOffset = gsmSubmitGetTpUdOffset() + userDataHeaderLength - + 1; // Add the byte containing the length + mUserDataMsgOffset = + gsmSubmitGetTpUdOffset() + + userDataHeaderLength + + 1; // Add the byte containing the length } else { mUserDataSeptetPadding = 0; mMsgSeptetCount = userDataLength; @@ -398,13 +394,15 @@ public class BluetoothMapSmsPdu { byte[] timeChars = timeStr.getBytes("US-ASCII"); for (int i = 0, n = timeStr.length(); i < n; i += 2) { - header.write((timeChars[i + 1] - 0x30) << 4 | (timeChars[i] - - 0x30)); // Offset from ascii char to decimal value + header.write( + (timeChars[i + 1] - 0x30) << 4 + | (timeChars[i] - 0x30)); // Offset from ascii char to decimal value } Calendar cal = Calendar.getInstance(); - int offset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (15 * 60 - * 1000); /* offset in quarters of an hour */ + int offset = + (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) + / (15 * 60 * 1000); /* offset in quarters of an hour */ String offsetString; if (offset < 0) { offsetString = String.format("%1$02d", -(offset)); @@ -417,7 +415,7 @@ public class BluetoothMapSmsPdu { } } -/* private void gsmSubmitExtractUserData() { + /* private void gsmSubmitExtractUserData() { int userDataLength = data[gsmSubmitGetTpUdlOffset()]; userData = new byte[userDataLength]; System.arraycopy(userData, 0, data, gsmSubmitGetTpUdOffset(), userDataLength); @@ -425,16 +423,15 @@ public class BluetoothMapSmsPdu { }*/ /** - * Change the GSM Submit Pdu data in this object to a deliver PDU: - * - Build the new header with deliver PDU type, originator and time stamp. - * - Extract encoding details from the submit PDU - * - Extract user data length and user data from the submitPdu - * - Build the new PDU - * @param date the time stamp to include (The value is the number of milliseconds since - * Jan. 1, 1970 GMT.) + * Change the GSM Submit Pdu data in this object to a deliver PDU: - Build the new header + * with deliver PDU type, originator and time stamp. - Extract encoding details from the + * submit PDU - Extract user data length and user data from the submitPdu - Build the new + * PDU + * + * @param date the time stamp to include (The value is the number of milliseconds since Jan. + * 1, 1970 GMT.) * @param originator the phone number to include in the deliver PDU header. Any undesired - * characters, - * such as '-' will be striped from this string. + * characters, such as '-' will be striped from this string. */ public void gsmChangeToDeliverPdu(long date, String originator) { ByteArrayOutputStream newPdu = @@ -443,19 +440,25 @@ public class BluetoothMapSmsPdu { int userDataLength = 0; try { newPdu.write( - TP_MIT_DELIVER | TP_MMS_NO_MORE | TP_RP_NO_REPLY_PATH | TP_SRI_NO_REPORT + TP_MIT_DELIVER + | TP_MMS_NO_MORE + | TP_RP_NO_REPLY_PATH + | TP_SRI_NO_REPORT | (mData[0] & 0xff) & TP_UDHI_MASK); encodedAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(originator); if (encodedAddress != null) { int padding = (encodedAddress[encodedAddress.length - 1] & 0xf0) == 0xf0 ? 1 : 0; - encodedAddress[0] = (byte) ((encodedAddress[0] - 1) * 2 - - padding); // Convert from octet length to semi octet length + encodedAddress[0] = + (byte) + ((encodedAddress[0] - 1) * 2 + - padding); // Convert from octet length to semi octet + // length // Insert originator address into the header - this includes the length newPdu.write(encodedAddress); } else { - newPdu.write(0); /* zero length */ + newPdu.write(0); /* zero length */ newPdu.write(0x81); /* International type */ } @@ -467,8 +470,8 @@ public class BluetoothMapSmsPdu { newPdu.write(userDataLength); // Copy the pdu user data - keep in mind that the userDataLength is not the // length in bytes for 7-bit encoding. - newPdu.write(mData, gsmSubmitGetTpUdOffset(), - mData.length - gsmSubmitGetTpUdOffset()); + newPdu.write( + mData, gsmSubmitGetTpUdOffset(), mData.length - gsmSubmitGetTpUdOffset()); } catch (IOException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -526,14 +529,13 @@ public class BluetoothMapSmsPdu { return sConcatenatedRef; } - public static ArrayList getSubmitPdus(Context context, String messageText, - String address) { + public static ArrayList getSubmitPdus( + Context context, String messageText, String address) { /* Use the generic GSM/CDMA SMS Message functionality within Android to generate the * SMS PDU's as once generated to send the SMS message. */ - int activePhone = context.getSystemService(TelephonyManager.class) - .getCurrentPhoneType(); + int activePhone = context.getSystemService(TelephonyManager.class).getCurrentPhoneType(); int phoneType; int[] ted = SmsMessage.calculateLength((CharSequence) messageText, false); @@ -561,17 +563,26 @@ public class BluetoothMapSmsPdu { } if (msgCount == 1) { - data = SmsMessage.getSubmitPdu(null, destinationAddress, smsFragments.get(0), - false).encodedMessage; + data = + SmsMessage.getSubmitPdu(null, destinationAddress, smsFragments.get(0), false) + .encodedMessage; newPdu = new SmsPdu(data, encoding, phoneType, languageTable); pdus.add(newPdu); } else { /* This code is a reduced copy of the actual code used in the Android SMS sub system, * hence the comments have been left untouched. */ for (int i = 0; i < msgCount; i++) { - data = SmsMessage.getSubmitPduEncodedMessage(phoneType == SMS_TYPE_GSM, - destinationAddress, smsFragments.get(i), encoding, languageTable, - languageShiftTable, refNumber, i + 1, msgCount); + data = + SmsMessage.getSubmitPduEncodedMessage( + phoneType == SMS_TYPE_GSM, + destinationAddress, + smsFragments.get(i), + encoding, + languageTable, + languageShiftTable, + refNumber, + i + 1, + msgCount); newPdu = new SmsPdu(data, encoding, phoneType, languageTable); pdus.add(newPdu); } @@ -582,15 +593,15 @@ public class BluetoothMapSmsPdu { /** * Generate a list of deliver PDUs. The messageText and address parameters must be different - * from null, - * for CDMA the date can be omitted (and will be ignored if supplied) + * from null, for CDMA the date can be omitted (and will be ignored if supplied) + * * @param messageText The text to include. * @param address The originator address. * @param date The delivery time stamp. * @return */ - public static ArrayList getDeliverPdus(Context context, String messageText, - String address, long date) { + public static ArrayList getDeliverPdus( + Context context, String messageText, String address, long date) { ArrayList deliverPdus = getSubmitPdus(context, messageText, address); /* @@ -603,7 +614,8 @@ public class BluetoothMapSmsPdu { for (SmsPdu currentPdu : deliverPdus) { if (currentPdu.getType() == SMS_TYPE_CDMA) { currentPdu.cdmaChangeToDeliverPdu(date); - } else { /* SMS_TYPE_GSM */ + } else { + /* SMS_TYPE_GSM */ currentPdu.gsmChangeToDeliverPdu(date, address); } } @@ -611,11 +623,10 @@ public class BluetoothMapSmsPdu { return deliverPdus; } - /** - * The decoding only supports decoding the actual textual content of the PDU received - * from the MAP client. (As the Android system has no interface to send pre encoded PDUs) - * The destination address must be extracted from the bmessage vCard(s). + * The decoding only supports decoding the actual textual content of the PDU received from the + * MAP client. (As the Android system has no interface to send pre encoded PDUs) The destination + * address must be extracted from the bmessage vCard(s). */ public static String decodePdu(byte[] data, int type) { String ret = ""; @@ -671,8 +682,11 @@ public class BluetoothMapSmsPdu { userDataCompressed = (0 != (dataCodingScheme & 0x20)); if (userDataCompressed) { - Log.w(TAG, "4 - Unsupported SMS data coding scheme " + "(compression) " + ( - dataCodingScheme & 0xff)); + Log.w( + TAG, + "4 - Unsupported SMS data coding scheme " + + "(compression) " + + (dataCodingScheme & 0xff)); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, @@ -690,8 +704,10 @@ public class BluetoothMapSmsPdu { case 1: // 8 bit data case 3: // reserved - Log.w(TAG, "1 - Unsupported SMS data coding scheme " + (dataCodingScheme - & 0xff)); + Log.w( + TAG, + "1 - Unsupported SMS data coding scheme " + + (dataCodingScheme & 0xff)); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, @@ -712,7 +728,8 @@ public class BluetoothMapSmsPdu { // 8 bit data encodingType = SmsConstants.ENCODING_8BIT; } - } else if ((dataCodingScheme & 0xF0) == 0xC0 || (dataCodingScheme & 0xF0) == 0xD0 + } else if ((dataCodingScheme & 0xF0) == 0xC0 + || (dataCodingScheme & 0xF0) == 0xD0 || (dataCodingScheme & 0xF0) == 0xE0) { // 3GPP TS 23.038 V7.0.0 (2006-03) section 4 @@ -770,23 +787,35 @@ public class BluetoothMapSmsPdu { break; case SmsConstants.ENCODING_7BIT: - messageBody = GsmAlphabet.gsm7BitPackedToString(pdu.getData(), - pdu.getUserDataMsgOffset(), pdu.getMsgSeptetCount(), - pdu.getUserDataSeptetPadding(), pdu.getLanguageTable(), - pdu.getLanguageShiftTable()); + messageBody = + GsmAlphabet.gsm7BitPackedToString( + pdu.getData(), + pdu.getUserDataMsgOffset(), + pdu.getMsgSeptetCount(), + pdu.getUserDataSeptetPadding(), + pdu.getLanguageTable(), + pdu.getLanguageShiftTable()); Log.i(TAG, "Decoded as 7BIT: " + messageBody); break; case SmsConstants.ENCODING_16BIT: - messageBody = new String(pdu.getData(), pdu.getUserDataMsgOffset(), - pdu.getUserDataMsgSize(), "utf-16"); + messageBody = + new String( + pdu.getData(), + pdu.getUserDataMsgOffset(), + pdu.getUserDataMsgSize(), + "utf-16"); Log.i(TAG, "Decoded as 16BIT: " + messageBody); break; case SmsConstants.ENCODING_KSC5601: - messageBody = new String(pdu.getData(), pdu.getUserDataMsgOffset(), - pdu.getUserDataMsgSize(), "KSC5601"); + messageBody = + new String( + pdu.getData(), + pdu.getUserDataMsgOffset(), + pdu.getUserDataMsgSize(), + "KSC5601"); Log.i(TAG, "Decoded as KSC5601: " + messageBody); break; } @@ -805,8 +834,7 @@ public class BluetoothMapSmsPdu { private static int[] getTableFromByteArray(byte[] data) { ByteArrayInputStream inStream = new ByteArrayInputStream(data); - /** tableValue[0]: languageTable - * tableValue[1]: languageShiftTable */ + /** tableValue[0]: languageTable tableValue[1]: languageShiftTable */ int[] tableValue = new int[2]; while (inStream.available() > 0) { int id = inStream.read(); @@ -828,20 +856,16 @@ public class BluetoothMapSmsPdu { private static class SmsConstants { /** User data text encoding code unit size */ public static final int ENCODING_UNKNOWN = 0; + public static final int ENCODING_7BIT = 1; public static final int ENCODING_8BIT = 2; public static final int ENCODING_16BIT = 3; - /** - * This value is not defined in global standard. Only in Korea, this is used. - */ + /** This value is not defined in global standard. Only in Korea, this is used. */ public static final int ENCODING_KSC5601 = 4; - /** - * SMS Class enumeration. - * See TS 23.038. - */ - public enum MessageClass{ + /** SMS Class enumeration. See TS 23.038. */ + public enum MessageClass { UNKNOWN, CLASS_0, CLASS_1, @@ -849,5 +873,4 @@ public class BluetoothMapSmsPdu { CLASS_3; } } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java index 80148b05ce5..1139a04c193 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -106,11 +106,16 @@ public class BluetoothMapUtils { private static boolean mPeerSupportUtcTimeStamp = false; /** - * This enum is used to convert from the bMessage type property to a type safe - * type. Hence do not change the names of the enum values. + * This enum is used to convert from the bMessage type property to a type safe type. Hence do + * not change the names of the enum values. */ public enum TYPE { - NONE, EMAIL, SMS_GSM, SMS_CDMA, MMS, IM; + NONE, + EMAIL, + SMS_GSM, + SMS_CDMA, + MMS, + IM; private static TYPE[] sAllValues = values(); public static TYPE fromOrdinal(int n) { @@ -132,11 +137,13 @@ public class BluetoothMapUtils { for (int i = 0; i < c.getColumnCount(); i++) { if (c.getColumnName(i).equals(BluetoothMapContract.MessageColumns.DATE) || c.getColumnName(i) - .equals(BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY) + .equals( + BluetoothMapContract.ConversationColumns + .LAST_THREAD_ACTIVITY) || c.getColumnName(i) - .equals(BluetoothMapContract.ChatStatusColumns.LAST_ACTIVE) + .equals(BluetoothMapContract.ChatStatusColumns.LAST_ACTIVE) || c.getColumnName(i) - .equals(BluetoothMapContract.PresenceColumns.LAST_ONLINE)) { + .equals(BluetoothMapContract.PresenceColumns.LAST_ONLINE)) { sb.append(" ") .append(c.getColumnName(i)) .append(" : ") @@ -173,16 +180,16 @@ public class BluetoothMapUtils { } /** - * Converts a hex-string to a long - please mind that Java has no unsigned data types, hence - * any value passed to this function, which has the upper bit set, will return a negative value. - * The bitwise content of the variable will however be the same. - * Will ignore any white-space characters as well as '-' seperators + * Converts a hex-string to a long - please mind that Java has no unsigned data types, hence any + * value passed to this function, which has the upper bit set, will return a negative value. The + * bitwise content of the variable will however be the same. Will ignore any white-space + * characters as well as '-' seperators + * * @param valueStr a hexstring - NOTE: shall not contain any "0x" prefix. * @return * @throws UnsupportedEncodingException if "US-ASCII" charset is not supported, - * NullPointerException if a null pointer is passed to the function, - * NumberFormatException if the string contains invalid characters. - * + * NullPointerException if a null pointer is passed to the function, NumberFormatException + * if the string contains invalid characters. */ public static long getLongFromString(String valueStr) throws UnsupportedEncodingException { if (valueStr == null) { @@ -205,8 +212,7 @@ public class BluetoothMapUtils { } else if (c >= 'a' && c <= 'f') { c -= ('a' - 10); } else if (c <= ' ' || c == '-') { - Log.v(TAG, - "Skipping c = '" + new String(new byte[]{(byte) c}, "US-ASCII") + "'"); + Log.v(TAG, "Skipping c = '" + new String(new byte[] {(byte) c}, "US-ASCII") + "'"); continue; // Skip any whitespace and '-' (which is used for UUIDs) } else { throw new NumberFormatException("Invalid character:" + c); @@ -259,9 +265,9 @@ public class BluetoothMapUtils { return new String(result, i, LONG_LONG_LENGTH - i); } - /** * Convert a Content Provider handle and a Messagetype into a unique handle + * * @param cpHandle content provider handle * @param messageType message type (TYPE_MMS/TYPE_SMS_GSM/TYPE_SMS_CDMA/TYPE_EMAIL) * @return String Formatted Map Handle @@ -300,11 +306,11 @@ public class BluetoothMapUtils { 0); } return mapHandle; - } /** * Convert a Content Provider handle and a Messagetype into a unique handle + * * @param cpHandle content provider handle * @param messageType message type (TYPE_MMS/TYPE_SMS_GSM/TYPE_SMS_CDMA/TYPE_EMAIL) * @return String Formatted Map Handle @@ -325,11 +331,11 @@ public class BluetoothMapUtils { throw new IllegalArgumentException("Message type not supported"); } return mapHandle; - } /** * Convert a handle string the the raw long representation, including the type bit. + * * @param mapHandle the handle string * @return the handle value */ @@ -339,6 +345,7 @@ public class BluetoothMapUtils { /** * Convert a Map Handle into a content provider Handle + * * @param mapHandle handle to convert from * @return content provider handle without message type mask */ @@ -354,6 +361,7 @@ public class BluetoothMapUtils { /** * Extract the message type from the handle. + * * @param mapHandle * @return */ @@ -381,13 +389,12 @@ public class BluetoothMapUtils { /** * TODO: Is this still needed after changing to another XML encoder? It should escape illegal - * characters. - * Strip away any illegal XML characters, that would otherwise cause the - * xml serializer to throw an exception. - * Examples of such characters are the emojis used on Android. + * characters. Strip away any illegal XML characters, that would otherwise cause the xml + * serializer to throw an exception. Examples of such characters are the emojis used on Android. + * * @param text The string to validate - * @return the same string if valid, otherwise a new String stripped for - * any illegal characters. If a null pointer is passed an empty string will be returned. + * @return the same string if valid, otherwise a new String stripped for any illegal characters. + * If a null pointer is passed an empty string will be returned. */ public static String stripInvalidChars(String text) { if (text == null) { @@ -411,6 +418,7 @@ public class BluetoothMapUtils { /** * Truncate UTF-8 string encoded byte array to desired length + * * @param utf8String String to convert to bytes array h * @param maxLength Max length of byte array returned including null termination * @return byte array containing valid utf8 characters with max length @@ -456,6 +464,7 @@ public class BluetoothMapUtils { /** * Truncate UTF-8 string encoded to desired length + * * @param utf8InString String to truncate * @param maxBytesLength Max length in bytes of the returned string * @return A valid truncated utf-8 string @@ -484,6 +493,7 @@ public class BluetoothMapUtils { /** * Method for converting quoted printable og base64 encoded string from headers. + * * @param in the string with encoding * @return decoded string if success - else the same string as was as input. */ @@ -500,11 +510,18 @@ public class BluetoothMapUtils { charset = m.group(1); encoding = m.group(2); encodedText = m.group(3); - Log.v(TAG, - "Matching:" + match + "\nCharset: " + charset + "\nEncoding : " + encoding - + "\nText: " + encodedText); + Log.v( + TAG, + "Matching:" + + match + + "\nCharset: " + + charset + + "\nEncoding : " + + encoding + + "\nText: " + + encodedText); if (encoding.equalsIgnoreCase("Q")) { - //quoted printable + // quoted printable Log.d(TAG, "StripEncoding: Quoted Printable string : " + encodedText); str = new String(quotedPrintableToUtf8(encodedText, charset)); in = in.replace(match, str); @@ -551,11 +568,10 @@ public class BluetoothMapUtils { return in; } - /** - * Convert a quoted-printable encoded string to a UTF-8 string: - * - Remove any soft line breaks: "=" - * - Convert all "=xx" to the corresponding byte + * Convert a quoted-printable encoded string to a UTF-8 string: - Remove any soft line breaks: + * "=" - Convert all "=xx" to the corresponding byte + * * @param text quoted-printable encoded UTF-8 text * @return decoded UTF-8 string */ @@ -590,9 +606,12 @@ public class BluetoothMapUtils { if (b1 == '\r' && b2 == '\n') { continue; // soft line break, remove all tree; } - if (((b1 >= '0' && b1 <= '9') || (b1 >= 'A' && b1 <= 'F') || (b1 >= 'a' - && b1 <= 'f')) && ((b2 >= '0' && b2 <= '9') || (b2 >= 'A' && b2 <= 'F') || ( - b2 >= 'a' && b2 <= 'f'))) { + if (((b1 >= '0' && b1 <= '9') + || (b1 >= 'A' && b1 <= 'F') + || (b1 >= 'a' && b1 <= 'f')) + && ((b2 >= '0' && b2 <= '9') + || (b2 >= 'A' && b2 <= 'F') + || (b2 >= 'a' && b2 <= 'f'))) { Log.v(TAG, "Found hex number: " + String.format("%c%c", b1, b2)); if (b1 <= '9') { b1 = (byte) (b1 - '0'); @@ -610,15 +629,16 @@ public class BluetoothMapUtils { b2 = (byte) (b2 - 'a' + 10); } - Log.v(TAG, - "Resulting nibble values: " + String.format("b1=%x b2=%x", b1, b2)); + Log.v(TAG, "Resulting nibble values: " + String.format("b1=%x b2=%x", b1, b2)); output[out++] = (byte) (b1 << 4 | b2); // valid hex char, append Log.v(TAG, "Resulting value: " + String.format("0x%2x", output[out - 1])); continue; } - Log.w(TAG, "Received wrongly quoted printable encoded text. " - + "Continuing at best effort..."); + Log.w( + TAG, + "Received wrongly quoted printable encoded text. " + + "Continuing at best effort..."); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, @@ -686,16 +706,15 @@ public class BluetoothMapUtils { } /** - * Encodes an array of bytes into an array of quoted-printable 7-bit characters. - * Unsafe characters are escaped. - * Simplified version of encoder from QuetedPrintableCodec.java (Apache external) + * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe + * characters are escaped. Simplified version of encoder from QuetedPrintableCodec.java (Apache + * external) * - * @param bytes - * array of bytes to be encoded + * @param bytes array of bytes to be encoded * @return UTF-8 string containing quoted-printable characters */ - private static final byte ESCAPE_CHAR = '='; + private static final byte TAB = 9; private static final byte SPACE = 32; @@ -738,18 +757,24 @@ public class BluetoothMapUtils { BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 10); - //cannot happen + // cannot happen return ""; } } static String getDateTimeString(long timestamp) { - SimpleDateFormat format = (mPeerSupportUtcTimeStamp) ? new - SimpleDateFormat("yyyyMMdd'T'HHmmssZ") : new SimpleDateFormat("yyyyMMdd'T'HHmmss"); + SimpleDateFormat format = + (mPeerSupportUtcTimeStamp) + ? new SimpleDateFormat("yyyyMMdd'T'HHmmssZ") + : new SimpleDateFormat("yyyyMMdd'T'HHmmss"); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(timestamp); - Log.v(TAG, "getDateTimeString timestamp :" + timestamp + " time:" - + format.format(cal.getTime())); + Log.v( + TAG, + "getDateTimeString timestamp :" + + timestamp + + " time:" + + format.format(cal.getTime())); return format.format(cal.getTime()); } @@ -759,8 +784,12 @@ public class BluetoothMapUtils { Calendar oneYearAgo = Calendar.getInstance(); oneYearAgo.add(Calendar.YEAR, -1); if (cal.before(oneYearAgo)) { - Log.v(TAG, "isDateTimeOlderThanOneYear " + cal.getTimeInMillis() - + " oneYearAgo: " + oneYearAgo.getTimeInMillis()); + Log.v( + TAG, + "isDateTimeOlderThanOneYear " + + cal.getTimeInMillis() + + " oneYearAgo: " + + oneYearAgo.getTimeInMillis()); return true; } return false; @@ -781,6 +810,4 @@ public class BluetoothMapUtils { } Log.v(TAG, "savePeerSupportUtcTimeStamp " + mPeerSupportUtcTimeStamp); } - } - diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java index 4dd3c48cdef..b4fe62c0002 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -43,7 +43,7 @@ public abstract class BluetoothMapbMessage { /* BMSG attributes */ private String mStatus = null; // READ/UNREAD - protected TYPE mType = null; // SMS/MMS/EMAIL + protected TYPE mType = null; // SMS/MMS/EMAIL private String mFolder = null; @@ -56,7 +56,6 @@ public abstract class BluetoothMapbMessage { private ArrayList mOriginator = null; private ArrayList mRecipient = null; - public static class VCard { /* VCARD attributes */ private String mVersion; @@ -70,14 +69,19 @@ public abstract class BluetoothMapbMessage { /** * Construct a version 3.0 vCard + * * @param name Structured * @param formattedName Formatted name * @param phoneNumbers a String[] of phone numbers * @param emailAddresses a String[] of email addresses * @param envLevel the bmessage envelope level (0 is the top/most outer level) */ - public VCard(String name, String formattedName, String[] phoneNumbers, - String[] emailAddresses, int envLevel) { + public VCard( + String name, + String formattedName, + String[] phoneNumbers, + String[] emailAddresses, + int envLevel) { this.mEnvLevel = envLevel; this.mVersion = "3.0"; this.mName = name != null ? name : ""; @@ -90,6 +94,7 @@ public abstract class BluetoothMapbMessage { /** * Construct a version 2.1 vCard + * * @param name Structured name * @param phoneNumbers a String[] of phone numbers * @param emailAddresses a String[] of email addresses @@ -107,6 +112,7 @@ public abstract class BluetoothMapbMessage { /** * Construct a version 3.0 vCard + * * @param name Structured name * @param formattedName Formatted name * @param phoneNumbers a String[] of phone numbers @@ -114,8 +120,13 @@ public abstract class BluetoothMapbMessage { * @param btUids a String[] of X-BT-UIDs if available, else null * @param btUcis a String[] of X-BT-UCIs if available, else null */ - public VCard(String name, String formattedName, String[] phoneNumbers, - String[] emailAddresses, String[] btUids, String[] btUcis) { + public VCard( + String name, + String formattedName, + String[] phoneNumbers, + String[] emailAddresses, + String[] btUids, + String[] btUcis) { this.mVersion = "3.0"; this.mName = (name != null) ? name : ""; this.mFormattedName = (formattedName != null) ? formattedName : ""; @@ -130,6 +141,7 @@ public abstract class BluetoothMapbMessage { /** * Construct a version 2.1 vCard + * * @param name Structured Name * @param phoneNumbers a String[] of phone numbers * @param emailAddresses a String[] of email addresses @@ -232,8 +244,8 @@ public abstract class BluetoothMapbMessage { } /** - * Parse a vCard from a BMgsReader, where a line containing "BEGIN:VCARD" - * have just been read. + * Parse a vCard from a BMgsReader, where a line containing "BEGIN:VCARD" have just been + * read. */ static VCard parseVcard(BMsgReader reader, int envLevel) { String formattedName = null; @@ -305,16 +317,20 @@ public abstract class BluetoothMapbMessage { // Empty UID entry - ignore } - line = reader.getLineEnforce(); } - return new VCard(name, formattedName, phoneNumbers == null ? null - : phoneNumbers.toArray(new String[phoneNumbers.size()]), - emailAddresses == null ? null - : emailAddresses.toArray(new String[emailAddresses.size()]), envLevel); + return new VCard( + name, + formattedName, + phoneNumbers == null + ? null + : phoneNumbers.toArray(new String[phoneNumbers.size()]), + emailAddresses == null + ? null + : emailAddresses.toArray(new String[emailAddresses.size()]), + envLevel); } } - ; @VisibleForTesting @@ -370,6 +386,7 @@ public abstract class BluetoothMapbMessage { /** * Read a line of text from the BMessage. + * * @return the next line of text, or null at end of file, or if UTF-8 is not supported. */ public String getLine() { @@ -392,8 +409,9 @@ public abstract class BluetoothMapbMessage { } /** - * same as getLine(), but throws an exception, if we run out of lines. - * Use this function when ever more lines are needed for the bMessage to be complete. + * same as getLine(), but throws an exception, if we run out of lines. Use this function + * when ever more lines are needed for the bMessage to be complete. + * * @return the next line */ public String getLineEnforce() { @@ -405,15 +423,11 @@ public abstract class BluetoothMapbMessage { return line; } - /** - * Reads a line from the InputStream, and examines if the subString - * matches the line read. - * @param subString - * The string to match against the line. - * @throws IllegalArgumentException - * If the expected substring is not found. + * Reads a line from the InputStream, and examines if the subString matches the line read. * + * @param subString The string to match against the line. + * @throws IllegalArgumentException If the expected substring is not found. */ public void expect(String subString) throws IllegalArgumentException { String line = getLine(); @@ -444,9 +458,10 @@ public abstract class BluetoothMapbMessage { /** * Read a part of the bMessage as raw data. + * * @param length the number of bytes to read * @return the byte[] containing the number of bytes or null if an error occurs or EOF is - * reached before length bytes have been read. + * reached before length bytes have been read. */ public byte[] getDataBytes(int length) { byte[] data = new byte[length]; @@ -472,12 +487,9 @@ public abstract class BluetoothMapbMessage { return data; } } - ; - public BluetoothMapbMessage() { - - } + public BluetoothMapbMessage() {} public String getVersionString() { return mVersionString; @@ -485,8 +497,9 @@ public abstract class BluetoothMapbMessage { /** * Set the version string for VCARD + * * @param version the actual number part of the version string i.e. 1.0 - * */ + */ public void setVersionString(String version) { this.mVersionString = "VERSION:" + version; } @@ -525,7 +538,7 @@ public abstract class BluetoothMapbMessage { String[] arg = line.split(":"); if (arg != null && arg.length == 2) { String value = arg[1].trim(); - //FIXME what should we do with this + // FIXME what should we do with this Log.i(TAG, "We got extended data with: " + value); } } @@ -536,7 +549,8 @@ public abstract class BluetoothMapbMessage { /* Will throw IllegalArgumentException if value is wrong */ type = TYPE.valueOf(value); if (appParamCharset == BluetoothMapAppParams.CHARSET_NATIVE - && type != TYPE.SMS_CDMA && type != TYPE.SMS_GSM) { + && type != TYPE.SMS_CDMA + && type != TYPE.SMS_GSM) { throw new IllegalArgumentException( "Native appParamsCharset " + "only supported for SMS"); } @@ -699,12 +713,13 @@ public abstract class BluetoothMapbMessage { } else if (line.contains("BEGIN:MSG")) { Log.v(TAG, "bMsgLength: " + mBMsgLength); if (mBMsgLength == INVALID_VALUE) { - throw new IllegalArgumentException("Missing value for 'LENGTH'. " - + "Unable to read remaining part of the message"); + throw new IllegalArgumentException( + "Missing value for 'LENGTH'. " + + "Unable to read remaining part of the message"); } /* For SMS: Encoding of MSG is always UTF-8 compliant, regardless of any properties, - since PDUs are encodes as hex-strings */ + since PDUs are encodes as hex-strings */ /* PTS has a bug regarding the message length, and sets it 2 bytes too short, hence * using the length field to determine the amount of data to read, might not be the * best solution. @@ -731,14 +746,11 @@ public abstract class BluetoothMapbMessage { } } - /** - * Parse the 'message' part of " - */ + /** Parse the 'message' part of " */ public abstract void parseMsgPart(String msgPart); /** - * Set initial values before parsing - will be called is a message body is found - * during parsing. + * Set initial values before parsing - will be called is a message body is found during parsing. */ public abstract void parseMsgInit(); @@ -775,7 +787,6 @@ public abstract class BluetoothMapbMessage { return mFolder; } - public void setEncoding(String encoding) { this.mEncoding = encoding; } @@ -793,11 +804,17 @@ public abstract class BluetoothMapbMessage { /** * Add a version 3.0 vCard with a formatted name + * * @param name e.g. Bonde;Casper * @param formattedName e.g. "Casper Bonde" */ - public void addOriginator(String name, String formattedName, String[] phoneNumbers, - String[] emailAddresses, String[] btUids, String[] btUcis) { + public void addOriginator( + String name, + String formattedName, + String[] phoneNumbers, + String[] emailAddresses, + String[] btUids, + String[] btUcis) { if (mOriginator == null) { mOriginator = new ArrayList(); } @@ -805,7 +822,6 @@ public abstract class BluetoothMapbMessage { new VCard(name, formattedName, phoneNumbers, emailAddresses, btUids, btUcis)); } - public void addOriginator(String[] btUcis, String[] btUids) { if (mOriginator == null) { mOriginator = new ArrayList(); @@ -813,8 +829,8 @@ public abstract class BluetoothMapbMessage { mOriginator.add(new VCard(null, null, null, null, btUids, btUcis)); } - - /** Add a version 2.1 vCard with only a name. + /** + * Add a version 2.1 vCard with only a name. * * @param name e.g. Bonde;Casper */ @@ -843,8 +859,13 @@ public abstract class BluetoothMapbMessage { mRecipient.add(new VCard(null, null, null, null, btUids, btUcis)); } - public void addRecipient(String name, String formattedName, String[] phoneNumbers, - String[] emailAddresses, String[] btUids, String[] btUcis) { + public void addRecipient( + String name, + String formattedName, + String[] phoneNumbers, + String[] emailAddresses, + String[] btUids, + String[] btUcis) { if (mRecipient == null) { mRecipient = new ArrayList(); } @@ -861,9 +882,9 @@ public abstract class BluetoothMapbMessage { /** * Convert a byte[] of data to a hex string representation, converting each nibble to the - * corresponding hex char. - * NOTE: There is not need to escape instances of "\r\nEND:MSG" in the binary data represented - * as a string as only the characters [0-9] and [a-f] is used. + * corresponding hex char. NOTE: There is not need to escape instances of "\r\nEND:MSG" in the + * binary data represented as a string as only the characters [0-9] and [a-f] is used. + * * @param pduData the byte-array of data. * @param scAddressData the byte-array of the encoded sc-Address. * @return the resulting string. @@ -877,16 +898,18 @@ public abstract class BluetoothMapbMessage { for (int i = 0; i < pduData.length; i++) { out.append(Integer.toString((pduData[i] >> 4) & 0x0f, 16)); // MS-nibble first out.append(Integer.toString(pduData[i] & 0x0f, 16)); - /*out.append(Integer.toHexString(data[i]));*/ /* This is the same as above, but does not - * include the needed 0's - * e.g. it converts the value 3 to "3" - * and not "03" */ + /*out.append(Integer.toHexString(data[i]));*/ + /* This is the same as above, but does not + * include the needed 0's + * e.g. it converts the value 3 to "3" + * and not "03" */ } return out.toString(); } /** * Decodes a binary hex-string encoded UTF-8 string to the represented binary data set. + * * @param data The string representation of the data - must have an even number of characters. * @return the byte[] represented in the data. */ @@ -955,7 +978,6 @@ public abstract class BluetoothMapbMessage { sb.append("CHARSET:").append(mCharset).append("\r\n"); } - int length = 0; /* 22 is the length of the 'BEGIN:MSG' and 'END:MSG' + 3*CRLF */ for (byte[] fragment : bodyFragments) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java index ea1b09067a4..3ba2c881a21 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -49,8 +49,7 @@ public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { } /** - * Set initial values before parsing - will be called is a message body is found - * during parsing. + * Set initial values before parsing - will be called is a message body is found during parsing. */ @Override public void parseMsgInit() { @@ -62,8 +61,8 @@ public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { ArrayList bodyFragments = new ArrayList(); /* Store the messages in an ArrayList to be able to handle the different message types in - a generic way. - * We use byte[] since we need to extract the length in bytes. */ + a generic way. + * We use byte[] since we need to extract the length in bytes. */ if (mEmailBody != null) { String tmpBody = mEmailBody.replaceAll( @@ -81,5 +80,4 @@ public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { } return encodeGeneric(bodyFragments); } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java index e7121a5abf1..99e7b6497f9 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -38,20 +38,19 @@ import java.util.UUID; public class BluetoothMapbMessageMime extends BluetoothMapbMessage { public static class MimePart { - public long mId = INVALID_VALUE; /* The _id from the content provider, can be used to + public long mId = INVALID_VALUE; /* The _id from the content provider, can be used to * sort the parts if needed */ public String mContentType = null; /* The mime type, e.g. text/plain */ public String mContentId = null; public String mContentLocation = null; public String mContentDisposition = null; - public String mPartName = null; /* e.g. text_1.txt*/ + public String mPartName = null; /* e.g. text_1.txt*/ public String mCharsetName = null; /* This seems to be a number e.g. 106 for UTF-8 CharacterSets holds a method for the mapping. */ - public String mFileName = null; /* Do not seem to be used */ - public byte[] mData = null; /* The raw un-encoded data e.g. the raw + public String mFileName = null; /* Do not seem to be used */ + public byte[] mData = null; /* The raw un-encoded data e.g. the raw * jpeg data or the text.getBytes("utf-8") */ - public String getDataAsString() { String result = null; String charset = mCharsetName; @@ -124,8 +123,9 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { or 1.2), the below use of UTF-8 is not allowed, Base64 should be used for text. */ - if (mContentType != null && (mContentType.toUpperCase().contains("TEXT") - || mContentType.toUpperCase().contains("SMIL"))) { + if (mContentType != null + && (mContentType.toUpperCase().contains("TEXT") + || mContentType.toUpperCase().contains("SMIL"))) { String text = new String(mData, "UTF-8"); if (text.getBytes().length == text.getBytes("UTF-8").length) { /* Add the header split empty line */ @@ -169,11 +169,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { private long mDate = INVALID_VALUE; private String mSubject = null; - private ArrayList mFrom = null; // Shall not be empty - private ArrayList mSender = null; // Shall not be empty - private ArrayList mTo = null; // Shall not be empty - private ArrayList mCc = null; // Can be empty - private ArrayList mBcc = null; // Can be empty + private ArrayList mFrom = null; // Shall not be empty + private ArrayList mSender = null; // Shall not be empty + private ArrayList mTo = null; // Shall not be empty + private ArrayList mCc = null; // Can be empty + private ArrayList mBcc = null; // Can be empty private ArrayList mReplyTo = null; // Can be empty private String mMessageId = null; private ArrayList mParts = null; @@ -391,12 +391,13 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { /** * Encode an address header, and perform folding if needed. + * * @param sb The stringBuilder to write to * @param headerName The RFC 2822 header name * @param addresses the reformatted address substrings to encode. */ - public void encodeHeaderAddresses(StringBuilder sb, String headerName, - ArrayList addresses) { + public void encodeHeaderAddresses( + StringBuilder sb, String headerName, ArrayList addresses) { /* TODO: Do we need to encode the addresses if they contain illegal characters? * This depends of the outcome of errata 4176. The current spec. states to use UTF-8 * where possible, but the RFCs states to use US-ASCII for the headers - hence encoding @@ -521,6 +522,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { /** * Encode the bMessage as a Mime message(MMS/IM) + * * @return * @throws UnsupportedEncodingException */ @@ -561,12 +563,12 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { return encodeGeneric(bodyFragments); } - /** * Try to parse the hdrPart string as e-mail headers. + * * @param hdrPart The string to parse. - * @return Null if the entire string were e-mail headers. The part of the string in which - * no headers were found. + * @return Null if the entire string were e-mail headers. The part of the string in which no + * headers were found. */ private String parseMimeHeaders(String hdrPart) { String[] headers = hdrPart.split("\r\n"); @@ -639,8 +641,8 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { if (contentTypeParts[j].contains("boundary")) { mBoundary = contentTypeParts[j].split("boundary[\\s]*=", 2)[1].trim(); // removing quotes from boundary string - if ((mBoundary.charAt(0) == '\"') && ( - mBoundary.charAt(mBoundary.length() - 1) == '\"')) { + if ((mBoundary.charAt(0) == '\"') + && (mBoundary.charAt(mBoundary.length() - 1) == '\"')) { mBoundary = mBoundary.substring(1, mBoundary.length() - 1); } Log.d(TAG, "Boundary tag=" + mBoundary); @@ -676,8 +678,9 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { } else { for (String header : headers) { // Skip empty lines(the \r\n after the boundary tag) and endBoundary tags - if ((header.length() == 0) || (header.trim().isEmpty()) || header.trim() - .equals("--")) { + if ((header.length() == 0) + || (header.trim().isEmpty()) + || header.trim().equals("--")) { continue; } @@ -718,8 +721,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { // This is used if the smil refers to a cid: in it's src newPart.mContentDisposition = headerValue; } else { - Log.w(TAG, "Skipping unknown part-header: " + headerType + " (" + header - + ")"); + Log.w(TAG, "Skipping unknown part-header: " + headerType + " (" + header + ")"); ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, @@ -835,7 +837,6 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { @Override public void parseMsgPart(String msgPart) { parseMime(msgPart); - } @Override @@ -848,5 +849,4 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { public byte[] encode() throws UnsupportedEncodingException { return encodeMime(); } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java index e7cb1bcb571..a04245f619c 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2013 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2013 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.util.Log; @@ -51,15 +51,19 @@ public class BluetoothMapbMessageSms extends BluetoothMapbMessage { if (mAppParamCharset == BluetoothMapAppParams.CHARSET_NATIVE) { Log.d(TAG, "Decoding \"" + msgPart + "\" as native PDU"); byte[] msgBytes = decodeBinary(msgPart); - if (msgBytes.length > 0 && msgBytes[0] < msgBytes.length - 1 + if (msgBytes.length > 0 + && msgBytes[0] < msgBytes.length - 1 && (msgBytes[msgBytes[0] + 1] & 0x03) != 0x01) { Log.d(TAG, "Only submit PDUs are supported"); throw new IllegalArgumentException("Only submit PDUs are supported"); } - mSmsBody += BluetoothMapSmsPdu.decodePdu(msgBytes, - mType == TYPE.SMS_CDMA ? BluetoothMapSmsPdu.SMS_TYPE_CDMA - : BluetoothMapSmsPdu.SMS_TYPE_GSM); + mSmsBody += + BluetoothMapSmsPdu.decodePdu( + msgBytes, + mType == TYPE.SMS_CDMA + ? BluetoothMapSmsPdu.SMS_TYPE_CDMA + : BluetoothMapSmsPdu.SMS_TYPE_GSM); } else { mSmsBody += msgPart; } @@ -75,26 +79,28 @@ public class BluetoothMapbMessageSms extends BluetoothMapbMessage { ArrayList bodyFragments = new ArrayList(); /* Store the messages in an ArrayList to be able to handle the different message types in - a generic way. - * We use byte[] since we need to extract the length in bytes. - */ + a generic way. + * We use byte[] since we need to extract the length in bytes. + */ if (mSmsBody != null) { - String tmpBody = mSmsBody.replaceAll("END:MSG", - "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG + String tmpBody = + mSmsBody.replaceAll( + "END:MSG", + "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG String remoteAddress = BluetoothMapService.getRemoteDevice().getAddress(); /* Fix IOT issue with PCM carkit where carkit is unable to parse - message if carriage return is present in it */ + message if carriage return is present in it */ if (DeviceWorkArounds.addressStartsWith(remoteAddress, DeviceWorkArounds.PCM_CARKIT)) { tmpBody = tmpBody.replaceAll("\r", ""); /* Fix Message Display issue with FORD SYNC carkit - * Remove line feed and include only carriage return */ } else if (DeviceWorkArounds.addressStartsWith( - remoteAddress, DeviceWorkArounds.FORD_SYNC_CARKIT)) { + remoteAddress, DeviceWorkArounds.FORD_SYNC_CARKIT)) { tmpBody = tmpBody.replaceAll("\n", ""); /* Fix IOT issue with SYNC carkit to remove trailing line feeds in the message body */ } else if (DeviceWorkArounds.addressStartsWith( - remoteAddress, DeviceWorkArounds.SYNC_CARKIT) + remoteAddress, DeviceWorkArounds.SYNC_CARKIT) && tmpBody.length() > 0) { int trailingLF = 0; while ((tmpBody.charAt(tmpBody.length() - trailingLF - 1)) == '\n') trailingLF++; @@ -113,5 +119,4 @@ public class BluetoothMapbMessageSms extends BluetoothMapbMessage { return encodeGeneric(bodyFragments); } - } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java b/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java index 7abf71678aa..ac828d1a2a3 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothDevice; @@ -65,16 +65,15 @@ public class BluetoothMnsObexClient { public static final int MSG_MNS_SEND_EVENT = 2; public static final int MSG_MNS_SDP_SEARCH_REGISTRATION = 3; - //Copy SdpManager.SDP_INTENT_DELAY - The timeout to wait for reply from native. + // Copy SdpManager.SDP_INTENT_DELAY - The timeout to wait for reply from native. private static final int MNS_SDP_SEARCH_DELAY = 6000; public MnsSdpSearchInfo mMnsLstRegRqst = null; private static final int MNS_NOTIFICATION_DELAY = 10; public static final ParcelUuid BLUETOOTH_UUID_OBEX_MNS = ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB"); - - public BluetoothMnsObexClient(BluetoothDevice remoteDevice, SdpMnsRecord mnsRecord, - Handler callback) { + public BluetoothMnsObexClient( + BluetoothDevice remoteDevice, SdpMnsRecord mnsRecord, Handler callback) { if (remoteDevice == null) { throw new NullPointerException("Obex transport is null"); } @@ -82,7 +81,7 @@ public class BluetoothMnsObexClient { HandlerThread thread = new HandlerThread("BluetoothMnsObexClient"); thread.start(); /* This will block until the looper have started, hence it will be safe to use it, - when the constructor completes */ + when the constructor completes */ Looper looper = thread.getLooper(); mHandler = new MnsObexClientHandler(looper); mCallback = callback; @@ -126,22 +125,22 @@ public class BluetoothMnsObexClient { if (isValidMnsRecord()) { handleRegistration(msg.arg1 /*masId*/, msg.arg2 /*status*/); } else { - //Should not happen + // Should not happen Log.d(TAG, "MNS SDP info not available yet - Cannot Connect."); } break; case MSG_MNS_SEND_EVENT: - sendEventHandler((byte[]) msg.obj/*byte[]*/, msg.arg1 /*masId*/); + sendEventHandler((byte[]) msg.obj /*byte[]*/, msg.arg1 /*masId*/); break; case MSG_MNS_SDP_SEARCH_REGISTRATION: - //Initiate SDP Search + // Initiate SDP Search notifyMnsSdpSearch(); - //Save the mns search info + // Save the mns search info mMnsLstRegRqst = new MnsSdpSearchInfo(true, msg.arg1, msg.arg2); - //Handle notification registration. + // Handle notification registration. Message msgReg = - mHandler.obtainMessage(MSG_MNS_NOTIFICATION_REGISTRATION, msg.arg1, - msg.arg2); + mHandler.obtainMessage( + MSG_MNS_NOTIFICATION_REGISTRATION, msg.arg1, msg.arg2); Log.v(TAG, "SearchReg masId: " + msg.arg1 + " notfStatus: " + msg.arg2); mHandler.sendMessageDelayed(msgReg, MNS_SDP_SEARCH_DELAY); break; @@ -156,8 +155,8 @@ public class BluetoothMnsObexClient { } /** - * Disconnect the connection to MNS server. - * Call this when the MAS client requests a de-registration on events. + * Disconnect the connection to MNS server. Call this when the MAS client requests a + * de-registration on events. */ public synchronized void disconnect() { try { @@ -206,9 +205,7 @@ public class BluetoothMnsObexClient { } } - /** - * Shutdown the MNS. - */ + /** Shutdown the MNS. */ public synchronized void shutdown() { /* should shutdown handler thread first to make sure * handleRegistration won't be called when disconnect @@ -230,6 +227,7 @@ public class BluetoothMnsObexClient { /** * We store a list of registered MasIds only to control connect/disconnect + * * @param masId * @param notificationStatus */ @@ -239,7 +237,7 @@ public class BluetoothMnsObexClient { if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_NO) { mRegisteredMasIds.delete(masId); if (mMnsLstRegRqst != null && mMnsLstRegRqst.lastMasId == masId) { - //Clear last saved MNSSdpSearchInfo , if Disconnect requested for same MasId. + // Clear last saved MNSSdpSearchInfo , if Disconnect requested for same MasId. mMnsLstRegRqst = null; } } else if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) { @@ -263,7 +261,7 @@ public class BluetoothMnsObexClient { disconnect(); } - //Register ContentObserver After connect/disconnect MNS channel. + // Register ContentObserver After connect/disconnect MNS channel. Log.v(TAG, "Send registerObserver: " + sendObserverRegistration); if (mCallback != null && sendObserverRegistration) { Message msg = Message.obtain(mCallback); @@ -290,11 +288,11 @@ public class BluetoothMnsObexClient { } mMnsRecord = mnsRecord; if (mMnsLstRegRqst != null) { - //SDP Search completed. + // SDP Search completed. mMnsLstRegRqst.setIsSearchInProgress(false); if (mHandler.hasMessages(MSG_MNS_NOTIFICATION_REGISTRATION)) { mHandler.removeMessages(MSG_MNS_NOTIFICATION_REGISTRATION); - //Search Result obtained within MNS_SDP_SEARCH_DELAY timeout + // Search Result obtained within MNS_SDP_SEARCH_DELAY timeout if (!isValidMnsRecord()) { // SDP info still not available for last trial. // Clear saved info. @@ -304,9 +302,8 @@ public class BluetoothMnsObexClient { Message msgReg = mHandler.obtainMessage(MSG_MNS_NOTIFICATION_REGISTRATION); msgReg.arg1 = mMnsLstRegRqst.lastMasId; msgReg.arg2 = mMnsLstRegRqst.lastNotificationStatus; - Log.v(TAG, "SearchReg masId: " + msgReg.arg1 + " notfStatus: " - + msgReg.arg2); - //Handle notification registration. + Log.v(TAG, "SearchReg masId: " + msgReg.arg1 + " notfStatus: " + msgReg.arg2); + // Handle notification registration. mHandler.sendMessageDelayed(msgReg, MNS_NOTIFICATION_DELAY); } } @@ -410,6 +407,7 @@ public class BluetoothMnsObexClient { /** * Call this method to queue an event report to be send to the MNS server. + * * @param eventBytes the encoded event data. * @param masInstanceId the MasId of the instance sending the event. */ diff --git a/android/app/src/com/android/bluetooth/map/MapContact.java b/android/app/src/com/android/bluetooth/map/MapContact.java index 2a460b00cab..d3be152c634 100644 --- a/android/app/src/com/android/bluetooth/map/MapContact.java +++ b/android/app/src/com/android/bluetooth/map/MapContact.java @@ -1,24 +1,22 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import com.android.bluetooth.SignedLongLong; -/** - * Local representation of an Android contact - */ +/** Local representation of an Android contact */ public class MapContact { private final String mName; private final long mId; diff --git a/android/app/src/com/android/bluetooth/map/MmsFileProvider.java b/android/app/src/com/android/bluetooth/map/MmsFileProvider.java index 194ff6c5bd6..75c821e046a 100644 --- a/android/app/src/com/android/bluetooth/map/MmsFileProvider.java +++ b/android/app/src/com/android/bluetooth/map/MmsFileProvider.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2014 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; import android.bluetooth.BluetoothProfile; @@ -55,7 +55,11 @@ public class MmsFileProvider extends ContentProvider { } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { // Don't support queries. return null; @@ -107,17 +111,17 @@ public class MmsFileProvider extends ContentProvider { return openPipeHelper(messageUri, null, null, null, mPipeWriter); } - public class PipeWriter implements PipeDataWriter { - /** - * Generate a message based on the cursor, and write the encoded data to the stream. - */ - + /** Generate a message based on the cursor, and write the encoded data to the stream. */ @Override - public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType, - Bundle opts, Cursor c) { - Log.d(TAG, "writeDataToPipe(): uri=" + uri.toString() + " - getLastPathSegment() = " - + uri.getLastPathSegment()); + public void writeDataToPipe( + ParcelFileDescriptor output, Uri uri, String mimeType, Bundle opts, Cursor c) { + Log.d( + TAG, + "writeDataToPipe(): uri=" + + uri.toString() + + " - getLastPathSegment() = " + + uri.getLastPathSegment()); FileOutputStream fout = null; GenericPdu pdu = null; @@ -179,6 +183,4 @@ public class MmsFileProvider extends ContentProvider { } } } - - } diff --git a/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java b/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java index f45e0ad3f84..c29d18908d3 100644 --- a/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java +++ b/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.map; @@ -46,6 +46,7 @@ public class SmsMmsContacts { private static final String TAG = "SmsMmsContacts"; private HashMap mPhoneNumbers = null; + @VisibleForTesting final HashMap mNames = new HashMap(10); @@ -54,8 +55,9 @@ public class SmsMmsContacts { @VisibleForTesting static final String[] ADDRESS_PROJECTION = { - CanonicalAddressesColumns._ID, CanonicalAddressesColumns.ADDRESS + CanonicalAddressesColumns._ID, CanonicalAddressesColumns.ADDRESS }; + private static final int COL_ADDR_ID = Arrays.asList(ADDRESS_PROJECTION).indexOf(CanonicalAddressesColumns._ID); private static final int COL_ADDR_ADDR = @@ -63,6 +65,7 @@ public class SmsMmsContacts { @VisibleForTesting static final String[] CONTACT_PROJECTION = {Contacts._ID, Contacts.DISPLAY_NAME}; + private static final String CONTACT_SEL_VISIBLE = Contacts.IN_VISIBLE_GROUP + "=1"; private static final int COL_CONTACT_ID = Arrays.asList(CONTACT_PROJECTION).indexOf(Contacts._ID); @@ -70,8 +73,9 @@ public class SmsMmsContacts { Arrays.asList(CONTACT_PROJECTION).indexOf(Contacts.DISPLAY_NAME); /** - * Get a contacts phone number based on the canonical addresses id of the contact. - * (The ID listed in the Threads table.) + * Get a contacts phone number based on the canonical addresses id of the contact. (The ID + * listed in the Threads table.) + * * @param resolver the ContantResolver to be used. * @param id the id of the contact, as listed in the Threads table * @return the phone number of the contact - or null if id does not exist. @@ -87,8 +91,10 @@ public class SmsMmsContacts { public static String getPhoneNumberUncached(ContentResolver resolver, long id) { String where = CanonicalAddressesColumns._ID + " = " + id; - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(resolver, ADDRESS_URI, - ADDRESS_PROJECTION, where, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + resolver, ADDRESS_URI, ADDRESS_PROJECTION, where, null, null); try { if (c != null) { if (c.moveToPosition(0)) { @@ -109,9 +115,7 @@ public class SmsMmsContacts { return null; } - /** - * Clears the local cache. Call after a listing is complete, to avoid using invalid data. - */ + /** Clears the local cache. Call after a listing is complete, to avoid using invalid data. */ public void clearCache() { if (mPhoneNumbers != null) { mPhoneNumbers.clear(); @@ -122,14 +126,17 @@ public class SmsMmsContacts { } /** - * Refreshes the cache, by clearing all cached values and fill the cache with the result of - * a new query. + * Refreshes the cache, by clearing all cached values and fill the cache with the result of a + * new query. + * * @param resolver the ContantResolver to be used. */ @VisibleForTesting void fillPhoneCache(ContentResolver resolver) { - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(resolver, ADDRESS_URI, - ADDRESS_PROJECTION, null, null, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + resolver, ADDRESS_URI, ADDRESS_PROJECTION, null, null, null); if (mPhoneNumbers == null) { int size = 0; if (c != null) { @@ -170,12 +177,13 @@ public class SmsMmsContacts { /** * Lookup a contacts name in the Android Contacts database. + * * @param phone the phone number of the contact * @param resolver the ContentResolver to use. * @return the name of the contact or null, if no contact was found. */ - public MapContact getContactNameFromPhone(String phone, ContentResolver resolver, - String contactNameFilter) { + public MapContact getContactNameFromPhone( + String phone, ContentResolver resolver, String contactNameFilter) { MapContact contact = mNames.get(phone); if (contact != null) { @@ -203,11 +211,13 @@ public class SmsMmsContacts { String[] selectionArgs = null; if (contactNameFilter != null) { selection += "AND " + ContactsContract.Contacts.DISPLAY_NAME + " like ?"; - selectionArgs = new String[]{"%" + contactNameFilter.replace("*", "%") + "%"}; + selectionArgs = new String[] {"%" + contactNameFilter.replace("*", "%") + "%"}; } - Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery(resolver, uri, - CONTACT_PROJECTION, selection, selectionArgs, null); + Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + resolver, uri, CONTACT_PROJECTION, selection, selectionArgs, null); try { if (c != null && c.getCount() >= 1) { c.moveToFirst(); diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java b/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java index 77945da0015..f36bc9d42f5 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java +++ b/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java @@ -90,10 +90,7 @@ class MapClientContent { private HashMap mHandleToUriMap = new HashMap<>(); private HashMap mUriToHandleMap = new HashMap<>(); - /** - * Callbacks - * API to notify about statusChanges as observed from the content provider - */ + /** Callbacks API to notify about statusChanges as observed from the content provider */ interface Callbacks { void onMessageStatusChanged(String handle, int status); } @@ -118,33 +115,36 @@ class MapClientContent { mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class); mTelephonyManager = mContext.getSystemService(TelephonyManager.class); - mSubscriptionManager - .addSubscriptionInfoRecord(mDevice.getAddress(), Utils.getName(mDevice), 0, - SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); - SubscriptionInfo info = mSubscriptionManager - .getActiveSubscriptionInfoForIcc(mDevice.getAddress()); + mSubscriptionManager.addSubscriptionInfoRecord( + mDevice.getAddress(), + Utils.getName(mDevice), + 0, + SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); + SubscriptionInfo info = + mSubscriptionManager.getActiveSubscriptionInfoForIcc(mDevice.getAddress()); if (info != null) { mSubscriptionId = info.getSubscriptionId(); } - mContentObserver = new ContentObserver(null) { - @Override - public boolean deliverSelfNotifications() { - return false; - } + mContentObserver = + new ContentObserver(null) { + @Override + public boolean deliverSelfNotifications() { + return false; + } - @Override - public void onChange(boolean selfChange) { - verbose("onChange(self=" + selfChange + ")"); - findChangeInDatabase(); - } + @Override + public void onChange(boolean selfChange) { + verbose("onChange(self=" + selfChange + ")"); + findChangeInDatabase(); + } - @Override - public void onChange(boolean selfChange, Uri uri) { - verbose("onChange(self=" + selfChange + ", uri=" + uri.toString() + ")"); - findChangeInDatabase(); - } - }; + @Override + public void onChange(boolean selfChange, Uri uri) { + verbose("onChange(self=" + selfChange + ", uri=" + uri.toString() + ")"); + findChangeInDatabase(); + } + }; clearMessages(mContext, mSubscriptionId); mResolver.registerContentObserver(Sms.CONTENT_URI, true, mContentObserver); @@ -164,8 +164,8 @@ class MapClientContent { if (info.getSubscriptionType() == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM) { clearMessages(context, info.getSubscriptionId()); try { - subscriptionManager.removeSubscriptionInfoRecord(info.getIccId(), - SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); + subscriptionManager.removeSubscriptionInfoRecord( + info.getIccId(), SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); } catch (Exception e) { Log.w(TAG, "[AllDevices] cleanUp failed: " + e.toString()); } @@ -198,8 +198,8 @@ class MapClientContent { } /** - * This number is necessary for thread_id to work properly. thread_id is needed for - * (group) MMS messages to be displayed/stitched correctly. + * This number is necessary for thread_id to work properly. thread_id is needed for (group) MMS + * messages to be displayed/stitched correctly. */ void setRemoteDeviceOwnNumber(String phoneNumber) { mPhoneNumber = phoneNumber; @@ -209,8 +209,8 @@ class MapClientContent { /** * storeMessage * - * Store a message in database with the associated handle and timestamp. - * The handle is used to associate the local message with the remote message. + *

Store a message in database with the associated handle and timestamp. The handle is used + * to associate the local message with the remote message. */ void storeMessage(Bmessage message, String handle, Long timestamp, boolean seen) { info( @@ -254,8 +254,10 @@ class MapClientContent { } verbose("Received SMS from Number " + recipients); - Uri contentUri = INBOX_PATH.equalsIgnoreCase(message.getFolder()) ? Sms.Inbox.CONTENT_URI - : Sms.Sent.CONTENT_URI; + Uri contentUri = + INBOX_PATH.equalsIgnoreCase(message.getFolder()) + ? Sms.Inbox.CONTENT_URI + : Sms.Sent.CONTENT_URI; ContentValues values = new ContentValues(); long threadId = getThreadId(message); int readStatus = message.getStatus() == Bmessage.Status.READ ? 1 : 0; @@ -279,10 +281,7 @@ class MapClientContent { debug("Map InsertedThread" + results); } - /** - * deleteMessage - * remove a message from the local provider based on a remote change - */ + /** deleteMessage remove a message from the local provider based on a remote change */ void deleteMessage(String handle) { debug("deleting handle" + handle); Uri messageToChange = mHandleToUriMap.get(handle); @@ -291,11 +290,7 @@ class MapClientContent { } } - - /** - * markRead - * mark a message read in the local provider based on a remote change - */ + /** markRead mark a message read in the local provider based on a remote change */ void markRead(String handle) { debug("marking read " + handle); Uri messageToChange = mHandleToUriMap.get(handle); @@ -307,9 +302,8 @@ class MapClientContent { } /** - * findChangeInDatabase - * compare the current state of the local content provider to the expected state and propagate - * changes to the remote. + * findChangeInDatabase compare the current state of the local content provider to the expected + * state and propagate changes to the remote. */ private void findChangeInDatabase() { HashMap originalUriToHandleMap; @@ -317,7 +311,7 @@ class MapClientContent { originalUriToHandleMap = mUriToHandleMap; duplicateUriToHandleMap = new HashMap<>(originalUriToHandleMap); - for (Uri uri : new Uri[]{Mms.CONTENT_URI, Sms.CONTENT_URI}) { + for (Uri uri : new Uri[] {Mms.CONTENT_URI, Sms.CONTENT_URI}) { try (Cursor cursor = mResolver.query(uri, null, null, null, null)) { while (cursor.moveToNext()) { Uri index = @@ -337,8 +331,8 @@ class MapClientContent { for (HashMap.Entry record : duplicateUriToHandleMap.entrySet()) { verbose("Deleted " + ((MessageStatus) record.getValue()).mHandle); originalUriToHandleMap.remove(record.getKey()); - mCallbacks.onMessageStatusChanged(((MessageStatus) record.getValue()).mHandle, - BluetoothMapClient.DELETED); + mCallbacks.onMessageStatusChanged( + ((MessageStatus) record.getValue()).mHandle, BluetoothMapClient.DELETED); } } @@ -452,28 +446,25 @@ class MapClientContent { } } - /** - * cleanUp - * clear the subscription info and content on shutdown - */ + /** cleanUp clear the subscription info and content on shutdown */ void cleanUp() { - debug("cleanUp(device=" + Utils.getLoggableAddress(mDevice) - + "subscriptionId=" + mSubscriptionId); + debug( + "cleanUp(device=" + + Utils.getLoggableAddress(mDevice) + + "subscriptionId=" + + mSubscriptionId); mResolver.unregisterContentObserver(mContentObserver); clearMessages(mContext, mSubscriptionId); try { - mSubscriptionManager.removeSubscriptionInfoRecord(mDevice.getAddress(), - SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); + mSubscriptionManager.removeSubscriptionInfoRecord( + mDevice.getAddress(), SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; } catch (Exception e) { warn("cleanUp failed: " + e.toString()); } } - /** - * clearMessages - * clean up the content provider on startup - */ + /** clearMessages clean up the content provider on startup */ private static void clearMessages(Context context, int subscriptionId) { Log.d(TAG, "[AllDevices] clearMessages(subscriptionId=" + subscriptionId); @@ -487,20 +478,21 @@ class MapClientContent { } } - resolver.delete(Sms.CONTENT_URI, Sms.SUBSCRIPTION_ID + " =? ", - new String[]{Integer.toString(subscriptionId)}); - resolver.delete(Mms.CONTENT_URI, Mms.SUBSCRIPTION_ID + " =? ", - new String[]{Integer.toString(subscriptionId)}); + resolver.delete( + Sms.CONTENT_URI, + Sms.SUBSCRIPTION_ID + " =? ", + new String[] {Integer.toString(subscriptionId)}); + resolver.delete( + Mms.CONTENT_URI, + Mms.SUBSCRIPTION_ID + " =? ", + new String[] {Integer.toString(subscriptionId)}); if (threads.length() > 2) { threads = threads.substring(0, threads.length() - 2); resolver.delete(Threads.CONTENT_URI, Threads._ID + " IN (" + threads + ")", null); } } - /** - * getThreadId - * utilize the originator and recipients to obtain the thread id - */ + /** getThreadId utilize the originator and recipients to obtain the thread id */ private long getThreadId(Bmessage message) { Set messageContacts = new ArraySet<>(); @@ -516,8 +508,12 @@ class MapClientContent { if (mPhoneNumber == null) { warn("getThreadId called, mPhoneNumber never found."); } - messageContacts.removeIf(number -> (PhoneNumberUtils.areSamePhoneNumber(number, - mPhoneNumber, mTelephonyManager.getNetworkCountryIso()))); + messageContacts.removeIf( + number -> + (PhoneNumberUtils.areSamePhoneNumber( + number, + mPhoneNumber, + mTelephonyManager.getNetworkCountryIso()))); } verbose("Contacts = " + messageContacts.toString()); @@ -529,8 +525,8 @@ class MapClientContent { for (VCardEntry recipient : recipients) { List phoneData = recipient.getPhoneList(); if (phoneData != null && !phoneData.isEmpty()) { - messageContacts - .add(PhoneNumberUtils.extractNetworkPortion(phoneData.get(0).getNumber())); + messageContacts.add( + PhoneNumberUtils.extractNetworkPortion(phoneData.get(0).getNumber())); } } } @@ -564,8 +560,8 @@ class MapClientContent { } /** - * addThreadContactToEntries - * utilizing the thread id fill in the appropriate fields of bmsg with the intended recipients + * addThreadContactToEntries utilizing the thread id fill in the appropriate fields of bmsg with + * the intended recipients */ boolean addThreadContactsToEntries(Bmessage bmsg, String thread) { String threadId = Uri.parse(thread).getLastPathSegment(); @@ -584,8 +580,9 @@ class MapClientContent { if (cursor.moveToNext()) { debug("Columns" + Arrays.toString(cursor.getColumnNames())); - verbose("CONTACT LIST: " - + cursor.getString(cursor.getColumnIndex("recipient_ids"))); + verbose( + "CONTACT LIST: " + + cursor.getString(cursor.getColumnIndex("recipient_ids"))); addRecipientsToEntries( bmsg, cursor.getString(cursor.getColumnIndex("recipient_ids")).split(" ")); return true; @@ -596,7 +593,6 @@ class MapClientContent { } } - private void addRecipientsToEntries(Bmessage bmsg, String[] recipients) { verbose("CONTACT LIST: " + Arrays.toString(recipients)); for (String recipient : recipients) { @@ -632,14 +628,26 @@ class MapClientContent { } Cursor cursor = null; - if (Sms.CONTENT_URI.equals(uri) || Sms.Inbox.CONTENT_URI.equals(uri) + if (Sms.CONTENT_URI.equals(uri) + || Sms.Inbox.CONTENT_URI.equals(uri) || Sms.Sent.CONTENT_URI.equals(uri)) { - cursor = mResolver.query(uri, new String[] {"count(*)"}, Sms.SUBSCRIPTION_ID + " =? ", - new String[]{Integer.toString(mSubscriptionId)}, null); - } else if (Mms.CONTENT_URI.equals(uri) || Mms.Inbox.CONTENT_URI.equals(uri) + cursor = + mResolver.query( + uri, + new String[] {"count(*)"}, + Sms.SUBSCRIPTION_ID + " =? ", + new String[] {Integer.toString(mSubscriptionId)}, + null); + } else if (Mms.CONTENT_URI.equals(uri) + || Mms.Inbox.CONTENT_URI.equals(uri) || Mms.Sent.CONTENT_URI.equals(uri)) { - cursor = mResolver.query(uri, new String[] {"count(*)"}, Mms.SUBSCRIPTION_ID + " =? ", - new String[]{Integer.toString(mSubscriptionId)}, null); + cursor = + mResolver.query( + uri, + new String[] {"count(*)"}, + Mms.SUBSCRIPTION_ID + " =? ", + new String[] {Integer.toString(mSubscriptionId)}, + null); } else if (Threads.CONTENT_URI.equals(uri)) { uri = Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build(); cursor = mResolver.query(uri, new String[] {"count(*)"}, null, null, null); @@ -800,15 +808,21 @@ class MapClientContent { sb.append(" Device Message DB:"); sb.append("\n Subscription ID: " + mSubscriptionId); if (mSubscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - sb.append("\n SMS Messages (Inbox/Sent/Total): " - + getStoredMessagesCount(Sms.Inbox.CONTENT_URI) - + " / " + getStoredMessagesCount(Sms.Sent.CONTENT_URI) - + " / " + getStoredMessagesCount(Sms.CONTENT_URI)); - - sb.append("\n MMS Messages (Inbox/Sent/Total): " - + getStoredMessagesCount(Mms.Inbox.CONTENT_URI) - + " / " + getStoredMessagesCount(Mms.Sent.CONTENT_URI) - + " / " + getStoredMessagesCount(Mms.CONTENT_URI)); + sb.append( + "\n SMS Messages (Inbox/Sent/Total): " + + getStoredMessagesCount(Sms.Inbox.CONTENT_URI) + + " / " + + getStoredMessagesCount(Sms.Sent.CONTENT_URI) + + " / " + + getStoredMessagesCount(Sms.CONTENT_URI)); + + sb.append( + "\n MMS Messages (Inbox/Sent/Total): " + + getStoredMessagesCount(Mms.Inbox.CONTENT_URI) + + " / " + + getStoredMessagesCount(Mms.Sent.CONTENT_URI) + + " / " + + getStoredMessagesCount(Mms.CONTENT_URI)); sb.append("\n Threads: " + getStoredMessagesCount(Threads.CONTENT_URI)); @@ -829,8 +843,8 @@ class MapClientContent { /** * MessageStatus * - * Helper class to store associations between remote and local provider based on message handle - * and read status + *

Helper class to store associations between remote and local provider based on message + * handle and read status */ class MessageStatus { @@ -844,8 +858,8 @@ class MapClientContent { @Override public boolean equals(Object other) { - return ((other instanceof MessageStatus) && ((MessageStatus) other).mHandle - .equals(mHandle)); + return ((other instanceof MessageStatus) + && ((MessageStatus) other).mHandle.equals(mHandle)); } } diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java index fde8fab40c0..e8ccde02875 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java +++ b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java @@ -62,8 +62,7 @@ public class MapClientService extends ProfileService { private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private static MapClientService sMapClientService; - @VisibleForTesting - private Handler mHandler; + @VisibleForTesting private Handler mHandler; private Looper mSmLooper; @@ -113,15 +112,18 @@ public class MapClientService extends ProfileService { */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public synchronized boolean connect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); if (device == null) { throw new IllegalArgumentException("Null device"); } Log.d(TAG, "connect(device= " + device + "): devices=" + mMapInstanceMap.keySet()); if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { - Log.w(TAG, "Connection not allowed: <" + device.getAddress() - + "> is CONNECTION_POLICY_FORBIDDEN"); + Log.w( + TAG, + "Connection not allowed: <" + + device.getAddress() + + "> is CONNECTION_POLICY_FORBIDDEN"); return false; } MceStateMachine mapStateMachine = mMapInstanceMap.get(device); @@ -138,8 +140,11 @@ public class MapClientService extends ProfileService { addDeviceToMapAndConnect(device); return true; } else { - Log.e(TAG, "Maxed out on the number of allowed MAP connections. " - + "Connect request rejected on " + device); + Log.e( + TAG, + "Maxed out on the number of allowed MAP connections. " + + "Connect request rejected on " + + device); return false; } } @@ -175,8 +180,8 @@ public class MapClientService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public synchronized boolean disconnect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "disconnect(device= " + device + "): devices=" + mMapInstanceMap.keySet()); MceStateMachine mapStateMachine = mMapInstanceMap.get(device); // a map state machine instance doesn't exist. maybe it is already gone? @@ -189,13 +194,12 @@ public class MapClientService extends ProfileService { return false; } mapStateMachine.disconnect(); - Log.d(TAG, "disconnect(device= " + device + "): end devices=" - + mMapInstanceMap.keySet()); + Log.d(TAG, "disconnect(device= " + device + "): end devices=" + mMapInstanceMap.keySet()); return true; } public List getConnectedDevices() { - return getDevicesMatchingConnectionStates(new int[]{BluetoothAdapter.STATE_CONNECTED}); + return getDevicesMatchingConnectionStates(new int[] {BluetoothAdapter.STATE_CONNECTED}); } MceStateMachine getMceStateMachineForDevice(BluetoothDevice device) { @@ -223,20 +227,20 @@ public class MapClientService extends ProfileService { public synchronized int getConnectionState(BluetoothDevice device) { MceStateMachine mapStateMachine = mMapInstanceMap.get(device); // a map state machine instance doesn't exist yet, create a new one if we can. - return (mapStateMachine == null) ? BluetoothProfile.STATE_DISCONNECTED + return (mapStateMachine == null) + ? BluetoothProfile.STATE_DISCONNECTED : mapStateMachine.getState(); } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -245,11 +249,11 @@ public class MapClientService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { Log.v(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.MAP_CLIENT, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.MAP_CLIENT, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -263,24 +267,26 @@ public class MapClientService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.MAP_CLIENT); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.MAP_CLIENT); } - public synchronized boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message, - PendingIntent sentIntent, PendingIntent deliveredIntent) { + public synchronized boolean sendMessage( + BluetoothDevice device, + Uri[] contacts, + String message, + PendingIntent sentIntent, + PendingIntent deliveredIntent) { MceStateMachine mapStateMachine = mMapInstanceMap.get(device); return mapStateMachine != null && mapStateMachine.sendMapMessage(contacts, message, sentIntent, deliveredIntent); @@ -296,8 +302,10 @@ public class MapClientService extends ProfileService { Log.d(TAG, "start()"); mAdapterService = AdapterService.getAdapterService(); - mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), - "DatabaseManager cannot be null when MapClientService starts"); + mDatabaseManager = + Objects.requireNonNull( + AdapterService.getAdapterService().getDatabase(), + "DatabaseManager cannot be null when MapClientService starts"); mHandler = new Handler(Looper.getMainLooper()); @@ -387,6 +395,7 @@ public class MapClientService extends ProfileService { /** * Returns the SDP record's MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114). + * * @param device The Bluetooth device to get this value for. * @return the SDP record's MapSupportedFeatures field. */ @@ -399,7 +408,8 @@ public class MapClientService extends ProfileService { return mapStateMachine.getSupportedFeatures(); } - public synchronized boolean setMessageStatus(BluetoothDevice device, String handle, int status) { + public synchronized boolean setMessageStatus( + BluetoothDevice device, String handle, int status) { MceStateMachine mapStateMachine = mMapInstanceMap.get(device); if (mapStateMachine == null) { return false; @@ -415,11 +425,11 @@ public class MapClientService extends ProfileService { } } - //Binder object: Must be static class or memory leak may occur + // Binder object: Must be static class or memory leak may occur /** - * This class implements the IClient interface - or actually it validates the - * preconditions for calling the actual functionality in the MapClientService, and calls it. + * This class implements the IClient interface - or actually it validates the preconditions for + * calling the actual functionality in the MapClientService, and calls it. */ @VisibleForTesting static class Binder extends IBluetoothMapClient.Stub implements IProfileServiceBinder { @@ -620,8 +630,12 @@ public class MapClientService extends ProfileService { return; } - Log.i(TAG, "Received ACL disconnection event, device=" + device.toString() - + ", transport=" + transport); + Log.i( + TAG, + "Received ACL disconnection event, device=" + + device.toString() + + ", transport=" + + transport); if (transport != BluetoothDevice.TRANSPORT_BREDR) { return; diff --git a/android/app/src/com/android/bluetooth/mapclient/MasClient.java b/android/app/src/com/android/bluetooth/mapclient/MasClient.java index b0a2c4242f6..99a0d47ed5c 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MasClient.java +++ b/android/app/src/com/android/bluetooth/mapclient/MasClient.java @@ -44,24 +44,25 @@ public class MasClient { private static final int CONNECT = 0; private static final int DISCONNECT = 1; private static final int REQUEST = 2; - private static final byte[] BLUETOOTH_UUID_OBEX_MAS = new byte[]{ - (byte) 0xbb, - 0x58, - 0x2b, - 0x40, - 0x42, - 0x0c, - 0x11, - (byte) 0xdb, - (byte) 0xb0, - (byte) 0xde, - 0x08, - 0x00, - 0x20, - 0x0c, - (byte) 0x9a, - 0x66 - }; + private static final byte[] BLUETOOTH_UUID_OBEX_MAS = + new byte[] { + (byte) 0xbb, + 0x58, + 0x2b, + 0x40, + 0x42, + 0x0c, + 0x11, + (byte) 0xdb, + (byte) 0xb0, + (byte) 0xde, + 0x08, + 0x00, + 0x20, + 0x0c, + (byte) 0x9a, + 0x66 + }; private static final byte OAP_TAGID_MAP_SUPPORTED_FEATURES = 0x29; private static final int L2CAP_INVALID_PSM = -1; private static final int MAP_FEATURE_NOTIFICATION_REGISTRATION = 0x00000001; @@ -70,9 +71,11 @@ public class MasClient { private static final int MAP_FEATURE_UPLOADING = 0x00000008; private static final int MAP_FEATURE_EXTENDED_EVENT_REPORT_1_1 = 0x00000040; static final int MAP_SUPPORTED_FEATURES = - MAP_FEATURE_NOTIFICATION_REGISTRATION | MAP_FEATURE_NOTIFICATION - | MAP_FEATURE_BROWSING | MAP_FEATURE_UPLOADING - | MAP_FEATURE_EXTENDED_EVENT_REPORT_1_1; + MAP_FEATURE_NOTIFICATION_REGISTRATION + | MAP_FEATURE_NOTIFICATION + | MAP_FEATURE_BROWSING + | MAP_FEATURE_UPLOADING + | MAP_FEATURE_EXTENDED_EVENT_REPORT_1_1; private final StateMachine mCallback; private Handler mHandler; @@ -84,8 +87,8 @@ public class MasClient { private boolean mConnected = false; SdpMasRecord mSdpMasRecord; - public MasClient(BluetoothDevice remoteDevice, StateMachine callback, - SdpMasRecord sdpMasRecord) { + public MasClient( + BluetoothDevice remoteDevice, StateMachine callback, SdpMasRecord sdpMasRecord) { if (remoteDevice == null) { throw new NullPointerException("Obex transport is null"); } @@ -95,7 +98,7 @@ public class MasClient { mThread = new HandlerThread("Client"); mThread.start(); /* This will block until the looper have started, hence it will be safe to use it, - when the constructor completes */ + when the constructor completes */ Looper looper = mThread.getLooper(); mHandler = new MasClientHandler(looper, this); @@ -110,8 +113,10 @@ public class MasClient { Log.d(TAG, "Connecting to OBEX on L2CAP channel " + l2capSocket); mSocket = mRemoteDevice.createL2capSocket(l2capSocket); } else { - Log.d(TAG, "Connecting to OBEX on RFCOM channel " - + mSdpMasRecord.getRfcommCannelNumber()); + Log.d( + TAG, + "Connecting to OBEX on RFCOM channel " + + mSdpMasRecord.getRfcommCannelNumber()); mSocket = mRemoteDevice.createRfcommSocket(mSdpMasRecord.getRfcommCannelNumber()); } Log.d(TAG, mRemoteDevice.toString() + "Socket: " + mSocket.toString()); @@ -203,7 +208,8 @@ public class MasClient { } public enum CharsetType { - NATIVE, UTF_8; + NATIVE, + UTF_8; } SdpMasRecord getSdpMasRecord() { @@ -242,5 +248,4 @@ public class MasClient { } } } - } diff --git a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java index 87d47819e68..c4ee7a6e244 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +++ b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java @@ -15,28 +15,16 @@ */ /** - * Bluetooth MAP MCE StateMachine - * (Disconnected) - * | ^ - * CONNECT | | DISCONNECTED - * V | - * (Connecting) (Disconnecting) - * | ^ - * CONNECTED | | DISCONNECT - * V | - * (Connected) + * Bluetooth MAP MCE StateMachine (Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting) + * (Disconnecting) | ^ CONNECTED | | DISCONNECT V | (Connected) * - * Valid Transitions: State + Event -> Transition: + *

Valid Transitions: State + Event -> Transition: * - * Disconnected + CONNECT -> Connecting - * Connecting + CONNECTED -> Connected - * Connecting + TIMEOUT -> Disconnecting - * Connecting + DISCONNECT/CONNECT -> Defer Message - * Connected + DISCONNECT -> Disconnecting - * Connected + CONNECT -> Disconnecting + Defer Message - * Disconnecting + DISCONNECTED -> (Safe) Disconnected - * Disconnecting + TIMEOUT -> (Force) Disconnected - * Disconnecting + DISCONNECT/CONNECT : Defer Message + *

Disconnected + CONNECT -> Connecting Connecting + CONNECTED -> Connected Connecting + TIMEOUT + * -> Disconnecting Connecting + DISCONNECT/CONNECT -> Defer Message Connected + DISCONNECT -> + * Disconnecting Connected + CONNECT -> Disconnecting + Defer Message Disconnecting + DISCONNECTED + * -> (Safe) Disconnected Disconnecting + TIMEOUT -> (Force) Disconnected Disconnecting + + * DISCONNECT/CONNECT : Defer Message */ package com.android.bluetooth.mapclient; @@ -167,18 +155,17 @@ class MceStateMachine extends StateMachine { // (1) MCE registering itself for being notified of the arrival of new messages; and // (2) MCE start downloading existing messages off of MSE. // NOTE: the value is not "final" so that it can be modified in the unit tests - @VisibleForTesting - static int sOwnNumberSearchTimeoutMs = 3_000; + @VisibleForTesting static int sOwnNumberSearchTimeoutMs = 3_000; /** * An object to hold the necessary meta-data for each message so we can broadcast it alongside * the message content. * - * This is necessary because the metadata is inferred or received separately from the actual + *

This is necessary because the metadata is inferred or received separately from the actual * message content. * - * Note: In the future it may be best to use the entries from the MessageListing in full instead - * of this small subset. + *

Note: In the future it may be best to use the entries from the MessageListing in full + * instead of this small subset. */ @VisibleForTesting static class MessageMetadata { @@ -213,7 +200,6 @@ class MceStateMachine extends StateMachine { public synchronized boolean getSeen() { return mSeen; } - } // Map each message to its metadata via the handle @@ -230,7 +216,10 @@ class MceStateMachine extends StateMachine { } @VisibleForTesting - MceStateMachine(MapClientService service, BluetoothDevice device, MasClient masClient, + MceStateMachine( + MapClientService service, + BluetoothDevice device, + MasClient masClient, MapClientContent database) { super(TAG); mService = service; @@ -294,8 +283,13 @@ class MceStateMachine extends StateMachine { if (mDevice == null) { return; } - Log.d(TAG, Utils.getLoggableAddress(mDevice) + ": Connection state changed, prev=" - + prevState + ", new=" + state); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + ": Connection state changed, prev=" + + prevState + + ", new=" + + state); if (prevState != state && state == BluetoothProfile.STATE_CONNECTED) { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.MAP_CLIENT); } @@ -312,7 +306,8 @@ class MceStateMachine extends StateMachine { intent.putExtra(BluetoothProfile.EXTRA_STATE, state); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - mService.sendBroadcastMultiplePermissions(intent, + mService.sendBroadcastMultiplePermissions( + intent, new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}, Utils.getTempBroadcastOptions()); } @@ -325,9 +320,7 @@ class MceStateMachine extends StateMachine { return mMostRecentState; } - /** - * Notify of SDP completion. - */ + /** Notify of SDP completion. */ public void sendSdpResult(int status, SdpMasRecord record) { Log.d(TAG, "Received SDP Result, status=" + status + ", record=" + record); if (status != SDP_SUCCESS || record == null) { @@ -344,8 +337,11 @@ class MceStateMachine extends StateMachine { return true; } - public synchronized boolean sendMapMessage(Uri[] contacts, String message, - PendingIntent sentIntent, PendingIntent deliveredIntent) { + public synchronized boolean sendMapMessage( + Uri[] contacts, + String message, + PendingIntent sentIntent, + PendingIntent deliveredIntent) { Log.d(TAG, Utils.getLoggableAddress(mDevice) + ": Send, message=" + message); if (contacts == null || contacts.length <= 0) { return false; @@ -380,8 +376,7 @@ class MceStateMachine extends StateMachine { destEntry.addProperty(destEntryContact); bmsg.addRecipient(destEntry); Log.d(TAG, "SPECIFIC: " + contact.getSchemeSpecificPart()); - Log.d(TAG, "Sending to emails " - + destEntryContact.getValueList()); + Log.d(TAG, "Sending to emails " + destEntryContact.getValueList()); } else { Log.w(TAG, "Scheme " + contact.getScheme() + " not supported."); return false; @@ -459,8 +454,11 @@ class MceStateMachine extends StateMachine { Log.e(TAG, "Invalid parameter for status" + status); return false; } - sendMessage(MSG_SET_MESSAGE_STATUS, 0, 0, new RequestSetMessageStatus( - handle, statusIndicator, value)); + sendMessage( + MSG_SET_MESSAGE_STATUS, + 0, + 0, + new RequestSetMessageStatus(handle, statusIndicator, value)); return true; } return false; @@ -500,8 +498,14 @@ class MceStateMachine extends StateMachine { } public void dump(StringBuilder sb) { - ProfileService.println(sb, "mCurrentDevice: " + mDevice + "(" - + Utils.getName(mDevice) + ") " + this.toString()); + ProfileService.println( + sb, + "mCurrentDevice: " + + mDevice + + "(" + + Utils.getName(mDevice) + + ") " + + this.toString()); if (mDatabase != null) { mDatabase.dump(sb); } else { @@ -513,8 +517,11 @@ class MceStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Disconnected]: Entered, message=" - + getMessageName(getCurrentMessage().what)); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Disconnected]: Entered, message=" + + getMessageName(getCurrentMessage().what)); onConnectionStateChanged(mPreviousState, BluetoothProfile.STATE_DISCONNECTED); mPreviousState = BluetoothProfile.STATE_DISCONNECTED; quit(); @@ -529,8 +536,11 @@ class MceStateMachine extends StateMachine { class Connecting extends State { @Override public void enter() { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Connecting]: Entered, message=" - + getMessageName(getCurrentMessage().what)); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: Entered, message=" + + getMessageName(getCurrentMessage().what)); onConnectionStateChanged(mPreviousState, BluetoothProfile.STATE_CONNECTING); // When commanded to connect begin SDP to find the MAS server. @@ -541,8 +551,11 @@ class MceStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Connecting]: Received " - + getMessageName(message.what)); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: Received " + + getMessageName(message.what)); switch (message.what) { case MSG_MAS_SDP_DONE: @@ -550,8 +563,10 @@ class MceStateMachine extends StateMachine { if (mMasClient == null) { SdpMasRecord record = (SdpMasRecord) message.obj; if (record == null) { - Log.e(TAG, Utils.getLoggableAddress(mDevice) - + " [Connecting]: SDP record is null"); + Log.e( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: SDP record is null"); return NOT_HANDLED; } mMasClient = new MasClient(mDevice, MceStateMachine.this, record); @@ -561,18 +576,25 @@ class MceStateMachine extends StateMachine { case MSG_MAS_SDP_UNSUCCESSFUL: int sdpStatus = message.arg1; - Log.i(TAG, Utils.getLoggableAddress(mDevice) - + " [Connecting]: SDP unsuccessful, status=" + sdpStatus); + Log.i( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: SDP unsuccessful, status=" + + sdpStatus); if (sdpStatus == SDP_BUSY) { - Log.d(TAG, Utils.getLoggableAddress(mDevice) - + " [Connecting]: SDP was busy, try again"); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: SDP was busy, try again"); mDevice.sdpSearch(BluetoothUuid.MAS); } else { // This means the status is 0 (success, but no record) or 1 (organic // failure). We historically have never retried SDP in failure cases, so we // don't need to wait for the timeout anymore. - Log.d(TAG, Utils.getLoggableAddress(mDevice) - + " [Connecting]: SDP failed completely, disconnecting"); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: SDP failed completely, disconnecting"); transitionTo(mDisconnecting); } break; @@ -598,8 +620,11 @@ class MceStateMachine extends StateMachine { break; default: - Log.w(TAG, Utils.getLoggableAddress(mDevice) - + " [Connecting]: Unexpected message: " + getMessageName(message.what)); + Log.w( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connecting]: Unexpected message: " + + getMessageName(message.what)); return NOT_HANDLED; } return HANDLED; @@ -615,15 +640,19 @@ class MceStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Connected]: Entered, message=" - + getMessageName(getCurrentMessage().what)); - - MapClientContent.Callbacks callbacks = new MapClientContent.Callbacks(){ - @Override - public void onMessageStatusChanged(String handle, int status) { - setMessageStatus(handle, status); - } - }; + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: Entered, message=" + + getMessageName(getCurrentMessage().what)); + + MapClientContent.Callbacks callbacks = + new MapClientContent.Callbacks() { + @Override + public void onMessageStatusChanged(String handle, int status) { + setMessageStatus(handle, status); + } + }; // Keeps mock database from being overwritten in tests if (mDatabase == null) { mDatabase = new MapClientContent(mService, callbacks, mDevice); @@ -647,15 +676,18 @@ class MceStateMachine extends StateMachine { RequestGetMessagesListingForOwnNumber requestForOwnNumber = new RequestGetMessagesListingForOwnNumber(); mMasClient.makeRequest(requestForOwnNumber); - sendMessageDelayed(MSG_SEARCH_OWN_NUMBER_TIMEOUT, requestForOwnNumber, - sOwnNumberSearchTimeoutMs); + sendMessageDelayed( + MSG_SEARCH_OWN_NUMBER_TIMEOUT, requestForOwnNumber, sOwnNumberSearchTimeoutMs); Log.i(TAG, Utils.getLoggableAddress(mDevice) + "[Connected]: Find phone number"); } @Override public boolean processMessage(Message message) { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Connected]: Received " - + getMessageName(message.what)); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: Received " + + getMessageName(message.what)); switch (message.what) { case MSG_DISCONNECT: if (mDevice.equals(message.obj)) { @@ -670,14 +702,14 @@ class MceStateMachine extends StateMachine { case MSG_OUTBOUND_MESSAGE: mMasClient.makeRequest( - new RequestPushMessage(FOLDER_OUTBOX, (Bmessage) message.obj, null, - false, false)); + new RequestPushMessage( + FOLDER_OUTBOX, (Bmessage) message.obj, null, false, false)); break; case MSG_INBOUND_MESSAGE: mMasClient.makeRequest( - new RequestGetMessage((String) message.obj, MasClient.CharsetType.UTF_8, - false)); + new RequestGetMessage( + (String) message.obj, MasClient.CharsetType.UTF_8, false)); break; case MSG_NOTIFICATION: @@ -729,18 +761,24 @@ class MceStateMachine extends StateMachine { } else if (message.obj instanceof RequestPushMessage) { RequestPushMessage requestPushMessage = (RequestPushMessage) message.obj; String messageHandle = requestPushMessage.getMsgHandle(); - Log.i(TAG, Utils.getLoggableAddress(mDevice) - + " [Connected]: Message Sent, handle=" + messageHandle); + Log.i( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: Message Sent, handle=" + + messageHandle); // ignore the top-order byte (converted to string) in the handle for now // some test devices don't populate messageHandle field. // in such cases, no need to wait up for response for such messages. if (messageHandle != null && messageHandle.length() > 2) { if (SAVE_OUTBOUND_MESSAGES) { - mDatabase.storeMessage(requestPushMessage.getBMsg(), messageHandle, - System.currentTimeMillis(), MESSAGE_SEEN); + mDatabase.storeMessage( + requestPushMessage.getBMsg(), + messageHandle, + System.currentTimeMillis(), + MESSAGE_SEEN); } - mSentMessageLog.put(messageHandle.substring(2), - requestPushMessage.getBMsg()); + mSentMessageLog.put( + messageHandle.substring(2), requestPushMessage.getBMsg()); } } else if (message.obj instanceof RequestGetMessagesListing) { processMessageListing((RequestGetMessagesListing) message.obj); @@ -780,8 +818,11 @@ class MceStateMachine extends StateMachine { break; default: - Log.w(TAG, Utils.getLoggableAddress(mDevice) - + " [Connected]: Unexpected message: " + getMessageName(message.what)); + Log.w( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: Unexpected message: " + + getMessageName(message.what)); return NOT_HANDLED; } return HANDLED; @@ -798,18 +839,23 @@ class MceStateMachine extends StateMachine { * Given a message notification event, will ensure message caching and updating and update * interested applications. * - * Message notifications arrive for both remote message reception and Message-Listing object - * updates that are triggered by the server side. + *

Message notifications arrive for both remote message reception and Message-Listing + * object updates that are triggered by the server side. * * @param msg - A Message object containing a EventReport object describing the remote event */ private void processNotification(EventReport event) { - Log.i(TAG, Utils.getLoggableAddress(mDevice) - + " [Connected]: Received Notification, event=" + event); + Log.i( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: Received Notification, event=" + + event); if (event == null) { - Log.w(TAG, Utils.getLoggableAddress(mDevice) - + "[Connected]: Notification event is null"); + Log.w( + TAG, + Utils.getLoggableAddress(mDevice) + + "[Connected]: Notification event is null"); return; } @@ -822,12 +868,14 @@ class MceStateMachine extends StateMachine { // false instead of getting the message listing data for it timestamp = Instant.now().toEpochMilli(); } - MessageMetadata metadata = new MessageMetadata(event.getHandle(), - timestamp, false, MESSAGE_NOT_SEEN); + MessageMetadata metadata = + new MessageMetadata( + event.getHandle(), timestamp, false, MESSAGE_NOT_SEEN); mMessages.put(event.getHandle(), metadata); } - mMasClient.makeRequest(new RequestGetMessage(event.getHandle(), - MasClient.CharsetType.UTF_8, false)); + mMasClient.makeRequest( + new RequestGetMessage( + event.getHandle(), MasClient.CharsetType.UTF_8, false)); break; case DELIVERY_FAILURE: // fall through @@ -860,11 +908,15 @@ class MceStateMachine extends StateMachine { * @param request - A request object that has been resolved and returned with a message list */ private void processMessageListing(RequestGetMessagesListing request) { - Log.i(TAG, Utils.getLoggableAddress(mDevice) - + " [Connected]: Received Message Listing, listing=" - + (request != null ? (request.getList() != null - ? String.valueOf(request.getList().size()) - : "null list") : "null request")); + Log.i( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: Received Message Listing, listing=" + + (request != null + ? (request.getList() != null + ? String.valueOf(request.getList().size()) + : "null list") + : "null request")); ArrayList messageListing = request.getList(); if (messageListing != null) { @@ -872,30 +924,41 @@ class MceStateMachine extends StateMachine { // oldest first. Iterate in reverse order so we initiate requests oldest first. for (int i = messageListing.size() - 1; i >= 0; i--) { com.android.bluetooth.mapclient.Message msg = messageListing.get(i); - Log.d(TAG, Utils.getLoggableAddress(mDevice) - + " [Connected]: fetch message content, handle=" + msg.getHandle()); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Connected]: fetch message content, handle=" + + msg.getHandle()); // A message listing coming from the server should always have up to date data if (msg.getDateTime() == null) { - Log.w(TAG, "message with handle " + msg.getHandle() - + " has a null datetime, ignoring"); + Log.w( + TAG, + "message with handle " + + msg.getHandle() + + " has a null datetime, ignoring"); continue; } - mMessages.put(msg.getHandle(), new MessageMetadata(msg.getHandle(), - msg.getDateTime().getTime(), msg.isRead(), MESSAGE_SEEN)); + mMessages.put( + msg.getHandle(), + new MessageMetadata( + msg.getHandle(), + msg.getDateTime().getTime(), + msg.isRead(), + MESSAGE_SEEN)); getMessage(msg.getHandle()); } } } /** - * Process the result of a MessageListing request that was made specifically to obtain - * the remote device's own phone number. + * Process the result of a MessageListing request that was made specifically to obtain the + * remote device's own phone number. * - * @param request - A request object that has been resolved and returned with: - * - a phone number (possibly null if a number wasn't found) - * - a flag indicating whether there are still messages that can be searched/requested. - * - the request will automatically update itself if a number wasn't found and there are - * still messages that can be searched. + * @param request - A request object that has been resolved and returned with: - a phone + * number (possibly null if a number wasn't found) - a flag indicating whether there are + * still messages that can be searched/requested. - the request will automatically + * update itself if a number wasn't found and there are still messages that can be + * searched. */ private void processMessageListingForOwnNumber( RequestGetMessagesListingForOwnNumber request) { @@ -904,8 +967,10 @@ class MceStateMachine extends StateMachine { Log.d(TAG, "processMessageListingForOwnNumber: search completed"); if (request.getOwnNumber() != null) { // A phone number was found (should be the remote device's). - Log.d(TAG, "processMessageListingForOwnNumber: number found = " - + request.getOwnNumber()); + Log.d( + TAG, + "processMessageListingForOwnNumber: number found = " + + request.getOwnNumber()); mDatabase.setRemoteDeviceOwnNumber(request.getOwnNumber()); } // Remove any outstanding timeouts from state machine queue @@ -922,8 +987,8 @@ class MceStateMachine extends StateMachine { } /** - * (1) MCE registering itself for being notified of the arrival of new messages; and - * (2) MCE downloading existing messages of off MSE. + * (1) MCE registering itself for being notified of the arrival of new messages; and (2) MCE + * downloading existing messages of off MSE. */ private void notificationRegistrationAndStartDownloadMessages() { Log.i(TAG, Utils.getLoggableAddress(mDevice) + "[Connected]: Queue Message downloads"); @@ -941,26 +1006,37 @@ class MceStateMachine extends StateMachine { } RequestSetMessageStatus.StatusIndicator status = request.getStatusIndicator(); switch (status) { - case READ: { - Intent intent = new Intent( - BluetoothMapClient.ACTION_MESSAGE_READ_STATUS_CHANGED); - intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_READ_STATUS, - request.getValue() == RequestSetMessageStatus.STATUS_YES ? true : false); - intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_HANDLE, request.getHandle()); - intent.putExtra(BluetoothMapClient.EXTRA_RESULT_CODE, result); - mService.sendBroadcast(intent, BLUETOOTH_CONNECT); - break; - } - case DELETED: { - Intent intent = new Intent( - BluetoothMapClient.ACTION_MESSAGE_DELETED_STATUS_CHANGED); - intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_DELETED_STATUS, - request.getValue() == RequestSetMessageStatus.STATUS_YES ? true : false); - intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_HANDLE, request.getHandle()); - intent.putExtra(BluetoothMapClient.EXTRA_RESULT_CODE, result); - mService.sendBroadcast(intent, BLUETOOTH_CONNECT); - break; - } + case READ: + { + Intent intent = + new Intent(BluetoothMapClient.ACTION_MESSAGE_READ_STATUS_CHANGED); + intent.putExtra( + BluetoothMapClient.EXTRA_MESSAGE_READ_STATUS, + request.getValue() == RequestSetMessageStatus.STATUS_YES + ? true + : false); + intent.putExtra( + BluetoothMapClient.EXTRA_MESSAGE_HANDLE, request.getHandle()); + intent.putExtra(BluetoothMapClient.EXTRA_RESULT_CODE, result); + mService.sendBroadcast(intent, BLUETOOTH_CONNECT); + break; + } + case DELETED: + { + Intent intent = + new Intent( + BluetoothMapClient.ACTION_MESSAGE_DELETED_STATUS_CHANGED); + intent.putExtra( + BluetoothMapClient.EXTRA_MESSAGE_DELETED_STATUS, + request.getValue() == RequestSetMessageStatus.STATUS_YES + ? true + : false); + intent.putExtra( + BluetoothMapClient.EXTRA_MESSAGE_HANDLE, request.getHandle()); + intent.putExtra(BluetoothMapClient.EXTRA_RESULT_CODE, result); + mService.sendBroadcast(intent, BLUETOOTH_CONNECT); + break; + } default: Log.e(TAG, "Unknown status indicator " + status); return; @@ -971,7 +1047,7 @@ class MceStateMachine extends StateMachine { * Given the response of a GetMessage request, will broadcast the bMessage contents on to * all registered applications. * - * Inbound messages arrive as bMessage objects following a GetMessage request. GetMessage + *

Inbound messages arrive as bMessage objects following a GetMessage request. GetMessage * uses a message handle that can arrive from both a GetMessageListing request or a Message * Notification event. * @@ -984,7 +1060,9 @@ class MceStateMachine extends StateMachine { if (message == null) { return; } - mDatabase.storeMessage(message, request.getHandle(), + mDatabase.storeMessage( + message, + request.getHandle(), mMessages.get(request.getHandle()).getTimestamp(), mMessages.get(request.getHandle()).getSeen()); if (!INBOX_PATH.equalsIgnoreCase(message.getFolder())) { @@ -1007,10 +1085,10 @@ class MceStateMachine extends StateMachine { intent.setAction(BluetoothMapClient.ACTION_MESSAGE_RECEIVED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_HANDLE, request.getHandle()); - intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_TIMESTAMP, - metadata.getTimestamp()); - intent.putExtra(BluetoothMapClient.EXTRA_MESSAGE_READ_STATUS, - metadata.getRead()); + intent.putExtra( + BluetoothMapClient.EXTRA_MESSAGE_TIMESTAMP, metadata.getTimestamp()); + intent.putExtra( + BluetoothMapClient.EXTRA_MESSAGE_READ_STATUS, metadata.getRead()); intent.putExtra(android.content.Intent.EXTRA_TEXT, message.getBodyContent()); VCardEntry originator = message.getOriginator(); if (originator != null) { @@ -1020,26 +1098,29 @@ class MceStateMachine extends StateMachine { if (phoneData != null && phoneData.size() > 0) { String phoneNumber = phoneData.get(0).getNumber(); Log.d(TAG, "Originator number: " + phoneNumber); - intent.putExtra(BluetoothMapClient.EXTRA_SENDER_CONTACT_URI, + intent.putExtra( + BluetoothMapClient.EXTRA_SENDER_CONTACT_URI, getContactURIFromPhone(phoneNumber)); } else if (emailData != null && emailData.size() > 0) { String email = emailData.get(0).getAddress(); Log.d(TAG, "Originator email: " + email); - intent.putExtra(BluetoothMapClient.EXTRA_SENDER_CONTACT_URI, + intent.putExtra( + BluetoothMapClient.EXTRA_SENDER_CONTACT_URI, getContactURIFromEmail(email)); } - intent.putExtra(BluetoothMapClient.EXTRA_SENDER_CONTACT_NAME, + intent.putExtra( + BluetoothMapClient.EXTRA_SENDER_CONTACT_NAME, originator.getDisplayName()); } if (message.getType() == Bmessage.Type.MMS) { BluetoothMapbMessageMime mmsBmessage = new BluetoothMapbMessageMime(); mmsBmessage.parseMsgPart(message.getBodyContent()); - intent.putExtra(android.content.Intent.EXTRA_TEXT, - mmsBmessage.getMessageAsText()); + intent.putExtra( + android.content.Intent.EXTRA_TEXT, mmsBmessage.getMessageAsText()); ArrayList recipients = message.getRecipients(); if (recipients != null && !recipients.isEmpty()) { - intent.putExtra(android.content.Intent.EXTRA_CC, - getRecipientsUri(recipients)); + intent.putExtra( + android.content.Intent.EXTRA_CC, getRecipientsUri(recipients)); } } String defaultMessagingPackage = Telephony.Sms.getDefaultSmsPackage(mService); @@ -1050,9 +1131,7 @@ class MceStateMachine extends StateMachine { } else { String smsReceiverPackageName = SystemProperties.get( - "bluetooth.profile.map_client.sms_receiver_package", - null - ); + "bluetooth.profile.map_client.sms_receiver_package", null); if (smsReceiverPackageName != null && !smsReceiverPackageName.isEmpty()) { // Clone intent and broadcast to SMS receiver package if one exists Intent messageNotificationIntent = (Intent) intent.clone(); @@ -1072,8 +1151,9 @@ class MceStateMachine extends StateMachine { } /** - * Retrieves the URIs of all the participants of a group conversation, besides the sender - * of the message. + * Retrieves the URIs of all the participants of a group conversation, besides the sender of + * the message. + * * @param recipients * @return */ @@ -1121,8 +1201,11 @@ class MceStateMachine extends StateMachine { Log.w(TAG, "Notification Request Canceled" + e); } } else { - Log.e(TAG, "Received a notification on message with handle = " - + handle + ", but it is NOT found in mSentMessageLog! where did it go?"); + Log.e( + TAG, + "Received a notification on message with handle = " + + handle + + ", but it is NOT found in mSentMessageLog! where did it go?"); } } } @@ -1130,8 +1213,11 @@ class MceStateMachine extends StateMachine { class Disconnecting extends State { @Override public void enter() { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Disconnecting]: Entered, message=" - + getMessageName(getCurrentMessage().what)); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Disconnecting]: Entered, message=" + + getMessageName(getCurrentMessage().what)); onConnectionStateChanged(mPreviousState, BluetoothProfile.STATE_DISCONNECTING); @@ -1147,8 +1233,11 @@ class MceStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { - Log.d(TAG, Utils.getLoggableAddress(mDevice) + " [Disconnecting]: Received " - + getMessageName(message.what)); + Log.d( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Disconnecting]: Received " + + getMessageName(message.what)); switch (message.what) { case MSG_DISCONNECTING_TIMEOUT: case MSG_MAS_DISCONNECTED: @@ -1162,9 +1251,11 @@ class MceStateMachine extends StateMachine { break; default: - Log.w(TAG, Utils.getLoggableAddress(mDevice) - + " [Disconnecting]: Unexpected message: " - + getMessageName(message.what)); + Log.w( + TAG, + Utils.getLoggableAddress(mDevice) + + " [Disconnecting]: Unexpected message: " + + getMessageName(message.what)); return NOT_HANDLED; } return HANDLED; @@ -1178,8 +1269,7 @@ class MceStateMachine extends StateMachine { } void receiveEvent(EventReport ev) { - Log.d(TAG, "Message Type = " + ev.getType() - + ", Message handle = " + ev.getHandle()); + Log.d(TAG, "Message Type = " + ev.getType() + ", Message handle = " + ev.getHandle()); sendMessage(MSG_NOTIFICATION, ev); } diff --git a/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java b/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java index 3018bf07222..e72cca015c5 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java +++ b/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java @@ -33,27 +33,27 @@ class MnsObexServer extends ServerRequestHandler { private static final String TAG = MnsObexServer.class.getSimpleName(); @VisibleForTesting - static final byte[] MNS_TARGET = new byte[]{ - (byte) 0xbb, - 0x58, - 0x2b, - 0x41, - 0x42, - 0x0c, - 0x11, - (byte) 0xdb, - (byte) 0xb0, - (byte) 0xde, - 0x08, - 0x00, - 0x20, - 0x0c, - (byte) 0x9a, - 0x66 - }; - - @VisibleForTesting - static final String TYPE = "x-bt/MAP-event-report"; + static final byte[] MNS_TARGET = + new byte[] { + (byte) 0xbb, + 0x58, + 0x2b, + 0x41, + 0x42, + 0x0c, + 0x11, + (byte) 0xdb, + (byte) 0xb0, + (byte) 0xde, + 0x08, + 0x00, + 0x20, + 0x0c, + (byte) 0x9a, + 0x66 + }; + + @VisibleForTesting static final String TYPE = "x-bt/MAP-event-report"; private final WeakReference mStateMachineReference; @@ -131,8 +131,8 @@ class MnsObexServer extends ServerRequestHandler { } @Override - public int onSetPath(final HeaderSet request, HeaderSet reply, final boolean backup, - final boolean create) { + public int onSetPath( + final HeaderSet request, HeaderSet reply, final boolean backup, final boolean create) { Log.v(TAG, "onSetPath"); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } diff --git a/android/app/src/com/android/bluetooth/mapclient/MnsService.java b/android/app/src/com/android/bluetooth/mapclient/MnsService.java index afebd7cd36a..1dd18e23262 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MnsService.java +++ b/android/app/src/com/android/bluetooth/mapclient/MnsService.java @@ -30,9 +30,7 @@ import com.android.obex.ServerSession; import java.io.IOException; -/** - * Message Notification Server implementation - */ +/** Message Notification Server implementation */ public class MnsService { private static final String TAG = MnsService.class.getSimpleName(); @@ -46,7 +44,7 @@ public class MnsService { private static ObexServerSockets sServerSockets = null; private static MapClientService sContext; - private volatile boolean mShutdown = false; // Used to interrupt socket accept thread + private volatile boolean mShutdown = false; // Used to interrupt socket accept thread private int mSdpHandle = -1; MnsService(MapClientService context) { @@ -103,9 +101,8 @@ public class MnsService { private class SocketAcceptor implements IObexConnectionHandler { /** - * Called when an unrecoverable error occurred in an accept thread. - * Close down the server socket, and restart. - * TODO: Change to message, to call start in correct context. + * Called when an unrecoverable error occurred in an accept thread. Close down the server + * socket, and restart. TODO: Change to message, to call start in correct context. */ @Override public synchronized void onAcceptFailed() { @@ -122,13 +119,22 @@ public class MnsService { /* Signal to the service that we have received an incoming connection.*/ MceStateMachine stateMachine = sContext.getMceStateMachineForDevice(device); if (stateMachine == null) { - Log.e(TAG, "Error: NO statemachine for device: " + device - + " (name: " + Utils.getName(device)); + Log.e( + TAG, + "Error: NO statemachine for device: " + + device + + " (name: " + + Utils.getName(device)); return false; } else if (stateMachine.getState() != BluetoothProfile.STATE_CONNECTED) { - Log.e(TAG, "Error: statemachine for device: " + device - + " (name: " + Utils.getName(device) + ") is not currently CONNECTED : " - + stateMachine.getCurrentState()); + Log.e( + TAG, + "Error: statemachine for device: " + + device + + " (name: " + + Utils.getName(device) + + ") is not currently CONNECTED : " + + stateMachine.getCurrentState()); return false; } MnsObexServer srv = new MnsObexServer(stateMachine); diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java b/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java index 1a432997c0c..044bbdf70ef 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java @@ -25,9 +25,8 @@ import java.util.ArrayList; /** * Object representation of message in bMessage format - *

- * This object will be received in {@link MasClient#EVENT_GET_MESSAGE} - * callback message. + * + *

This object will be received in {@link MasClient#EVENT_GET_MESSAGE} callback message. */ public class Bmessage { @@ -46,9 +45,7 @@ public class Bmessage { ArrayList mOriginators; ArrayList mRecipients; - /** - * Constructs empty message object - */ + /** Constructs empty message object */ public Bmessage() { mOriginators = new ArrayList(); mRecipients = new ArrayList(); @@ -161,10 +158,14 @@ public class Bmessage { } public enum Status { - READ, UNREAD + READ, + UNREAD } public enum Type { - EMAIL, SMS_GSM, SMS_CDMA, MMS + EMAIL, + SMS_GSM, + SMS_CDMA, + MMS } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/BmessageBuilder.java b/android/app/src/com/android/bluetooth/mapclient/obex/BmessageBuilder.java index ba56285a1d6..a5d0c2e9969 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/BmessageBuilder.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/BmessageBuilder.java @@ -68,8 +68,11 @@ class BmessageBuilder { } private void build(Bmessage bmsg) { - int bodyLen = MSG_BEGIN.length() + MSG_END.length() + 3 * CRLF.length() - + bmsg.mMessage.getBytes().length; + int bodyLen = + MSG_BEGIN.length() + + MSG_END.length() + + 3 * CRLF.length() + + bmsg.mMessage.getBytes().length; mBmsg.append(BMSG_BEGIN).append(CRLF); diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java b/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java index 70a18f23642..337b5f3f541 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java @@ -57,10 +57,11 @@ class BmessageParser { private static final int CRLF_LEN = 2; /** - * length of "container" for 'message' in bmessage-body-content: - * BEGIN:MSG + + END:MSG + * length of "container" for 'message' in bmessage-body-content: BEGIN:MSG + + + * END:MSG */ private static final int MSG_CONTAINER_LEN = 22; + private final Bmessage mBmsg; private BmsgTokenizer mParser; @@ -179,7 +180,6 @@ class BmessageParser { } else if (prop.name.equals("FOLDER")) { mBmsg.mBmsgFolder = prop.value; - } } while (!prop.equals(BEGIN_VCARD) && !prop.equals(BEGIN_BENV)); @@ -275,7 +275,6 @@ class BmessageParser { } catch (NumberFormatException e) { throw new ParseException("Invalid LENGTH value", mParser.pos()); } - } } while (!prop.equals(BEGIN_MSG)); @@ -421,8 +420,8 @@ class BmessageParser { } if (vcard == null) { - throw new ParseException("Cannot parse vCard object (neither 2.1 nor 3.0?)", - mParser.pos()); + throw new ParseException( + "Cannot parse vCard object (neither 2.1 nor 3.0?)", mParser.pos()); } return vcard; @@ -432,8 +431,7 @@ class BmessageParser { public VCardEntry vcard; @Override - public void onStart() { - } + public void onStart() {} @Override public void onEntryCreated(VCardEntry entry) { @@ -441,7 +439,6 @@ class BmessageParser { } @Override - public void onEnd() { - } + public void onEnd() {} } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/BmsgTokenizer.java b/android/app/src/com/android/bluetooth/mapclient/obex/BmsgTokenizer.java index 2c4cd7a1e85..9d15bf44f76 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/BmsgTokenizer.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/BmsgTokenizer.java @@ -100,7 +100,8 @@ public final class BmsgTokenizer { @Override public boolean equals(Object o) { - return ((o instanceof Property) && ((Property) o).name.equals(name) + return ((o instanceof Property) + && ((Property) o).name.equals(name) && ((Property) o).value.equals(value)); } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java b/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java index 215f5db82a9..c883f5c6f3d 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java @@ -34,9 +34,8 @@ import java.util.HashMap; /** * Object representation of event report received by MNS - *

- * This object will be received in {@link Client#EVENT_EVENT_REPORT} - * callback message. + * + *

This object will be received in {@link Client#EVENT_EVENT_REPORT} callback message. */ public class EventReport { private static final String TAG = "EventReport"; @@ -148,48 +147,45 @@ public class EventReport { } /** - * @return {@link EventReport.Type} object corresponding to - * type application parameter in MAP specification + * @return {@link EventReport.Type} object corresponding to type application + * parameter in MAP specification */ public Type getType() { return mType; } /** - * @return value corresponding to handle parameter in MAP - * specification + * @return value corresponding to handle parameter in MAP specification */ public String getHandle() { return mHandle; } /** - * @return value corresponding to folder parameter in MAP - * specification + * @return value corresponding to folder parameter in MAP specification */ public String getFolder() { return mFolder; } /** - * @return value corresponding to old_folder parameter in MAP - * specification + * @return value corresponding to old_folder parameter in MAP specification */ public String getOldFolder() { return mOldFolder; } /** - * @return {@link Bmessage.Type} object corresponding to - * msg_type application parameter in MAP specification + * @return {@link Bmessage.Type} object corresponding to msg_type application + * parameter in MAP specification */ public Bmessage.Type getMsgType() { return mMsgType; } /** - * @return value corresponding to datetime parameter in MAP - * specification for NEW_MESSAGE (can be null) + * @return value corresponding to datetime parameter in MAP specification for + * NEW_MESSAGE (can be null) */ @Nullable public String getDateTime() { @@ -198,7 +194,7 @@ public class EventReport { /** * @return timestamp from the value corresponding to datetime parameter in MAP - * specification for NEW_MESSAGE (can be null) + * specification for NEW_MESSAGE (can be null) */ @Nullable public Long getTimestamp() { diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/Message.java b/android/app/src/com/android/bluetooth/mapclient/obex/Message.java index 007775f409f..ec8403a1b4d 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/Message.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/Message.java @@ -25,9 +25,8 @@ import java.util.HashMap; /** * Object representation of message received in messages listing - *

- * This object will be received in - * {@link Client#EVENT_GET_MESSAGES_LISTING} callback message. + * + *

This object will be received in {@link Client#EVENT_GET_MESSAGES_LISTING} callback message. */ public class Message { @@ -83,14 +82,13 @@ public class Message { mSubject = attrs.get("subject"); String dateTime = attrs.get("datetime"); - //Handle possible NPE when not able to retreive datetime attribute + // Handle possible NPE when not able to retreive datetime attribute if (dateTime != null) { mDateTime = (new ObexTime(dateTime)).getTime(); } else { mDateTime = null; } - mSenderName = attrs.get("sender_name"); mSenderAddressing = attrs.get("sender_addressing"); @@ -192,146 +190,139 @@ public class Message { } /** - * @return value corresponding to handle parameter in MAP - * specification + * @return value corresponding to handle parameter in MAP specification */ public String getHandle() { return mHandle; } /** - * @return value corresponding to subject parameter in MAP - * specification + * @return value corresponding to subject parameter in MAP specification */ public String getSubject() { return mSubject; } /** - * @return Date object corresponding to datetime - * parameter in MAP specification + * @return Date object corresponding to datetime parameter in MAP + * specification */ public Date getDateTime() { return mDateTime; } /** - * @return value corresponding to sender_name parameter in MAP - * specification + * @return value corresponding to sender_name parameter in MAP specification */ public String getSenderName() { return mSenderName; } /** - * @return value corresponding to sender_addressing parameter - * in MAP specification + * @return value corresponding to sender_addressing parameter in MAP specification */ public String getSenderAddressing() { return mSenderAddressing; } /** - * @return value corresponding to replyto_addressing parameter - * in MAP specification + * @return value corresponding to replyto_addressing parameter in MAP specification */ public String getReplytoAddressing() { return mReplytoAddressing; } /** - * @return value corresponding to recipient_name parameter in - * MAP specification + * @return value corresponding to recipient_name parameter in MAP specification */ public String getRecipientName() { return mRecipientName; } /** - * @return value corresponding to recipient_addressing - * parameter in MAP specification + * @return value corresponding to recipient_addressing parameter in MAP + * specification */ public String getRecipientAddressing() { return mRecipientAddressing; } /** - * @return {@link Type} object corresponding to type parameter - * in MAP specification + * @return {@link Type} object corresponding to type parameter in MAP specification */ public Type getType() { return mType; } /** - * @return value corresponding to size parameter in MAP - * specification + * @return value corresponding to size parameter in MAP specification */ public int getSize() { return mSize; } /** - * @return {@link .ReceptionStatus} object corresponding to - * reception_status parameter in MAP specification + * @return {@link .ReceptionStatus} object corresponding to reception_status + * parameter in MAP specification */ public ReceptionStatus getReceptionStatus() { return mReceptionStatus; } /** - * @return value corresponding to attachment_size parameter in - * MAP specification + * @return value corresponding to attachment_size parameter in MAP specification */ public int getAttachmentSize() { return mAttachmentSize; } /** - * @return value corresponding to text parameter in MAP - * specification + * @return value corresponding to text parameter in MAP specification */ public boolean isText() { return mText; } /** - * @return value corresponding to priority parameter in MAP - * specification + * @return value corresponding to priority parameter in MAP specification */ public boolean isPriority() { return mPriority; } /** - * @return value corresponding to read parameter in MAP - * specification + * @return value corresponding to read parameter in MAP specification */ public boolean isRead() { return mRead; } /** - * @return value corresponding to sent parameter in MAP - * specification + * @return value corresponding to sent parameter in MAP specification */ public boolean isSent() { return mSent; } /** - * @return value corresponding to protected parameter in MAP - * specification + * @return value corresponding to protected parameter in MAP specification */ public boolean isProtected() { return mProtected; } public enum Type { - UNKNOWN, EMAIL, SMS_GSM, SMS_CDMA, MMS + UNKNOWN, + EMAIL, + SMS_GSM, + SMS_CDMA, + MMS } public enum ReceptionStatus { - UNKNOWN, COMPLETE, FRACTIONED, NOTIFICATION + UNKNOWN, + COMPLETE, + FRACTIONED, + NOTIFICATION } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java b/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java index 918b0a98fe8..92889176560 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java @@ -38,8 +38,7 @@ public final class MessagesFilter { public byte priority = PRIORITY_ANY; - public MessagesFilter() { - } + public MessagesFilter() {} public MessagesFilter(MessagesFilter filter) { this.messageType = filter.messageType; @@ -56,7 +55,7 @@ public final class MessagesFilter { } public void setPeriod(Date filterBegin, Date filterEnd) { - //Handle possible NPE for obexTime constructor utility + // Handle possible NPE for obexTime constructor utility if (filterBegin != null) { periodBegin = (new ObexTime(filterBegin)).toString(); } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java b/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java index 119975e47f8..cce3c4985a7 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java @@ -45,8 +45,10 @@ public final class ObexTime { * All groups are guaranteed to be numeric so conversion will always succeed (except group 8 * which is either + or -) */ - Pattern p = Pattern.compile( - "(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(([+-])(\\d{2})(\\d{2})" + ")?"); + Pattern p = + Pattern.compile( + "(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(([+-])(\\d{2})(\\d{2})" + + ")?"); Matcher m = p.matcher(time); if (m.matches()) { @@ -59,15 +61,17 @@ public final class ObexTime { Calendar.Builder builder = new Calendar.Builder(); /* Note that Calendar months are zero-based */ - builder.setDate(Integer.parseInt(m.group(1)), /* year */ - Integer.parseInt(m.group(2)) - 1, /* month */ - Integer.parseInt(m.group(3))); /* day of month */ + builder.setDate( + Integer.parseInt(m.group(1)), /* year */ + Integer.parseInt(m.group(2)) - 1, /* month */ + Integer.parseInt(m.group(3))); /* day of month */ /* Note the MAP timestamp doesn't have milliseconds and we're explicitly setting to 0 */ - builder.setTimeOfDay(Integer.parseInt(m.group(4)), /* hours */ - Integer.parseInt(m.group(5)), /* minutes */ - Integer.parseInt(m.group(6)), /* seconds */ - 0); /* milliseconds */ + builder.setTimeOfDay( + Integer.parseInt(m.group(4)), /* hours */ + Integer.parseInt(m.group(5)), /* minutes */ + Integer.parseInt(m.group(6)), /* seconds */ + 0); /* milliseconds */ /* * If 7th group is matched then we're no longer using "Local Time basis" and instead @@ -123,12 +127,18 @@ public final class ObexTime { return null; } - Calendar cal = GregorianCalendar.from( - ZonedDateTime.ofInstant(mInstant, ZoneId.systemDefault())); + Calendar cal = + GregorianCalendar.from(ZonedDateTime.ofInstant(mInstant, ZoneId.systemDefault())); /* note that months are numbered stating from 0 */ - return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d", cal.get(Calendar.YEAR), - cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); + return String.format( + Locale.US, + "%04d%02d%02dT%02d%02d%02d", + cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH) + 1, + cal.get(Calendar.DATE), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + cal.get(Calendar.SECOND)); } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/Request.java b/android/app/src/com/android/bluetooth/mapclient/obex/Request.java index b34ec64082c..0058b7c6401 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/Request.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/Request.java @@ -52,9 +52,7 @@ abstract class Request { protected static final byte OAP_TAGID_STATUS_VALUE = 0x18; protected static final byte OAP_TAGID_MSE_TIME = 0x19; /* used for PUT requests which require filler byte */ - protected static final byte[] FILLER_BYTE = { - 0x30 - }; + protected static final byte[] FILLER_BYTE = {0x30}; protected static final byte NOTIFICATION_ON = 0x01; protected static final byte NOTIFICATION_OFF = 0x00; protected static final byte ATTACHMENT_ON = 0x01; diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java index e2a784ba22a..33e576bdac6 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java @@ -51,7 +51,8 @@ class RequestGetMessage extends Request { ObexAppParameters oap = new ObexAppParameters(); - oap.add(OAP_TAGID_CHARSET, + oap.add( + OAP_TAGID_CHARSET, MasClient.CharsetType.UTF_8.equals(charset) ? CHARSET_UTF8 : CHARSET_NATIVE); oap.add(OAP_TAGID_ATTACHMENT, attachment ? ATTACHMENT_ON : ATTACHMENT_OFF); @@ -81,7 +82,8 @@ class RequestGetMessage extends Request { try { bmsg = baos.toString(StandardCharsets.UTF_8.name()); } catch (UnsupportedEncodingException ex) { - Log.e(TAG, + Log.e( + TAG, "Coudn't decode the bmessage with UTF-8. Something must be really messed up."); return; } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java index 2f7068dbbca..c3ff77c7144 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java @@ -36,8 +36,13 @@ class RequestGetMessagesListing extends Request { private Date mServerTime = null; - RequestGetMessagesListing(String folderName, int parameters, MessagesFilter filter, - int subjectLength, int maxListCount, int listStartOffset) { + RequestGetMessagesListing( + String folderName, + int parameters, + MessagesFilter filter, + int subjectLength, + int maxListCount, + int listStartOffset) { if (subjectLength < 0 || subjectLength > 255) { throw new IllegalArgumentException("subjectLength should be [0..255]"); } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java index aa15fd6c298..852ecfee0df 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java @@ -34,20 +34,20 @@ import java.util.List; import java.util.Locale; /** - * Request to get a listing of messages in directory. Listing is used to determine the - * remote device's own phone number. Searching the SENT folder is the most reliable way - * since there should only be one Originator (From:), as opposed to the INBOX folder, - * where there can be multiple Recipients (To: and Cc:). + * Request to get a listing of messages in directory. Listing is used to determine the remote + * device's own phone number. Searching the SENT folder is the most reliable way since there should + * only be one Originator (From:), as opposed to the INBOX folder, where there can be multiple + * Recipients (To: and Cc:). * - * Ideally, only a single message is needed; however, the Originator (From:) field in the listing - * is optional (not required by specs). Hence, a geometrically increasing sliding window is used - * to request additional message listings until either a number is found or folders have been + *

Ideally, only a single message is needed; however, the Originator (From:) field in the listing + * is optional (not required by specs). Hence, a geometrically increasing sliding window is used to + * request additional message listings until either a number is found or folders have been * exhausted. * - * The sliding window is automated (i.e., offset and size, transitions across folders). Simply use - * the same {@link RequestGetMessagesListingForOwnNumber} repeatedly with {@link - * MasClient#makeRequest}. {@link #isSearchCompleted} indicates when the search is complete, - * i.e., the object cannot be used further. + *

The sliding window is automated (i.e., offset and size, transitions across folders). Simply + * use the same {@link RequestGetMessagesListingForOwnNumber} repeatedly with {@link + * MasClient#makeRequest}. {@link #isSearchCompleted} indicates when the search is complete, i.e., + * the object cannot be used further. */ class RequestGetMessagesListingForOwnNumber extends Request { private static final String TAG = RequestGetMessagesListingForOwnNumber.class.getSimpleName(); @@ -56,25 +56,22 @@ class RequestGetMessagesListingForOwnNumber extends Request { // Search for sent messages (MMS or SMS) first. If that fails, search for received SMS. @VisibleForTesting - static final List FOLDERS_TO_SEARCH = new ArrayList<>(Arrays.asList( - MceStateMachine.FOLDER_SENT, - MceStateMachine.FOLDER_INBOX - )); + static final List FOLDERS_TO_SEARCH = + new ArrayList<>( + Arrays.asList(MceStateMachine.FOLDER_SENT, MceStateMachine.FOLDER_INBOX)); private static final int MAX_LIST_COUNT_INITIAL = 1; // NOTE: the value is not "final" so that it can be modified in the unit tests - @VisibleForTesting - static int sMaxListCountUpperLimit = 65535; + @VisibleForTesting static int sMaxListCountUpperLimit = 65535; private static final int LIST_START_OFFSET_INITIAL = 0; // NOTE: the value is not "final" so that it can be modified in the unit tests - @VisibleForTesting - static int sListStartOffsetUpperLimit = 65535; + @VisibleForTesting static int sListStartOffsetUpperLimit = 65535; /** * A geometrically increasing sliding window for messages to list. * - * E.g., if we don't find the phone number in the 1st message, try the next 2, then the next 4, - * then the next 8, etc. + *

E.g., if we don't find the phone number in the 1st message, try the next 2, then the next + * 4, then the next 8, etc. */ private static class MessagesSlidingWindow { private int mListStartOffset; @@ -84,9 +81,7 @@ class RequestGetMessagesListingForOwnNumber extends Request { reset(); } - /** - * Returns false if start of window exceeds range; o.w. returns true. - */ + /** Returns false if start of window exceeds range; o.w. returns true. */ public boolean moveWindow() { if (mListStartOffset > sListStartOffsetUpperLimit) { return false; @@ -96,9 +91,12 @@ class RequestGetMessagesListingForOwnNumber extends Request { return false; } mMaxListCount = min(2 * mMaxListCount, sMaxListCountUpperLimit); - logD(String.format(Locale.US, - "MessagesSlidingWindow, moveWindow: startOffset=%d, maxCount=%d", - mListStartOffset, mMaxListCount)); + logD( + String.format( + Locale.US, + "MessagesSlidingWindow, moveWindow: startOffset=%d, maxCount=%d", + mListStartOffset, + mMaxListCount)); return true; } @@ -115,6 +113,7 @@ class RequestGetMessagesListingForOwnNumber extends Request { return mMaxListCount; } } + private MessagesSlidingWindow mMessageListingWindow; private ObexAppParameters mOap; @@ -162,19 +161,21 @@ class RequestGetMessagesListingForOwnNumber extends Request { // Search through message listing for own phone number. // Message listings by spec arrive ordered newest first. String folderName = FOLDERS_TO_SEARCH.get(mFolderCounter); - logD(String.format(Locale.US, - "readResponse: Folder=%s, # of msgs=%d, startOffset=%d, maxCount=%d", - folderName, messageListing.size(), - mMessageListingWindow.getStartOffset(), mMessageListingWindow.getMaxCount())); + logD( + String.format( + Locale.US, + "readResponse: Folder=%s, # of msgs=%d, startOffset=%d, maxCount=%d", + folderName, + messageListing.size(), + mMessageListingWindow.getStartOffset(), + mMessageListingWindow.getMaxCount())); String number = null; for (int i = 0; i < messageListing.size(); i++) { Message msg = messageListing.get(i); if (MceStateMachine.FOLDER_INBOX.equals(folderName)) { - number = PhoneNumberUtils.extractNetworkPortion( - msg.getRecipientAddressing()); + number = PhoneNumberUtils.extractNetworkPortion(msg.getRecipientAddressing()); } else if (MceStateMachine.FOLDER_SENT.equals(folderName)) { - number = PhoneNumberUtils.extractNetworkPortion( - msg.getSenderAddressing()); + number = PhoneNumberUtils.extractNetworkPortion(msg.getSenderAddressing()); } if (number != null && !number.trim().isEmpty()) { // Search is completed when a phone number is found @@ -195,7 +196,7 @@ class RequestGetMessagesListingForOwnNumber extends Request { /** * Move on to next folder to start searching (sliding window). * - * Overall search for own-phone-number is completed when we run out of folders to search. + *

Overall search for own-phone-number is completed when we run out of folders to search. */ private void moveToNextFolder() { if (mFolderCounter < FOLDERS_TO_SEARCH.size() - 1) { @@ -208,15 +209,14 @@ class RequestGetMessagesListingForOwnNumber extends Request { } /** - * Tries sliding the window in the current folder. - * - If successful (didn't exceed range), update the headers to reflect new window's - * offset and size. - * - If fails (exceeded range), move on to the next folder. + * Tries sliding the window in the current folder. - If successful (didn't exceed range), update + * the headers to reflect new window's offset and size. - If fails (exceeded range), move on to + * the next folder. */ private void moveToNextWindow() { if (mMessageListingWindow.moveWindow()) { - setListOffsetAndMaxCountInHeaderSet(mMessageListingWindow.getMaxCount(), - mMessageListingWindow.getStartOffset()); + setListOffsetAndMaxCountInHeaderSet( + mMessageListingWindow.getMaxCount(), mMessageListingWindow.getStartOffset()); } else { // Can't slide window anymore, exceeded range; move on to next folder logD("moveToNextWindow: can't slide window anymore, folder complete"); @@ -225,10 +225,8 @@ class RequestGetMessagesListingForOwnNumber extends Request { } /** - * Set up the current folder for searching: - * 1. Updates headers to reflect new folder name. - * 2. Resets the sliding window. - * 3. Updates headers to reflect new window's offset and size. + * Set up the current folder for searching: 1. Updates headers to reflect new folder name. 2. + * Resets the sliding window. 3. Updates headers to reflect new window's offset and size. */ private void setupCurrentFolderForSearch() { String folderName = FOLDERS_TO_SEARCH.get(mFolderCounter); @@ -242,15 +240,22 @@ class RequestGetMessagesListingForOwnNumber extends Request { int maxCount = mMessageListingWindow.getMaxCount(); int offset = mMessageListingWindow.getStartOffset(); setListOffsetAndMaxCountInHeaderSet(maxCount, offset); - logD(String.format(Locale.US, - "setupCurrentFolderForSearch: folder=%s, filter=%d, offset=%d, maxCount=%d", - folderName, filter, maxCount, offset)); + logD( + String.format( + Locale.US, + "setupCurrentFolderForSearch: folder=%s, filter=%d, offset=%d, maxCount=%d", + folderName, + filter, + maxCount, + offset)); } private byte messageTypeBasedOnFolder(String folderName) { - byte messageType = (byte) (MessagesFilter.MESSAGE_TYPE_SMS_GSM - | MessagesFilter.MESSAGE_TYPE_SMS_CDMA - | MessagesFilter.MESSAGE_TYPE_MMS); + byte messageType = + (byte) + (MessagesFilter.MESSAGE_TYPE_SMS_GSM + | MessagesFilter.MESSAGE_TYPE_SMS_CDMA + | MessagesFilter.MESSAGE_TYPE_MMS); // If trying to grab own number from messages received by the remote device, // only use SMS messages since SMS will only have one recipient (the remote device), @@ -259,8 +264,10 @@ class RequestGetMessagesListingForOwnNumber extends Request { // Bluetooth in a group MMS, it may not necessarily correspond to the remote device; // there is no specification governing the `To:` and `Cc:` fields in the MMS specs. if (MceStateMachine.FOLDER_INBOX.equals(folderName)) { - messageType = (byte) (MessagesFilter.MESSAGE_TYPE_SMS_GSM - | MessagesFilter.MESSAGE_TYPE_SMS_CDMA); + messageType = + (byte) + (MessagesFilter.MESSAGE_TYPE_SMS_GSM + | MessagesFilter.MESSAGE_TYPE_SMS_CDMA); } return messageType; @@ -274,10 +281,10 @@ class RequestGetMessagesListingForOwnNumber extends Request { } /** - * Returns {@code null} if {@code readResponse} has not completed or if no - * phone number was obtained from the Message Listing. + * Returns {@code null} if {@code readResponse} has not completed or if no phone number was + * obtained from the Message Listing. * - * Otherwise, returns the remote device's own phone number. + *

Otherwise, returns the remote device's own phone number. */ public String getOwnNumber() { return mPhoneNumber; diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java index 07e01356b83..08e24dd4905 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java @@ -42,8 +42,8 @@ public class RequestPushMessage extends Request { mHeaderSet.setHeader(HeaderSet.NAME, folder); } - RequestPushMessage(String folder, Bmessage msg, CharsetType charset, boolean transparent, - boolean retry) { + RequestPushMessage( + String folder, Bmessage msg, CharsetType charset, boolean transparent, boolean retry) { this(folder); mMsg = msg; ObexAppParameters oap = new ObexAppParameters(); diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java index 5de30745538..75ff6140770 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java @@ -25,7 +25,11 @@ import com.android.obex.HeaderSet; import java.io.IOException; final class RequestSetMessageStatus extends Request { - public enum StatusIndicator { READ, DELETED } + public enum StatusIndicator { + READ, + DELETED + } + private static final String TAG = "RequestSetMessageStatus"; private static final String TYPE = "x-bt/messageStatus"; private static StatusIndicator mStatusInd; @@ -36,11 +40,12 @@ final class RequestSetMessageStatus extends Request { mHeaderSet.setHeader(HeaderSet.NAME, handle); ObexAppParameters oap = new ObexAppParameters(); - oap.add(OAP_TAGID_STATUS_INDICATOR, - statusInd == StatusIndicator.READ ? STATUS_INDICATOR_READ - : STATUS_INDICATOR_DELETED); - oap.add(OAP_TAGID_STATUS_VALUE, value == STATUS_YES ? STATUS_YES - : STATUS_NO); + oap.add( + OAP_TAGID_STATUS_INDICATOR, + statusInd == StatusIndicator.READ + ? STATUS_INDICATOR_READ + : STATUS_INDICATOR_DELETED); + oap.add(OAP_TAGID_STATUS_VALUE, value == STATUS_YES ? STATUS_YES : STATUS_NO); oap.addToHeaderSet(mHeaderSet); mStatusInd = statusInd; mValue = value; diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetNotificationRegistration.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetNotificationRegistration.java index 9b25a52789a..74f9f92a759 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetNotificationRegistration.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetNotificationRegistration.java @@ -16,7 +16,6 @@ package com.android.bluetooth.mapclient; - import com.android.bluetooth.ObexAppParameters; import com.android.obex.ClientSession; import com.android.obex.HeaderSet; diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetPath.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetPath.java index cde76b2477e..505afa3188b 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetPath.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetPath.java @@ -68,6 +68,8 @@ class RequestSetPath extends Request { } enum SetPathDir { - ROOT, UP, DOWN + ROOT, + UP, + DOWN } } diff --git a/android/app/src/com/android/bluetooth/mcp/McpService.java b/android/app/src/com/android/bluetooth/mcp/McpService.java index 84832e2e610..a149e0cca79 100644 --- a/android/app/src/com/android/bluetooth/mcp/McpService.java +++ b/android/app/src/com/android/bluetooth/mcp/McpService.java @@ -39,9 +39,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -/** - * Provides Media Control Profile, as a service in the Bluetooth application. - */ +/** Provides Media Control Profile, as a service in the Bluetooth application. */ public class McpService extends ProfileService { private static final String TAG = "BluetoothMcpService"; @@ -49,8 +47,10 @@ public class McpService extends ProfileService { private static MediaControlProfile sGmcsForTesting; private final Object mLock = new Object(); + @GuardedBy("mLock") private MediaControlProfile mGmcs; + private Map mDeviceAuthorizations = new HashMap<>(); private Handler mHandler = new Handler(Looper.getMainLooper()); @@ -114,13 +114,14 @@ public class McpService extends ProfileService { } mGmcs = new MediaControlProfile(this); // Requires this service to be already started thus we have to make it an async call - mHandler.post(() -> { - synchronized (mLock) { - if (mGmcs != null) { - mGmcs.init(); - } - } - }); + mHandler.post( + () -> { + synchronized (mLock) { + if (mGmcs != null) { + mGmcs.init(); + } + } + }); } } } @@ -200,10 +201,11 @@ public class McpService extends ProfileService { } public void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { - Log.i(TAG, "\tsetDeviceAuthorized(): device: " + device + ", isAuthorized: " - + isAuthorized); - int authorization = isAuthorized ? BluetoothDevice.ACCESS_ALLOWED - : BluetoothDevice.ACCESS_REJECTED; + Log.i( + TAG, + "\tsetDeviceAuthorized(): device: " + device + ", isAuthorized: " + isAuthorized); + int authorization = + isAuthorized ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; mDeviceAuthorizations.put(device, authorization); synchronized (mLock) { @@ -220,8 +222,12 @@ public class McpService extends ProfileService { * 2. authorized devices * 3. Any LeAudio devices which are allowed to connect */ - int authorization = mDeviceAuthorizations.getOrDefault(device, Utils.isPtsTestMode() - ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_UNKNOWN); + int authorization = + mDeviceAuthorizations.getOrDefault( + device, + Utils.isPtsTestMode() + ? BluetoothDevice.ACCESS_ALLOWED + : BluetoothDevice.ACCESS_UNKNOWN); if (authorization != BluetoothDevice.ACCESS_UNKNOWN) { return authorization; } @@ -272,11 +278,9 @@ public class McpService extends ProfileService { } } - /** - * Binder object: must be a static class or memory leak may occur - */ - static class BluetoothMcpServiceBinder - extends IBluetoothMcpServiceManager.Stub implements IProfileServiceBinder { + /** Binder object: must be a static class or memory leak may occur */ + static class BluetoothMcpServiceBinder extends IBluetoothMcpServiceManager.Stub + implements IProfileServiceBinder { private McpService mService; BluetoothMcpServiceBinder(McpService svc) { @@ -292,8 +296,8 @@ public class McpService extends ProfileService { } @Override - public void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized, - AttributionSource source) { + public void setDeviceAuthorized( + BluetoothDevice device, boolean isAuthorized, AttributionSource source) { McpService service = getService(); if (service == null) { return; diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java index a6107166e5e..84f2f57abad 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java @@ -69,7 +69,7 @@ import java.util.UUID; * the GATT Service logic, allowing the higher level layer to control the service state and react to * bluetooth peer device requests through the method calls and callback mechanism. * - * Implemented according to Media Control Service v1.0 specification. + *

Implemented according to Media Control Service v1.0 specification. */ public class MediaControlGattService implements MediaControlGattServiceInterface { private static final String TAG = "MediaControlGattService"; @@ -214,9 +214,15 @@ public class MediaControlGattService implements MediaControlGattServiceInterface WRITE_DESCRIPTOR, } - GattOpContext(Operation operation, int requestId, - BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor, - boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { + GattOpContext( + Operation operation, + int requestId, + BluetoothGattCharacteristic characteristic, + BluetoothGattDescriptor descriptor, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value) { mOperation = operation; mRequestId = requestId; mCharacteristic = characteristic; @@ -227,8 +233,11 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mValue = value; } - GattOpContext(Operation operation, int requestId, - BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor) { + GattOpContext( + Operation operation, + int requestId, + BluetoothGattCharacteristic characteristic, + BluetoothGattDescriptor descriptor) { mOperation = operation; mRequestId = requestId; mCharacteristic = characteristic; @@ -249,122 +258,182 @@ public class MediaControlGattService implements MediaControlGattServiceInterface public byte[] mValue; } - private final Map mCharWriteCallback = Map.of( - UUID_TRACK_POSITION, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "TRACK_POSITION write request"); - int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; - if (value.length == 4) { - status = BluetoothGatt.GATT_SUCCESS; - ByteBuffer bb = ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN); - handleTrackPositionRequest(bb.getInt()); - } - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_PLAYBACK_SPEED, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "PLAYBACK_SPEED write request"); - int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; - if (value.length == 1) { - status = BluetoothGatt.GATT_SUCCESS; - - Integer intVal = characteristic.getIntValue( - BluetoothGattCharacteristic.FORMAT_SINT8, 0); - // Don't bother player with the same value - if (intVal == value[0]) { - notifyCharacteristic(characteristic, null); - } else { - handlePlaybackSpeedRequest(value[0]); - } - } - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_CURRENT_TRACK_OBJ_ID, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "CURRENT_TRACK_OBJ_ID write request"); - int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; - if (value.length == 6) { - status = BluetoothGatt.GATT_SUCCESS; - handleObjectIdRequest( - ObjectIds.CURRENT_TRACK_OBJ_ID, byteArray2ObjId(value)); - } - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_NEXT_TRACK_OBJ_ID, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "NEXT_TRACK_OBJ_ID write request"); - int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; - if (value.length == 6) { - status = BluetoothGatt.GATT_SUCCESS; - handleObjectIdRequest(ObjectIds.NEXT_TRACK_OBJ_ID, byteArray2ObjId(value)); - } - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_CURRENT_GROUP_OBJ_ID, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "CURRENT_GROUP_OBJ_ID write request"); - int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; - if (value.length == 6) { - status = BluetoothGatt.GATT_SUCCESS; - handleObjectIdRequest( - ObjectIds.CURRENT_GROUP_OBJ_ID, byteArray2ObjId(value)); - } - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_PLAYING_ORDER, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "PLAYING_ORDER write request"); - int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; - Integer currentPlayingOrder = null; - - if (characteristic.getValue() != null) { - currentPlayingOrder = characteristic.getIntValue( - BluetoothGattCharacteristic.FORMAT_UINT8, 0); - } - - if (value.length == 1 - && (currentPlayingOrder == null || currentPlayingOrder != value[0])) { - status = BluetoothGatt.GATT_SUCCESS; - BluetoothGattCharacteristic supportedPlayingOrderChar = - mCharacteristics.get(CharId.PLAYING_ORDER_SUPPORTED); - Integer supportedPlayingOrder = - supportedPlayingOrderChar.getIntValue( - BluetoothGattCharacteristic.FORMAT_UINT16, 0); - - if ((supportedPlayingOrder & (1 << (value[0] - 1))) != 0) { - handlePlayingOrderRequest(value[0]); - } - } - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_MEDIA_CONTROL_POINT, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "MEDIA_CONTROL_POINT write request"); - int status = handleMediaControlPointRequest(device, value); - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); - } - }, - UUID_SEARCH_CONTROL_POINT, - (device, requestId, characteristic, preparedWrite, responseNeeded, offset, value) -> { - Log.d(TAG, "SEARCH_CONTROL_POINT write request"); - // TODO: There is no Object Trasfer Service implementation. - if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, 0, offset, value); - } - }); + private final Map mCharWriteCallback = + Map.of( + UUID_TRACK_POSITION, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "TRACK_POSITION write request"); + int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; + if (value.length == 4) { + status = BluetoothGatt.GATT_SUCCESS; + ByteBuffer bb = ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN); + handleTrackPositionRequest(bb.getInt()); + } + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_PLAYBACK_SPEED, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "PLAYBACK_SPEED write request"); + int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; + if (value.length == 1) { + status = BluetoothGatt.GATT_SUCCESS; + + Integer intVal = + characteristic.getIntValue( + BluetoothGattCharacteristic.FORMAT_SINT8, 0); + // Don't bother player with the same value + if (intVal == value[0]) { + notifyCharacteristic(characteristic, null); + } else { + handlePlaybackSpeedRequest(value[0]); + } + } + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_CURRENT_TRACK_OBJ_ID, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "CURRENT_TRACK_OBJ_ID write request"); + int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; + if (value.length == 6) { + status = BluetoothGatt.GATT_SUCCESS; + handleObjectIdRequest( + ObjectIds.CURRENT_TRACK_OBJ_ID, byteArray2ObjId(value)); + } + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_NEXT_TRACK_OBJ_ID, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "NEXT_TRACK_OBJ_ID write request"); + int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; + if (value.length == 6) { + status = BluetoothGatt.GATT_SUCCESS; + handleObjectIdRequest( + ObjectIds.NEXT_TRACK_OBJ_ID, byteArray2ObjId(value)); + } + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_CURRENT_GROUP_OBJ_ID, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "CURRENT_GROUP_OBJ_ID write request"); + int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; + if (value.length == 6) { + status = BluetoothGatt.GATT_SUCCESS; + handleObjectIdRequest( + ObjectIds.CURRENT_GROUP_OBJ_ID, byteArray2ObjId(value)); + } + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_PLAYING_ORDER, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "PLAYING_ORDER write request"); + int status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; + Integer currentPlayingOrder = null; + + if (characteristic.getValue() != null) { + currentPlayingOrder = + characteristic.getIntValue( + BluetoothGattCharacteristic.FORMAT_UINT8, 0); + } + + if (value.length == 1 + && (currentPlayingOrder == null + || currentPlayingOrder != value[0])) { + status = BluetoothGatt.GATT_SUCCESS; + BluetoothGattCharacteristic supportedPlayingOrderChar = + mCharacteristics.get(CharId.PLAYING_ORDER_SUPPORTED); + Integer supportedPlayingOrder = + supportedPlayingOrderChar.getIntValue( + BluetoothGattCharacteristic.FORMAT_UINT16, 0); + + if ((supportedPlayingOrder & (1 << (value[0] - 1))) != 0) { + handlePlayingOrderRequest(value[0]); + } + } + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_MEDIA_CONTROL_POINT, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "MEDIA_CONTROL_POINT write request"); + int status = handleMediaControlPointRequest(device, value); + if (responseNeeded) { + mBluetoothGattServer.sendResponse( + device, requestId, status, offset, value); + } + }, + UUID_SEARCH_CONTROL_POINT, + (device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value) -> { + Log.d(TAG, "SEARCH_CONTROL_POINT write request"); + // TODO: There is no Object Trasfer Service implementation. + if (responseNeeded) { + mBluetoothGattServer.sendResponse(device, requestId, 0, offset, value); + } + }); private long millisecondsToMcsInterval(long interval) { /* MCS presents time in 0.01s intervals */ @@ -512,7 +581,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface + (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN")); switch (op.mOperation) { - /* Allow not yet authorized devices to subscribe for notifications */ + /* Allow not yet authorized devices to subscribe for notifications */ case READ_DESCRIPTOR: if (op.mOffset > 1) { mBluetoothGattServer.sendResponse( @@ -602,8 +671,9 @@ public class MediaControlGattService implements MediaControlGattServiceInterface switch (op.mOperation) { case READ_CHARACTERISTIC: // Always ask for the latest position - if (op.mCharacteristic.getUuid().equals( - mCharacteristics.get(CharId.TRACK_POSITION).getUuid())) { + if (op.mCharacteristic + .getUuid() + .equals(mCharacteristics.get(CharId.TRACK_POSITION).getUuid())) { long positionMs = mCallbacks.onGetCurrentTrackPosition(); final int position = (positionMs != TRACK_POSITION_UNAVAILABLE) @@ -614,23 +684,36 @@ public class MediaControlGattService implements MediaControlGattServiceInterface ByteBuffer.allocate(Integer.BYTES).order(ByteOrder.LITTLE_ENDIAN); bb.putInt(position); - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_SUCCESS, op.mOffset, + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_SUCCESS, + op.mOffset, Arrays.copyOfRange(bb.array(), op.mOffset, Integer.BYTES)); return; } if (op.mCharacteristic.getValue() != null) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_SUCCESS, op.mOffset, - Arrays.copyOfRange(op.mCharacteristic.getValue(), op.mOffset, + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_SUCCESS, + op.mOffset, + Arrays.copyOfRange( + op.mCharacteristic.getValue(), + op.mOffset, op.mCharacteristic.getValue().length)); } else { - Log.e(TAG, + Log.e( + TAG, "Missing characteristic value for char: " + op.mCharacteristic.getUuid()); - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH, op.mOffset, new byte[]{}); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH, + op.mOffset, + new byte[] {}); } break; @@ -643,8 +726,13 @@ public class MediaControlGattService implements MediaControlGattServiceInterface CharacteristicWriteHandler handler = mCharWriteCallback.get(op.mCharacteristic.getUuid()); handler.onCharacteristicWriteRequest( - device, op.mRequestId, op.mCharacteristic, op.mPreparedWrite, - op.mResponseNeeded, op.mOffset, op.mValue); + device, + op.mRequestId, + op.mCharacteristic, + op.mPreparedWrite, + op.mResponseNeeded, + op.mOffset, + op.mValue); break; } @@ -656,8 +744,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface case READ_DESCRIPTOR: if (op.mOffset > 1) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INVALID_OFFSET, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INVALID_OFFSET, + op.mOffset, + null); break; } @@ -680,8 +772,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface status = BluetoothGatt.GATT_INVALID_OFFSET; } else { status = BluetoothGatt.GATT_SUCCESS; - setCcc(device, op.mDescriptor.getCharacteristic().getUuid(), op.mOffset, - op.mValue, true); + setCcc( + device, + op.mDescriptor.getCharacteristic().getUuid(), + op.mOffset, + op.mValue, + true); } if (op.mResponseNeeded) { @@ -714,13 +810,21 @@ public class MediaControlGattService implements MediaControlGattServiceInterface switch (op.mOperation) { case READ_CHARACTERISTIC: case READ_DESCRIPTOR: - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, + op.mOffset, + null); break; case WRITE_CHARACTERISTIC: if (op.mResponseNeeded) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, + op.mOffset, + null); } else { // In case of control point operations we can send an application error code if (op.mCharacteristic.getUuid().equals(UUID_MEDIA_CONTROL_POINT)) { @@ -734,8 +838,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface break; case WRITE_DESCRIPTOR: if (op.mResponseNeeded) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, + op.mOffset, + null); } break; @@ -786,8 +894,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mEventLogger.logd( TAG, "restoreCccValuesForStoredDevices: device= " + device + ", char= " + uuid); - setCcc(device, uuid.getUuid(), 0, - BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE, false); + setCcc( + device, + uuid.getUuid(), + 0, + BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE, + false); } } } @@ -806,157 +918,228 @@ public class MediaControlGattService implements MediaControlGattServiceInterface }; @VisibleForTesting - final BluetoothGattServerCallback mServerCallback = new BluetoothGattServerCallback() { - @Override - public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { - super.onConnectionStateChange(device, status, newState); - Log.d(TAG, "BluetoothGattServerCallback: onConnectionStateChange"); - if (newState == BluetoothProfile.STATE_DISCONNECTED) { - ClearUnauthorizedGattOperations(device); - } - } - - @Override - public void onServiceAdded(int status, BluetoothGattService service) { - super.onServiceAdded(status, service); - Log.d(TAG, "BluetoothGattServerCallback: onServiceAdded"); - - if (mCallbacks != null) { - mCallbacks.onServiceInstanceRegistered((status != BluetoothGatt.GATT_SUCCESS) - ? ServiceStatus.UNKNOWN_ERROR - : ServiceStatus.OK, - MediaControlGattService.this); - } - - mCharacteristics.get(CharId.CONTENT_CONTROL_ID) - .setValue(mCcid, BluetoothGattCharacteristic.FORMAT_UINT8, 0); - restoreCccValuesForStoredDevices(); - setInitialCharacteristicValuesAndNotify(); - initialStateRequest(); - } - - @Override - public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattCharacteristic characteristic) { - super.onCharacteristicReadRequest(device, requestId, offset, characteristic); - Log.d(TAG, "BluetoothGattServerCallback: onCharacteristicReadRequest offset= " - + offset + " entire value= " + Arrays.toString(characteristic.getValue())); - - if ((characteristic.getProperties() & PROPERTY_READ) == 0) { - mBluetoothGattServer.sendResponse(device, requestId, - BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, offset, null); - return; - } + final BluetoothGattServerCallback mServerCallback = + new BluetoothGattServerCallback() { + @Override + public void onConnectionStateChange( + BluetoothDevice device, int status, int newState) { + super.onConnectionStateChange(device, status, newState); + Log.d(TAG, "BluetoothGattServerCallback: onConnectionStateChange"); + if (newState == BluetoothProfile.STATE_DISCONNECTED) { + ClearUnauthorizedGattOperations(device); + } + } - GattOpContext op = new GattOpContext( - GattOpContext.Operation.READ_CHARACTERISTIC, requestId, characteristic, null); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } + @Override + public void onServiceAdded(int status, BluetoothGattService service) { + super.onServiceAdded(status, service); + Log.d(TAG, "BluetoothGattServerCallback: onServiceAdded"); + + if (mCallbacks != null) { + mCallbacks.onServiceInstanceRegistered( + (status != BluetoothGatt.GATT_SUCCESS) + ? ServiceStatus.UNKNOWN_ERROR + : ServiceStatus.OK, + MediaControlGattService.this); + } - @Override - public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattCharacteristic characteristic, boolean preparedWrite, - boolean responseNeeded, int offset, byte[] value) { - super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, - responseNeeded, offset, value); - Log.d(TAG, - "BluetoothGattServerCallback: " - + "onCharacteristicWriteRequest"); + mCharacteristics + .get(CharId.CONTENT_CONTROL_ID) + .setValue(mCcid, BluetoothGattCharacteristic.FORMAT_UINT8, 0); + restoreCccValuesForStoredDevices(); + setInitialCharacteristicValuesAndNotify(); + initialStateRequest(); + } - if ((characteristic.getProperties() & PROPERTY_WRITE) - == 0) { - mBluetoothGattServer.sendResponse( - device, requestId, BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, offset, value); - return; - } + @Override + public void onCharacteristicReadRequest( + BluetoothDevice device, + int requestId, + int offset, + BluetoothGattCharacteristic characteristic) { + super.onCharacteristicReadRequest(device, requestId, offset, characteristic); + Log.d( + TAG, + "BluetoothGattServerCallback: onCharacteristicReadRequest offset= " + + offset + + " entire value= " + + Arrays.toString(characteristic.getValue())); + + if ((characteristic.getProperties() & PROPERTY_READ) == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, + offset, + null); + return; + } - GattOpContext op = new GattOpContext(GattOpContext.Operation.WRITE_CHARACTERISTIC, - requestId, characteristic, null, preparedWrite, responseNeeded, offset, value); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.READ_CHARACTERISTIC, + requestId, + characteristic, + null); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } - @Override - public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattDescriptor descriptor) { - super.onDescriptorReadRequest(device, requestId, offset, descriptor); - Log.d(TAG, - "BluetoothGattServerCallback: " - + "onDescriptorReadRequest"); + @Override + public void onCharacteristicWriteRequest( + BluetoothDevice device, + int requestId, + BluetoothGattCharacteristic characteristic, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value) { + super.onCharacteristicWriteRequest( + device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value); + Log.d(TAG, "BluetoothGattServerCallback: " + "onCharacteristicWriteRequest"); + + if ((characteristic.getProperties() & PROPERTY_WRITE) == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, + offset, + value); + return; + } - if ((descriptor.getPermissions() & BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED) - == 0) { - mBluetoothGattServer.sendResponse( - device, requestId, BluetoothGatt.GATT_READ_NOT_PERMITTED, offset, null); - return; - } + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.WRITE_CHARACTERISTIC, + requestId, + characteristic, + null, + preparedWrite, + responseNeeded, + offset, + value); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } - GattOpContext op = new GattOpContext( - GattOpContext.Operation.READ_DESCRIPTOR, requestId, null, descriptor); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } + @Override + public void onDescriptorReadRequest( + BluetoothDevice device, + int requestId, + int offset, + BluetoothGattDescriptor descriptor) { + super.onDescriptorReadRequest(device, requestId, offset, descriptor); + Log.d(TAG, "BluetoothGattServerCallback: " + "onDescriptorReadRequest"); + + if ((descriptor.getPermissions() + & BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED) + == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_READ_NOT_PERMITTED, + offset, + null); + return; + } - @Override - public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, - int offset, byte[] value) { - super.onDescriptorWriteRequest( - device, requestId, descriptor, preparedWrite, responseNeeded, offset, value); - Log.d(TAG, - "BluetoothGattServerCallback: " - + "onDescriptorWriteRequest"); + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.READ_DESCRIPTOR, + requestId, + null, + descriptor); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } - if ((descriptor.getPermissions() & BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED) - == 0) { - mBluetoothGattServer.sendResponse( - device, requestId, BluetoothGatt.GATT_WRITE_NOT_PERMITTED, offset, value); - return; - } + @Override + public void onDescriptorWriteRequest( + BluetoothDevice device, + int requestId, + BluetoothGattDescriptor descriptor, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value) { + super.onDescriptorWriteRequest( + device, + requestId, + descriptor, + preparedWrite, + responseNeeded, + offset, + value); + Log.d(TAG, "BluetoothGattServerCallback: " + "onDescriptorWriteRequest"); + + if ((descriptor.getPermissions() + & BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED) + == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_WRITE_NOT_PERMITTED, + offset, + value); + return; + } - GattOpContext op = new GattOpContext(GattOpContext.Operation.WRITE_DESCRIPTOR, - requestId, null, descriptor, preparedWrite, responseNeeded, offset, value); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } - }; + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.WRITE_DESCRIPTOR, + requestId, + null, + descriptor, + preparedWrite, + responseNeeded, + offset, + value); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } + }; private void initialStateRequest() { List field_list = new ArrayList<>(); @@ -1019,8 +1202,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface /** * A proxy class that facilitates testing of the McpService class. * - * This is necessary due to the "final" attribute of the BluetoothGattServer class. In order to - * test the correct functioning of the McpService class, the final class must be put into a + *

This is necessary due to the "final" attribute of the BluetoothGattServer class. In order + * to test the correct functioning of the McpService class, the final class must be put into a * container that can be mocked correctly. */ public class BluetoothGattServerProxy { @@ -1049,8 +1232,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface return mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); } - public boolean notifyCharacteristicChanged(BluetoothDevice device, - BluetoothGattCharacteristic characteristic, boolean confirm) { + public boolean notifyCharacteristicChanged( + BluetoothDevice device, + BluetoothGattCharacteristic characteristic, + boolean confirm) { return mBluetoothGattServer.notifyCharacteristicChanged( device, characteristic, confirm); } @@ -1065,15 +1250,17 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } } - protected MediaControlGattService(McpService mcpService, - @NonNull MediaControlServiceCallbacks callbacks, int ccid) { + protected MediaControlGattService( + McpService mcpService, @NonNull MediaControlServiceCallbacks callbacks, int ccid) { mContext = mcpService; mCallbacks = callbacks; mCcid = ccid; mMcpService = mcpService; - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService shouldn't be null when creating MediaControlCattService"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService shouldn't be null when creating MediaControlCattService"); mAdapterService.registerBluetoothStateCallback( mContext.getMainExecutor(), mBluetoothStateChangeCallback); @@ -1116,9 +1303,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private void handleTrackPositionRequest(long position) { - final long positionMs = (position != INTERVAL_UNAVAILABLE) - ? mcsIntervalToMilliseconds(position) - : TRACK_POSITION_UNAVAILABLE; + final long positionMs = + (position != INTERVAL_UNAVAILABLE) + ? mcsIntervalToMilliseconds(position) + : TRACK_POSITION_UNAVAILABLE; mEventLogger.add("handleTrackPositionRequest: positionMs= " + positionMs); mCallbacks.onTrackPositionSetRequest(positionMs); } @@ -1142,18 +1330,25 @@ public class MediaControlGattService implements MediaControlGattServiceInterface // Test for RFU bits and currently supported opcodes if (!isOpcodeSupported(opcode)) { - Log.i(TAG, "handleMediaControlPointRequest: " + Request.Opcodes.toString(opcode) - + " not supported"); - mHandler.post(() -> { - setMediaControlRequestResult(new Request(opcode, 0), - Request.Results.OPCODE_NOT_SUPPORTED); - }); + Log.i( + TAG, + "handleMediaControlPointRequest: " + + Request.Opcodes.toString(opcode) + + " not supported"); + mHandler.post( + () -> { + setMediaControlRequestResult( + new Request(opcode, 0), Request.Results.OPCODE_NOT_SUPPORTED); + }); return BluetoothGatt.GATT_SUCCESS; } if (getMediaControlPointRequestPayloadLength(opcode) != (value.length - payloadOffset)) { - Log.w(TAG, "handleMediaControlPointRequest: " + Request.Opcodes.toString(opcode) - + " bad payload length"); + Log.w( + TAG, + "handleMediaControlPointRequest: " + + Request.Opcodes.toString(opcode) + + " bad payload length"); return BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; } @@ -1163,9 +1358,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface || opcode == Request.Opcodes.GOTO_SEGMENT || opcode == Request.Opcodes.GOTO_TRACK || opcode == Request.Opcodes.GOTO_GROUP) { - intVal = ByteBuffer.wrap(value, payloadOffset, value.length - payloadOffset) - .order(ByteOrder.LITTLE_ENDIAN) - .getInt(); + intVal = + ByteBuffer.wrap(value, payloadOffset, value.length - payloadOffset) + .order(ByteOrder.LITTLE_ENDIAN) + .getInt(); // If the argument is time interval, convert to milliseconds time domain if (opcode == Request.Opcodes.MOVE_RELATIVE) { @@ -1227,7 +1423,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface BluetoothGattServer server = manager.openGattServer(mContext, mServerCallback); if (server == null) { Log.e(TAG, "Failed to start BluetoothGattServer for MCP"); - //TODO: This now effectively makes MCP unusable, but fixes tests + // TODO: This now effectively makes MCP unusable, but fixes tests // Handle this error more gracefully, verify BluetoothInstrumentationTests // are passing after fix is applied return false; @@ -1243,18 +1439,19 @@ public class MediaControlGattService implements MediaControlGattServiceInterface UUID uuid = entry.first; Log.d(TAG, "Checking uuid: " + uuid); if ((mFeatures & desc.featureFlag) != 0) { - int notifyProp = (((mFeatures & desc.ntfFeatureFlag) != 0) - ? PROPERTY_NOTIFY - : 0); + int notifyProp = (((mFeatures & desc.ntfFeatureFlag) != 0) ? PROPERTY_NOTIFY : 0); - BluetoothGattCharacteristic myChar = new BluetoothGattCharacteristic( - uuid, desc.properties | notifyProp, desc.permissions); + BluetoothGattCharacteristic myChar = + new BluetoothGattCharacteristic( + uuid, desc.properties | notifyProp, desc.permissions); // Add CCC descriptor if notification is supported if ((myChar.getProperties() & PROPERTY_NOTIFY) != 0) { - BluetoothGattDescriptor cccDesc = new BluetoothGattDescriptor(UUID_CCCD, - BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED - | BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED); + BluetoothGattDescriptor cccDesc = + new BluetoothGattDescriptor( + UUID_CCCD, + BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED + | BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED); Log.d(TAG, "Adding descriptor: " + cccDesc); myChar.addDescriptor(cccDesc); } @@ -1276,8 +1473,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mCccDescriptorValues.put(device.getAddress(), characteristicCcc); } - characteristicCcc.put(charUuid, - ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN).getShort()); + characteristicCcc.put( + charUuid, ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN).getShort()); if (!store) { return; @@ -1321,8 +1518,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface int getMediaStateChar() { if (!isFeatureSupported(ServiceFeature.MEDIA_STATE)) return MediaState.INACTIVE.getValue(); - BluetoothGattCharacteristic stateChar = - mCharacteristics.get(CharId.MEDIA_STATE); + BluetoothGattCharacteristic stateChar = mCharacteristics.get(CharId.MEDIA_STATE); if (stateChar.getValue() != null) { return stateChar.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0); @@ -1339,8 +1535,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mEventLogger.logd(TAG, "updateMediaStateChar: state= " + MediaState.toString(state)); - BluetoothGattCharacteristic stateChar = - mCharacteristics.get(CharId.MEDIA_STATE); + BluetoothGattCharacteristic stateChar = mCharacteristics.get(CharId.MEDIA_STATE); stateChar.setValue(state, BluetoothGattCharacteristic.FORMAT_UINT8, 0); notifyCharacteristic(stateChar, null); } @@ -1357,8 +1552,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface + CharId.FromFeature(feature) + ", objId= " + objectIdValue); - updateObjectIdChar(mCharacteristics.get(CharId.FromFeature(feature)), - objectIdValue, null, notify); + updateObjectIdChar( + mCharacteristics.get(CharId.FromFeature(feature)), objectIdValue, null, notify); } @Override @@ -1367,8 +1562,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } @Override - public void setMediaControlRequestResult(Request request, - Request.Results resultStatus) { + public void setMediaControlRequestResult(Request request, Request.Results resultStatus) { Log.d(TAG, "setMediaControlRequestResult"); if (getMediaStateChar() == MediaState.INACTIVE.getValue()) { @@ -1386,14 +1580,14 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } @Override - public void setSearchRequestResult(SearchRequest request, - SearchRequest.Results resultStatus, long resultObjectId) { + public void setSearchRequestResult( + SearchRequest request, SearchRequest.Results resultStatus, long resultObjectId) { Log.d(TAG, "setSearchRequestResult"); // TODO: There is no Object Trasfer Service implementation. BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.SEARCH_CONTROL_POINT); - characteristic.setValue(new byte[]{SEARCH_CONTROL_POINT_RESULT_FAILURE}); + characteristic.setValue(new byte[] {SEARCH_CONTROL_POINT_RESULT_FAILURE}); notifyCharacteristic(characteristic, null); } @@ -1406,7 +1600,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (stateFields.containsKey(PlayerStateField.PLAYBACK_STATE)) { MediaState playbackState = (MediaState) stateFields.get(PlayerStateField.PLAYBACK_STATE); - Log.d(TAG, + Log.d( + TAG, "updatePlayerState: playbackState= " + stateFields.get(PlayerStateField.PLAYBACK_STATE)); @@ -1430,7 +1625,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } if (stateFields.containsKey(PlayerStateField.PLAYING_ORDER)) { - updatePlayingOrderChar((PlayingOrder) stateFields.get(PlayerStateField.PLAYING_ORDER), + updatePlayingOrderChar( + (PlayingOrder) stateFields.get(PlayerStateField.PLAYING_ORDER), doNotifyValueChange); } @@ -1487,7 +1683,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface String newTitle = (String) stateFields.get(PlayerStateField.TRACK_TITLE); if (getTrackTitleChar().compareTo(newTitle) != 0) { - updateTrackTitleChar((String) stateFields.get(PlayerStateField.TRACK_TITLE), + updateTrackTitleChar( + (String) stateFields.get(PlayerStateField.TRACK_TITLE), doNotifyValueChange); notifyTrackChange = true; } @@ -1502,8 +1699,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } if (stateFields.containsKey(PlayerStateField.PLAYBACK_STATE)) { - mCurrentMediaState = - (MediaState) stateFields.get(PlayerStateField.PLAYBACK_STATE); + mCurrentMediaState = (MediaState) stateFields.get(PlayerStateField.PLAYBACK_STATE); } int mediaState = getMediaStateChar(); @@ -1516,7 +1712,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface // Seeking speed should be 1.0f (char. value of 0) when not in seeking state. // [Ref. Media Control Service v1.0, sec. 3.9] if (playbackState == MediaState.SEEKING.getValue()) { - updateSeekingSpeedChar((float) stateFields.get(PlayerStateField.SEEKING_SPEED), + updateSeekingSpeedChar( + (float) stateFields.get(PlayerStateField.SEEKING_SPEED), doNotifyValueChange); } else { updateSeekingSpeedChar(1.0f, doNotifyValueChange); @@ -1527,9 +1724,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface // [Ref. Media Control Service v1.0, sec. 3.4.1] if (notifyTrackChange) { if (isFeatureSupported(ServiceFeature.TRACK_CHANGED)) { - BluetoothGattCharacteristic myChar = - mCharacteristics.get(CharId.TRACK_CHANGED); - myChar.setValue(new byte[]{}); + BluetoothGattCharacteristic myChar = mCharacteristics.get(CharId.TRACK_CHANGED); + myChar.setValue(new byte[] {}); notifyCharacteristic(myChar, null); } } @@ -1630,11 +1826,11 @@ public class MediaControlGattService implements MediaControlGattServiceInterface byte[] ccc = getCccBytes(device, characteristic.getUuid()); Log.d( - TAG, - "notifyCharacteristic: char= " - + characteristic.getUuid().toString() - + " cccVal= " - + ByteBuffer.wrap(ccc).order(ByteOrder.LITTLE_ENDIAN).getShort()); + TAG, + "notifyCharacteristic: char= " + + characteristic.getUuid().toString() + + " cccVal= " + + ByteBuffer.wrap(ccc).order(ByteOrder.LITTLE_ENDIAN).getShort()); if (!Arrays.equals(ccc, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) return; Log.d(TAG, "notifyCharacteristic: sending notification"); @@ -1677,8 +1873,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Float speed = null; if (isFeatureSupported(ServiceFeature.SEEKING_SPEED)) { - BluetoothGattCharacteristic characteristic = - mCharacteristics.get(CharId.SEEKING_SPEED); + BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.SEEKING_SPEED); if (characteristic.getValue() != null) { Integer intVal = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT8, 0); @@ -1702,8 +1897,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } mEventLogger.logd( - TAG, - "updateSeekingSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); + TAG, "updateSeekingSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); } } } @@ -1740,8 +1934,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } mEventLogger.logd( - TAG, - "updatePlaybackSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); + TAG, "updatePlaybackSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); } } @@ -1755,8 +1948,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface ? (int) millisecondsToMcsInterval(positionMs) : INTERVAL_UNAVAILABLE; - BluetoothGattCharacteristic characteristic = - mCharacteristics.get(CharId.TRACK_POSITION); + BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.TRACK_POSITION); characteristic.setValue(position, BluetoothGattCharacteristic.FORMAT_SINT32, 0); if (isFeatureSupported(ServiceFeature.TRACK_POSITION_NOTIFY)) { @@ -1778,9 +1970,9 @@ public class MediaControlGattService implements MediaControlGattServiceInterface BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.TRACK_DURATION); if (characteristic.getValue() != null) { - int duration = - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0); - return (duration != INTERVAL_UNAVAILABLE) ? mcsIntervalToMilliseconds(duration) + int duration = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT32, 0); + return (duration != INTERVAL_UNAVAILABLE) + ? mcsIntervalToMilliseconds(duration) : TRACK_DURATION_UNAVAILABLE; } return TRACK_DURATION_UNAVAILABLE; @@ -1812,8 +2004,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private String getTrackTitleChar() { if (isFeatureSupported(ServiceFeature.TRACK_TITLE)) { - BluetoothGattCharacteristic characteristic = - mCharacteristics.get(CharId.TRACK_TITLE); + BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.TRACK_TITLE); if (characteristic.getValue() != null) { return characteristic.getStringValue(0); } @@ -1826,8 +2017,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface void updateTrackTitleChar(String title, boolean notify) { Log.d(TAG, "updateTrackTitleChar: " + title); if (isFeatureSupported(ServiceFeature.TRACK_TITLE)) { - BluetoothGattCharacteristic characteristic = - mCharacteristics.get(CharId.TRACK_TITLE); + BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.TRACK_TITLE); characteristic.setValue(title); if (notify && isFeatureSupported(ServiceFeature.TRACK_TITLE_NOTIFY)) { notifyCharacteristic(characteristic, null); @@ -1844,18 +2034,19 @@ public class MediaControlGattService implements MediaControlGattServiceInterface + Request.SupportedOpcodes.toString(opcodes)); if (!isFeatureSupported(ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED)) return; - BluetoothGattCharacteristic characteristic = mCharacteristics.get( - CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); + BluetoothGattCharacteristic characteristic = + mCharacteristics.get(CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED); // Do nothing if nothing has changed if (characteristic.getValue() != null - && characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) == opcodes) { + && characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) + == opcodes) { return; } characteristic.setValue(opcodes, BluetoothGattCharacteristic.FORMAT_UINT32, 0); if (notify && isFeatureSupported( - ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY)) { + ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY)) { notifyCharacteristic(characteristic, null); } mEventLogger.logd( @@ -1868,7 +2059,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface void updatePlayingOrderSupportedChar(int supportedOrder) { Log.d(TAG, "updatePlayingOrderSupportedChar: " + supportedOrder); if (isFeatureSupported(ServiceFeature.PLAYING_ORDER_SUPPORTED)) { - mCharacteristics.get(CharId.PLAYING_ORDER_SUPPORTED) + mCharacteristics + .get(CharId.PLAYING_ORDER_SUPPORTED) .setValue(supportedOrder, BluetoothGattCharacteristic.FORMAT_UINT16, 0); mEventLogger.logd(TAG, "updatePlayingOrderSupportedChar: order= " + supportedOrder); } @@ -1882,8 +2074,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface + CharId.PLAYER_ICON_OBJ_ID + ", objId= " + objId); - updateObjectIdChar(mCharacteristics.get(CharId.PLAYER_ICON_OBJ_ID), objId, - null, true); + updateObjectIdChar(mCharacteristics.get(CharId.PLAYER_ICON_OBJ_ID), objId, null, true); } } @@ -1909,8 +2100,11 @@ public class MediaControlGattService implements MediaControlGattServiceInterface return bb.array(); } - private void updateObjectIdChar(BluetoothGattCharacteristic characteristic, long objId, - BluetoothDevice originDevice, boolean notify) { + private void updateObjectIdChar( + BluetoothGattCharacteristic characteristic, + long objId, + BluetoothDevice originDevice, + boolean notify) { characteristic.setValue(objId2ByteArray(objId)); if ((characteristic.getProperties() & PROPERTY_NOTIFY) != 0) { // Notify all clients but not the originDevice @@ -1944,8 +2138,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (!isFeatureSupported(ServiceFeature.PLAYER_NAME)) return; - BluetoothGattCharacteristic characteristic = - mCharacteristics.get(CharId.PLAYER_NAME); + BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.PLAYER_NAME); characteristic.setValue(name); mEventLogger.logd(TAG, "updatePlayerNameChar: name= '" + name + "'"); if (notify && isFeatureSupported(ServiceFeature.PLAYER_NAME_NOTIFY)) { @@ -1954,8 +2147,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private boolean isFeatureSupported(long featureBit) { - Log.w(TAG, "Feature " + ServiceFeature.toString(featureBit) + " support: " - + ((mFeatures & featureBit) != 0)); + Log.w( + TAG, + "Feature " + + ServiceFeature.toString(featureBit) + + " support: " + + ((mFeatures & featureBit) != 0)); return (mFeatures & featureBit) != 0; } @@ -1986,15 +2183,22 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Integer opcodeSupportBit = Request.OpcodeToOpcodeSupport.get(opcode); if (opcodeSupportBit == null) return false; - return (mCharacteristics.get(CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED) - .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) - & opcodeSupportBit) == opcodeSupportBit; + return (mCharacteristics + .get(CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED) + .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) + & opcodeSupportBit) + == opcodeSupportBit; } private interface CharacteristicWriteHandler { - void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattCharacteristic characteristic, boolean preparedWrite, - boolean responseNeeded, int offset, byte[] value); + void onCharacteristicWriteRequest( + BluetoothDevice device, + int requestId, + BluetoothGattCharacteristic characteristic, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value); } private static final class CharacteristicData { @@ -2014,7 +2218,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } } - private final static class CharId { + private static final class CharId { public static final int PLAYER_NAME = Long.numberOfTrailingZeros(ServiceFeature.PLAYER_NAME); public static final int PLAYER_ICON_OBJ_ID = @@ -2072,115 +2276,214 @@ public class MediaControlGattService implements MediaControlGattServiceInterface */ private static List> getUuidCharacteristicList() { List> characteristics = new ArrayList<>(); - characteristics.add(new Pair<>(UUID_PLAYER_NAME, - new CharacteristicData(CharId.PLAYER_NAME, ServiceFeature.PLAYER_NAME, - ServiceFeature.PLAYER_NAME_NOTIFY, PROPERTY_READ, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_PLAYER_ICON_OBJ_ID, - new CharacteristicData(CharId.PLAYER_ICON_OBJ_ID, ServiceFeature.PLAYER_ICON_OBJ_ID, - // Notifications unsupported - 0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_PLAYER_ICON_URL, - new CharacteristicData(CharId.PLAYER_ICON_URL, ServiceFeature.PLAYER_ICON_URL, - // Notifications unsupported - 0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_TRACK_CHANGED, - new CharacteristicData(CharId.TRACK_CHANGED, ServiceFeature.TRACK_CHANGED, - // Mandatory notification if char. exists. - ServiceFeature.TRACK_CHANGED, PROPERTY_NOTIFY, 0))); - characteristics.add(new Pair<>(UUID_TRACK_TITLE, - new CharacteristicData(CharId.TRACK_TITLE, ServiceFeature.TRACK_TITLE, - ServiceFeature.TRACK_TITLE_NOTIFY, PROPERTY_READ, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_TRACK_DURATION, - new CharacteristicData(CharId.TRACK_DURATION, ServiceFeature.TRACK_DURATION, - ServiceFeature.TRACK_DURATION_NOTIFY, PROPERTY_READ, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_TRACK_POSITION, - new CharacteristicData(CharId.TRACK_POSITION, ServiceFeature.TRACK_POSITION, - ServiceFeature.TRACK_POSITION_NOTIFY, - PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, - PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_PLAYBACK_SPEED, - new CharacteristicData(CharId.PLAYBACK_SPEED, ServiceFeature.PLAYBACK_SPEED, - ServiceFeature.PLAYBACK_SPEED_NOTIFY, - PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, - PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_SEEKING_SPEED, - new CharacteristicData(CharId.SEEKING_SPEED, ServiceFeature.SEEKING_SPEED, - ServiceFeature.SEEKING_SPEED_NOTIFY, PROPERTY_READ, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_CURRENT_TRACK_SEGMENT_OBJ_ID, - new CharacteristicData(CharId.CURRENT_TRACK_SEGMENT_OBJ_ID, - ServiceFeature.CURRENT_TRACK_SEGMENT_OBJ_ID, - // Notifications unsupported - 0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_CURRENT_TRACK_OBJ_ID, - new CharacteristicData(CharId.CURRENT_TRACK_OBJ_ID, - ServiceFeature.CURRENT_TRACK_OBJ_ID, - ServiceFeature.CURRENT_TRACK_OBJ_ID_NOTIFY, - PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, - PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_NEXT_TRACK_OBJ_ID, - new CharacteristicData(CharId.NEXT_TRACK_OBJ_ID, ServiceFeature.NEXT_TRACK_OBJ_ID, - ServiceFeature.NEXT_TRACK_OBJ_ID_NOTIFY, - PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, - PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_CURRENT_GROUP_OBJ_ID, - new CharacteristicData(CharId.CURRENT_GROUP_OBJ_ID, - ServiceFeature.CURRENT_GROUP_OBJ_ID, - ServiceFeature.CURRENT_GROUP_OBJ_ID_NOTIFY, - PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, - PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_PARENT_GROUP_OBJ_ID, - new CharacteristicData(CharId.PARENT_GROUP_OBJ_ID, - ServiceFeature.PARENT_GROUP_OBJ_ID, - ServiceFeature.PARENT_GROUP_OBJ_ID_NOTIFY, PROPERTY_READ, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_PLAYING_ORDER, - new CharacteristicData(CharId.PLAYING_ORDER, ServiceFeature.PLAYING_ORDER, - ServiceFeature.PLAYING_ORDER_NOTIFY, - PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, - PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_PLAYING_ORDER_SUPPORTED, - new CharacteristicData(CharId.PLAYING_ORDER_SUPPORTED, - ServiceFeature.PLAYING_ORDER_SUPPORTED, - // Notifications unsupported - 0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_MEDIA_STATE, - new CharacteristicData(CharId.MEDIA_STATE, ServiceFeature.MEDIA_STATE, - // Mandatory notification if char. exists. - ServiceFeature.MEDIA_STATE, PROPERTY_READ | PROPERTY_NOTIFY, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_MEDIA_CONTROL_POINT, - new CharacteristicData(CharId.MEDIA_CONTROL_POINT, - ServiceFeature.MEDIA_CONTROL_POINT, - // Mandatory notification if char. exists. - ServiceFeature.MEDIA_CONTROL_POINT, - PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY, - PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED, - new CharacteristicData(CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED, - ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED, - ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY, PROPERTY_READ, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_SEARCH_RESULT_OBJ_ID, - new CharacteristicData(CharId.SEARCH_RESULT_OBJ_ID, - ServiceFeature.SEARCH_RESULT_OBJ_ID, - // Mandatory notification if char. exists. - ServiceFeature.SEARCH_RESULT_OBJ_ID, PROPERTY_READ | PROPERTY_NOTIFY, - PERMISSION_READ_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_SEARCH_CONTROL_POINT, - new CharacteristicData(CharId.SEARCH_CONTROL_POINT, - ServiceFeature.SEARCH_CONTROL_POINT, - // Mandatory notification if char. exists. - ServiceFeature.SEARCH_CONTROL_POINT, - PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY, - PERMISSION_WRITE_ENCRYPTED))); - characteristics.add(new Pair<>(UUID_CONTENT_CONTROL_ID, - new CharacteristicData(CharId.CONTENT_CONTROL_ID, ServiceFeature.CONTENT_CONTROL_ID, - // Notifications unsupported - 0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PLAYER_NAME, + new CharacteristicData( + CharId.PLAYER_NAME, + ServiceFeature.PLAYER_NAME, + ServiceFeature.PLAYER_NAME_NOTIFY, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PLAYER_ICON_OBJ_ID, + new CharacteristicData( + CharId.PLAYER_ICON_OBJ_ID, + ServiceFeature.PLAYER_ICON_OBJ_ID, + // Notifications unsupported + 0, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PLAYER_ICON_URL, + new CharacteristicData( + CharId.PLAYER_ICON_URL, + ServiceFeature.PLAYER_ICON_URL, + // Notifications unsupported + 0, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_TRACK_CHANGED, + new CharacteristicData( + CharId.TRACK_CHANGED, + ServiceFeature.TRACK_CHANGED, + // Mandatory notification if char. exists. + ServiceFeature.TRACK_CHANGED, + PROPERTY_NOTIFY, + 0))); + characteristics.add( + new Pair<>( + UUID_TRACK_TITLE, + new CharacteristicData( + CharId.TRACK_TITLE, + ServiceFeature.TRACK_TITLE, + ServiceFeature.TRACK_TITLE_NOTIFY, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_TRACK_DURATION, + new CharacteristicData( + CharId.TRACK_DURATION, + ServiceFeature.TRACK_DURATION, + ServiceFeature.TRACK_DURATION_NOTIFY, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_TRACK_POSITION, + new CharacteristicData( + CharId.TRACK_POSITION, + ServiceFeature.TRACK_POSITION, + ServiceFeature.TRACK_POSITION_NOTIFY, + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, + PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PLAYBACK_SPEED, + new CharacteristicData( + CharId.PLAYBACK_SPEED, + ServiceFeature.PLAYBACK_SPEED, + ServiceFeature.PLAYBACK_SPEED_NOTIFY, + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, + PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_SEEKING_SPEED, + new CharacteristicData( + CharId.SEEKING_SPEED, + ServiceFeature.SEEKING_SPEED, + ServiceFeature.SEEKING_SPEED_NOTIFY, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_CURRENT_TRACK_SEGMENT_OBJ_ID, + new CharacteristicData( + CharId.CURRENT_TRACK_SEGMENT_OBJ_ID, + ServiceFeature.CURRENT_TRACK_SEGMENT_OBJ_ID, + // Notifications unsupported + 0, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_CURRENT_TRACK_OBJ_ID, + new CharacteristicData( + CharId.CURRENT_TRACK_OBJ_ID, + ServiceFeature.CURRENT_TRACK_OBJ_ID, + ServiceFeature.CURRENT_TRACK_OBJ_ID_NOTIFY, + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, + PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_NEXT_TRACK_OBJ_ID, + new CharacteristicData( + CharId.NEXT_TRACK_OBJ_ID, + ServiceFeature.NEXT_TRACK_OBJ_ID, + ServiceFeature.NEXT_TRACK_OBJ_ID_NOTIFY, + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, + PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_CURRENT_GROUP_OBJ_ID, + new CharacteristicData( + CharId.CURRENT_GROUP_OBJ_ID, + ServiceFeature.CURRENT_GROUP_OBJ_ID, + ServiceFeature.CURRENT_GROUP_OBJ_ID_NOTIFY, + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, + PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PARENT_GROUP_OBJ_ID, + new CharacteristicData( + CharId.PARENT_GROUP_OBJ_ID, + ServiceFeature.PARENT_GROUP_OBJ_ID, + ServiceFeature.PARENT_GROUP_OBJ_ID_NOTIFY, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PLAYING_ORDER, + new CharacteristicData( + CharId.PLAYING_ORDER, + ServiceFeature.PLAYING_ORDER, + ServiceFeature.PLAYING_ORDER_NOTIFY, + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE, + PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_PLAYING_ORDER_SUPPORTED, + new CharacteristicData( + CharId.PLAYING_ORDER_SUPPORTED, + ServiceFeature.PLAYING_ORDER_SUPPORTED, + // Notifications unsupported + 0, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_MEDIA_STATE, + new CharacteristicData( + CharId.MEDIA_STATE, + ServiceFeature.MEDIA_STATE, + // Mandatory notification if char. exists. + ServiceFeature.MEDIA_STATE, + PROPERTY_READ | PROPERTY_NOTIFY, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_MEDIA_CONTROL_POINT, + new CharacteristicData( + CharId.MEDIA_CONTROL_POINT, + ServiceFeature.MEDIA_CONTROL_POINT, + // Mandatory notification if char. exists. + ServiceFeature.MEDIA_CONTROL_POINT, + PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY, + PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED, + new CharacteristicData( + CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED, + ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED, + ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_SEARCH_RESULT_OBJ_ID, + new CharacteristicData( + CharId.SEARCH_RESULT_OBJ_ID, + ServiceFeature.SEARCH_RESULT_OBJ_ID, + // Mandatory notification if char. exists. + ServiceFeature.SEARCH_RESULT_OBJ_ID, + PROPERTY_READ | PROPERTY_NOTIFY, + PERMISSION_READ_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_SEARCH_CONTROL_POINT, + new CharacteristicData( + CharId.SEARCH_CONTROL_POINT, + ServiceFeature.SEARCH_CONTROL_POINT, + // Mandatory notification if char. exists. + ServiceFeature.SEARCH_CONTROL_POINT, + PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY, + PERMISSION_WRITE_ENCRYPTED))); + characteristics.add( + new Pair<>( + UUID_CONTENT_CONTROL_ID, + new CharacteristicData( + CharId.CONTENT_CONTROL_ID, + ServiceFeature.CONTENT_CONTROL_ID, + // Notifications unsupported + 0, + PROPERTY_READ, + PERMISSION_READ_ENCRYPTED))); return characteristics; } @@ -2189,8 +2492,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface sb.append("\n\t\tCcid = " + mCcid); sb.append("\n\t\tFeatures:" + ServiceFeature.featuresToString(mFeatures, "\n\t\t\t")); - BluetoothGattCharacteristic characteristic = - mCharacteristics.get(CharId.PLAYER_NAME); + BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.PLAYER_NAME); if (characteristic == null) { sb.append("\n\t\tPlayer name: "); } else { @@ -2199,11 +2501,16 @@ public class MediaControlGattService implements MediaControlGattServiceInterface sb.append("\n\t\tCurrentPlaybackState = " + mCurrentMediaState); for (Map.Entry> deviceEntry : mCccDescriptorValues.entrySet()) { - sb.append("\n\t\tCCC states for device: " + "xx:xx:xx:xx:" - + deviceEntry.getKey().substring(12)); + sb.append( + "\n\t\tCCC states for device: " + + "xx:xx:xx:xx:" + + deviceEntry.getKey().substring(12)); for (Map.Entry entry : deviceEntry.getValue().entrySet()) { - sb.append("\n\t\t\tCharacteristic: " + mcsUuidToString(entry.getKey()) + ", value: " - + Utils.cccIntToStr(entry.getValue())); + sb.append( + "\n\t\t\tCharacteristic: " + + mcsUuidToString(entry.getKey()) + + ", value: " + + Utils.cccIntToStr(entry.getValue())); } } diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattServiceInterface.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattServiceInterface.java index 5a1b97074c0..7faccfe36f9 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattServiceInterface.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattServiceInterface.java @@ -22,33 +22,33 @@ import android.bluetooth.BluetoothDevice; import java.util.Map; import java.util.UUID; -/** - * Media Control Service interface. These are sent Media Players => GATT Servers - */ +/** Media Control Service interface. These are sent Media Players => GATT Servers */ public interface MediaControlGattServiceInterface { - /** - * Track position unavailable definition - */ + /** Track position unavailable definition */ static final long TRACK_POSITION_UNAVAILABLE = -1L; - /** - * Track duration unavailable definition - */ + /** Track duration unavailable definition */ static final long TRACK_DURATION_UNAVAILABLE = -1L; - /** - * API for Media Control Profile service control - */ + /** API for Media Control Profile service control */ void updatePlaybackState(MediaState state); + void updatePlayerState(Map stateFields); + void updateObjectID(int objField, long objectId); - void setMediaControlRequestResult(Request request, - Request.Results resultStatus); - void setSearchRequestResult(SearchRequest request, - SearchRequest.Results resultStatus, long resultObjectId); + + void setMediaControlRequestResult(Request request, Request.Results resultStatus); + + void setSearchRequestResult( + SearchRequest request, SearchRequest.Results resultStatus, long resultObjectId); + int getContentControlId(); + UUID getServiceUuid(); + void onDeviceAuthorizationSet(BluetoothDevice device); + void destroy(); + void dump(StringBuilder sb); } diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java index 349db884f17..fe894c9d9f9 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java @@ -83,6 +83,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { private MediaPlayerWrapper mLastActivePlayer = null; static MediaPlayerList sMediaPlayerListForTesting = null; + static void setsMediaPlayerListForTesting(MediaPlayerList mediaPlayerList) { sMediaPlayerListForTesting = mediaPlayerList; } @@ -180,7 +181,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { mEventLogger.loge( TAG, "onCurrentPlayerStateUpdated: base actions not supported, player" - + " actions= " + + " actions= " + Long.toHexString(mCurrentData.state.getActions()) + ", expected at least= " + Long.toHexString(BASE_PLAYER_ACTION_SET)); @@ -194,7 +195,8 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { PlayerStateField.SEEKING_SPEED, mCurrentData.state.getPlaybackSpeed()); state_map.put( PlayerStateField.PLAYBACK_SPEED, mCurrentData.state.getPlaybackSpeed()); - state_map.put(PlayerStateField.TRACK_POSITION, + state_map.put( + PlayerStateField.TRACK_POSITION, getDriftCorrectedTrackPosition(mCurrentData.state)); } @@ -224,26 +226,33 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { + "', duration= " + mCurrentData.metadata.duration); - state_map.put(PlayerStateField.TRACK_DURATION, + state_map.put( + PlayerStateField.TRACK_DURATION, mCurrentData.metadata.duration != null ? Long.valueOf(mCurrentData.metadata.duration) - : Long.valueOf(MediaControlGattServiceInterface - .TRACK_DURATION_UNAVAILABLE)); + : Long.valueOf( + MediaControlGattServiceInterface + .TRACK_DURATION_UNAVAILABLE)); - state_map.put(PlayerStateField.TRACK_TITLE, + state_map.put( + PlayerStateField.TRACK_TITLE, mCurrentData.metadata.title != null ? mCurrentData.metadata.title : ""); // Update the position if track has changed - state_map.put(PlayerStateField.TRACK_POSITION, + state_map.put( + PlayerStateField.TRACK_POSITION, mCurrentData.state != null ? getDriftCorrectedTrackPosition(mCurrentData.state) - : Long.valueOf(MediaControlGattServiceInterface - .TRACK_POSITION_UNAVAILABLE)); + : Long.valueOf( + MediaControlGattServiceInterface + .TRACK_POSITION_UNAVAILABLE)); } else { - state_map.put(PlayerStateField.TRACK_DURATION, + state_map.put( + PlayerStateField.TRACK_DURATION, Long.valueOf(MediaControlGattServiceInterface.TRACK_DURATION_UNAVAILABLE)); state_map.put(PlayerStateField.TRACK_TITLE, ""); - state_map.put(PlayerStateField.TRACK_POSITION, + state_map.put( + PlayerStateField.TRACK_POSITION, Long.valueOf(MediaControlGattServiceInterface.TRACK_POSITION_UNAVAILABLE)); } } @@ -283,8 +292,8 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { } @Override - public void onServiceInstanceRegistered(ServiceStatus status, - MediaControlGattServiceInterface service) { + public void onServiceInstanceRegistered( + ServiceStatus status, MediaControlGattServiceInterface service) { mEventLogger.logd(TAG, "onServiceInstanceRegistered: status= " + status); mGMcsService = service; } @@ -359,7 +368,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { state_map.put(PlayerStateField.TRACK_POSITION, getLatestTrackPosition()); if (mGMcsService != null) { - mGMcsService.updatePlayerState(state_map); + mGMcsService.updatePlayerState(state_map); } } } @@ -481,7 +490,8 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { long current_pos_ms = getLatestTrackPosition(); long track_duration_ms = getCurrentTrackDuration(); - if (track_duration_ms != MediaControlGattServiceInterface.TRACK_DURATION_UNAVAILABLE) { + if (track_duration_ms + != MediaControlGattServiceInterface.TRACK_DURATION_UNAVAILABLE) { current_pos_ms = current_pos_ms + requested_offset_ms; if (current_pos_ms < 0) { current_pos_ms = 0; @@ -606,7 +616,8 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { switch (settings_field) { case PLAYBACK_STATE: if (mCurrentData.state != null) { - handled_request_map.put(settings_field, + handled_request_map.put( + settings_field, playerState2McsState(mCurrentData.state.getState())); } break; @@ -623,7 +634,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { float seeking_speed = 1.0f; if (mCurrentData.state != null) { if ((mCurrentData.state.getState() - == PlaybackState.STATE_FAST_FORWARDING) + == PlaybackState.STATE_FAST_FORWARDING) || (mCurrentData.state.getState() == PlaybackState.STATE_REWINDING)) { seeking_speed = mCurrentData.state.getPlaybackSpeed(); @@ -638,8 +649,8 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { case TRACK_POSITION: if (mCurrentData.state != null) { handled_request_map.put( - settings_field, getDriftCorrectedTrackPosition( - mCurrentData.state)); + settings_field, + getDriftCorrectedTrackPosition(mCurrentData.state)); } break; case PLAYER_NAME: @@ -679,7 +690,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { if (!handled_request_map.isEmpty()) { removePendingStateRequests(handled_request_map.keySet()); if (mGMcsService != null) { - mGMcsService.updatePlayerState(handled_request_map); + mGMcsService.updatePlayerState(handled_request_map); } } @@ -761,8 +772,11 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { } // Instantiate a Service Instance and it's state machine - int ccid = ContentControlIdKeeper.acquireCcid(BluetoothUuid.GENERIC_MEDIA_CONTROL, - BluetoothLeAudio.CONTEXT_TYPE_MEDIA | BluetoothLeAudio.CONTEXT_TYPE_LIVE); + int ccid = + ContentControlIdKeeper.acquireCcid( + BluetoothUuid.GENERIC_MEDIA_CONTROL, + BluetoothLeAudio.CONTEXT_TYPE_MEDIA + | BluetoothLeAudio.CONTEXT_TYPE_LIVE); if (ccid == ContentControlIdKeeper.CCID_INVALID) { Log.e(TAG, "Unable to acquire valid CCID!"); return; @@ -779,8 +793,10 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { + ServiceFeature.featuresToString(SUPPORTED_FEATURES, "\n\t\t\t")); MediaControlGattService svc = new MediaControlGattService(mMcpService, this, ccid); - svc.init(isGenericMcs ? BluetoothUuid.GENERIC_MEDIA_CONTROL.getUuid() - : BluetoothUuid.MEDIA_CONTROL.getUuid()); + svc.init( + isGenericMcs + ? BluetoothUuid.GENERIC_MEDIA_CONTROL.getUuid() + : BluetoothUuid.MEDIA_CONTROL.getUuid()); mServiceMap.put(appToken, svc); } } @@ -813,36 +829,45 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { return playback_state; } - private static final Map sPlayerState2McsStateMap = Map.ofEntries( - entry(PlaybackState.STATE_NONE, MediaState.INACTIVE), - entry(PlaybackState.STATE_STOPPED, MediaState.PAUSED), - entry(PlaybackState.STATE_PAUSED, MediaState.PAUSED), - entry(PlaybackState.STATE_PLAYING, MediaState.PLAYING), - entry(PlaybackState.STATE_FAST_FORWARDING, MediaState.SEEKING), - entry(PlaybackState.STATE_REWINDING, MediaState.SEEKING), - entry(PlaybackState.STATE_BUFFERING, MediaState.PAUSED), - entry(PlaybackState.STATE_ERROR, MediaState.INACTIVE), - entry(PlaybackState.STATE_CONNECTING, MediaState.INACTIVE), - entry(PlaybackState.STATE_SKIPPING_TO_PREVIOUS, MediaState.PAUSED), - entry(PlaybackState.STATE_SKIPPING_TO_NEXT, MediaState.PAUSED), - entry(PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM, MediaState.PAUSED)); - - private static final long SUPPORTED_FEATURES = ServiceFeature.PLAYER_NAME - | ServiceFeature.PLAYER_NAME_NOTIFY - // It seems that can't provide player icon URIs that easily - // BluetoothMcs.ServiceFeature.PLAYER_ICON_URL | - | ServiceFeature.TRACK_CHANGED | ServiceFeature.TRACK_TITLE - | ServiceFeature.TRACK_TITLE_NOTIFY | ServiceFeature.TRACK_DURATION - | ServiceFeature.TRACK_DURATION_NOTIFY | ServiceFeature.TRACK_POSITION - | ServiceFeature.TRACK_POSITION_NOTIFY | ServiceFeature.PLAYBACK_SPEED - | ServiceFeature.PLAYBACK_SPEED_NOTIFY | ServiceFeature.SEEKING_SPEED - | ServiceFeature.SEEKING_SPEED_NOTIFY | ServiceFeature.PLAYING_ORDER - | ServiceFeature.PLAYING_ORDER_NOTIFY | ServiceFeature.PLAYING_ORDER_SUPPORTED - | ServiceFeature.MEDIA_STATE | ServiceFeature.MEDIA_CONTROL_POINT - | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED - | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY - | ServiceFeature.CONTENT_CONTROL_ID; - + private static final Map sPlayerState2McsStateMap = + Map.ofEntries( + entry(PlaybackState.STATE_NONE, MediaState.INACTIVE), + entry(PlaybackState.STATE_STOPPED, MediaState.PAUSED), + entry(PlaybackState.STATE_PAUSED, MediaState.PAUSED), + entry(PlaybackState.STATE_PLAYING, MediaState.PLAYING), + entry(PlaybackState.STATE_FAST_FORWARDING, MediaState.SEEKING), + entry(PlaybackState.STATE_REWINDING, MediaState.SEEKING), + entry(PlaybackState.STATE_BUFFERING, MediaState.PAUSED), + entry(PlaybackState.STATE_ERROR, MediaState.INACTIVE), + entry(PlaybackState.STATE_CONNECTING, MediaState.INACTIVE), + entry(PlaybackState.STATE_SKIPPING_TO_PREVIOUS, MediaState.PAUSED), + entry(PlaybackState.STATE_SKIPPING_TO_NEXT, MediaState.PAUSED), + entry(PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM, MediaState.PAUSED)); + + private static final long SUPPORTED_FEATURES = + ServiceFeature.PLAYER_NAME + | ServiceFeature.PLAYER_NAME_NOTIFY + // It seems that can't provide player icon URIs that easily + // BluetoothMcs.ServiceFeature.PLAYER_ICON_URL | + | ServiceFeature.TRACK_CHANGED + | ServiceFeature.TRACK_TITLE + | ServiceFeature.TRACK_TITLE_NOTIFY + | ServiceFeature.TRACK_DURATION + | ServiceFeature.TRACK_DURATION_NOTIFY + | ServiceFeature.TRACK_POSITION + | ServiceFeature.TRACK_POSITION_NOTIFY + | ServiceFeature.PLAYBACK_SPEED + | ServiceFeature.PLAYBACK_SPEED_NOTIFY + | ServiceFeature.SEEKING_SPEED + | ServiceFeature.SEEKING_SPEED_NOTIFY + | ServiceFeature.PLAYING_ORDER + | ServiceFeature.PLAYING_ORDER_NOTIFY + | ServiceFeature.PLAYING_ORDER_SUPPORTED + | ServiceFeature.MEDIA_STATE + | ServiceFeature.MEDIA_CONTROL_POINT + | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED + | ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY + | ServiceFeature.CONTENT_CONTROL_ID; private final Map mServiceMap; diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlServiceCallbacks.java b/android/app/src/com/android/bluetooth/mcp/MediaControlServiceCallbacks.java index 2976daa6830..7960402560e 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlServiceCallbacks.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlServiceCallbacks.java @@ -21,19 +21,34 @@ package com.android.bluetooth.mcp; * Media Control Service callback interface. These callbacks are sent GATT servers => Media Players */ interface MediaControlServiceCallbacks { - void onServiceInstanceRegistered(ServiceStatus status, MediaControlGattServiceInterface serviceProxy); + void onServiceInstanceRegistered( + ServiceStatus status, MediaControlGattServiceInterface serviceProxy); + void onServiceInstanceUnregistered(ServiceStatus status); + void onMediaControlRequest(Request request); + void onSearchRequest(SearchRequest request); + void onSetObjectIdRequest(int objField, long objectId); + void onTrackPositionSetRequest(long position); + void onPlaybackSpeedSetRequest(float speed); + void onPlayingOrderSetRequest(int order); + void onCurrentTrackObjectIdSet(long objectId); + void onNextTrackObjectIdSet(long objectId); + void onCurrentGroupObjectIdSet(long objectId); + void onCurrentTrackMetadataRequest(); + void onPlayerStateRequest(PlayerStateField[] stateFields); + long onGetFeatureFlags(); + long onGetCurrentTrackPosition(); } diff --git a/android/app/src/com/android/bluetooth/mcp/MediaState.java b/android/app/src/com/android/bluetooth/mcp/MediaState.java index a543d413c5d..4ca01dee147 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaState.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaState.java @@ -17,9 +17,7 @@ package com.android.bluetooth.mcp; -/** - * Playback states definition - */ +/** Playback states definition */ public enum MediaState { INACTIVE(0x00), PLAYING(0x01), diff --git a/android/app/src/com/android/bluetooth/mcp/ObjectIds.java b/android/app/src/com/android/bluetooth/mcp/ObjectIds.java index 66056f4243d..0237022fb04 100644 --- a/android/app/src/com/android/bluetooth/mcp/ObjectIds.java +++ b/android/app/src/com/android/bluetooth/mcp/ObjectIds.java @@ -17,9 +17,7 @@ package com.android.bluetooth.mcp; -/** - * Objects IDs definition - */ +/** Objects IDs definition */ public final class ObjectIds { public static final int PLAYER_ICON_OBJ_ID = (int) ServiceFeature.PLAYER_ICON_OBJ_ID; public static final int CURRENT_TRACK_SEGMENT_OBJ_ID = @@ -29,6 +27,7 @@ public final class ObjectIds { public static final int CURRENT_GROUP_OBJ_ID = (int) ServiceFeature.CURRENT_GROUP_OBJ_ID; public static final int PARENT_GROUP_OBJ_ID = (int) ServiceFeature.PARENT_GROUP_OBJ_ID; public static final int SEARCH_RESULT_OBJ_ID = (int) ServiceFeature.SEARCH_RESULT_OBJ_ID; + private ObjectIds() { // not called } diff --git a/android/app/src/com/android/bluetooth/mcp/PlayerStateField.java b/android/app/src/com/android/bluetooth/mcp/PlayerStateField.java index edeaded9e3a..8302da3c3de 100644 --- a/android/app/src/com/android/bluetooth/mcp/PlayerStateField.java +++ b/android/app/src/com/android/bluetooth/mcp/PlayerStateField.java @@ -17,9 +17,7 @@ package com.android.bluetooth.mcp; -/** - * Player state fields definition - */ +/** Player state fields definition */ public enum PlayerStateField { PLAYBACK_STATE, PLAYBACK_SPEED, diff --git a/android/app/src/com/android/bluetooth/mcp/PlayingOrder.java b/android/app/src/com/android/bluetooth/mcp/PlayingOrder.java index fae42f2265a..c3f7a34eadd 100644 --- a/android/app/src/com/android/bluetooth/mcp/PlayingOrder.java +++ b/android/app/src/com/android/bluetooth/mcp/PlayingOrder.java @@ -17,9 +17,7 @@ package com.android.bluetooth.mcp; -/** - * Playing order definition - */ +/** Playing order definition */ public enum PlayingOrder { SINGLE_ONCE(0x01), SINGLE_REPEAT(0x02), diff --git a/android/app/src/com/android/bluetooth/mcp/Request.java b/android/app/src/com/android/bluetooth/mcp/Request.java index cb656a966ea..b0f0f994e59 100644 --- a/android/app/src/com/android/bluetooth/mcp/Request.java +++ b/android/app/src/com/android/bluetooth/mcp/Request.java @@ -21,9 +21,7 @@ import static java.util.Map.entry; import java.util.Map; -/** - * Media control request, from client to Media Player - */ +/** Media control request, from client to Media Player */ public final class Request { private final int mOpcode; private final Integer mIntArg; @@ -32,7 +30,7 @@ public final class Request { * Media control request constructor * * @param opcode Control request opcode - * @param arg Control request argument + * @param arg Control request argument */ public Request(int opcode, int arg) { this.mOpcode = opcode; @@ -57,9 +55,7 @@ public final class Request { return mIntArg; } - /** - * Media control request results definition - */ + /** Media control request results definition */ public enum Results { SUCCESS(0x01), OPCODE_NOT_SUPPORTED(0x02), @@ -77,10 +73,8 @@ public final class Request { } } - /** - * Media control request supported opcodes definition - */ - public final static class SupportedOpcodes { + /** Media control request supported opcodes definition */ + public static final class SupportedOpcodes { public static final int NONE = 0x00; public static final int PLAY = 0x01; public static final int PAUSE = 0x02; @@ -174,10 +168,8 @@ public final class Request { } } - /** - * Media control request opcodes definition - */ - public final static class Opcodes { + /** Media control request opcodes definition */ + public static final class Opcodes { public static final int PLAY = 0x01; public static final int PAUSE = 0x02; public static final int FAST_REWIND = 0x03; @@ -201,7 +193,7 @@ public final class Request { public static final int GOTO_GROUP = 0x44; static String toString(int opcode) { - switch(opcode) { + switch (opcode) { case 0x01: return "PLAY(0x01)"; case 0x02: @@ -253,27 +245,27 @@ public final class Request { /* Map opcodes which are written to 'Media Control Point' characteristics to their corresponding * feature bit masks used in 'Media Control Point Opcodes Supported' characteristic. */ - public final static Map OpcodeToOpcodeSupport = Map.ofEntries( - entry(Opcodes.PLAY, SupportedOpcodes.PLAY), - entry(Opcodes.PAUSE, SupportedOpcodes.PAUSE), - entry(Opcodes.FAST_REWIND, SupportedOpcodes.FAST_REWIND), - entry(Opcodes.FAST_FORWARD, SupportedOpcodes.FAST_FORWARD), - entry(Opcodes.STOP, SupportedOpcodes.STOP), - entry(Opcodes.MOVE_RELATIVE, SupportedOpcodes.MOVE_RELATIVE), - entry(Opcodes.PREVIOUS_SEGMENT, SupportedOpcodes.PREVIOUS_SEGMENT), - entry(Opcodes.NEXT_SEGMENT, SupportedOpcodes.NEXT_SEGMENT), - entry(Opcodes.FIRST_SEGMENT, SupportedOpcodes.FIRST_SEGMENT), - entry(Opcodes.LAST_SEGMENT, SupportedOpcodes.LAST_SEGMENT), - entry(Opcodes.GOTO_SEGMENT, SupportedOpcodes.GOTO_SEGMENT), - entry(Opcodes.PREVIOUS_TRACK, SupportedOpcodes.PREVIOUS_TRACK), - entry(Opcodes.NEXT_TRACK, SupportedOpcodes.NEXT_TRACK), - entry(Opcodes.FIRST_TRACK, SupportedOpcodes.FIRST_TRACK), - entry(Opcodes.LAST_TRACK, SupportedOpcodes.LAST_TRACK), - entry(Opcodes.GOTO_TRACK, SupportedOpcodes.GOTO_TRACK), - entry(Opcodes.PREVIOUS_GROUP, SupportedOpcodes.PREVIOUS_GROUP), - entry(Opcodes.NEXT_GROUP, SupportedOpcodes.NEXT_GROUP), - entry(Opcodes.FIRST_GROUP, SupportedOpcodes.FIRST_GROUP), - entry(Opcodes.LAST_GROUP, SupportedOpcodes.LAST_GROUP), - entry(Opcodes.GOTO_GROUP, SupportedOpcodes.GOTO_GROUP)); - + public static final Map OpcodeToOpcodeSupport = + Map.ofEntries( + entry(Opcodes.PLAY, SupportedOpcodes.PLAY), + entry(Opcodes.PAUSE, SupportedOpcodes.PAUSE), + entry(Opcodes.FAST_REWIND, SupportedOpcodes.FAST_REWIND), + entry(Opcodes.FAST_FORWARD, SupportedOpcodes.FAST_FORWARD), + entry(Opcodes.STOP, SupportedOpcodes.STOP), + entry(Opcodes.MOVE_RELATIVE, SupportedOpcodes.MOVE_RELATIVE), + entry(Opcodes.PREVIOUS_SEGMENT, SupportedOpcodes.PREVIOUS_SEGMENT), + entry(Opcodes.NEXT_SEGMENT, SupportedOpcodes.NEXT_SEGMENT), + entry(Opcodes.FIRST_SEGMENT, SupportedOpcodes.FIRST_SEGMENT), + entry(Opcodes.LAST_SEGMENT, SupportedOpcodes.LAST_SEGMENT), + entry(Opcodes.GOTO_SEGMENT, SupportedOpcodes.GOTO_SEGMENT), + entry(Opcodes.PREVIOUS_TRACK, SupportedOpcodes.PREVIOUS_TRACK), + entry(Opcodes.NEXT_TRACK, SupportedOpcodes.NEXT_TRACK), + entry(Opcodes.FIRST_TRACK, SupportedOpcodes.FIRST_TRACK), + entry(Opcodes.LAST_TRACK, SupportedOpcodes.LAST_TRACK), + entry(Opcodes.GOTO_TRACK, SupportedOpcodes.GOTO_TRACK), + entry(Opcodes.PREVIOUS_GROUP, SupportedOpcodes.PREVIOUS_GROUP), + entry(Opcodes.NEXT_GROUP, SupportedOpcodes.NEXT_GROUP), + entry(Opcodes.FIRST_GROUP, SupportedOpcodes.FIRST_GROUP), + entry(Opcodes.LAST_GROUP, SupportedOpcodes.LAST_GROUP), + entry(Opcodes.GOTO_GROUP, SupportedOpcodes.GOTO_GROUP)); } diff --git a/android/app/src/com/android/bluetooth/mcp/SearchRequest.java b/android/app/src/com/android/bluetooth/mcp/SearchRequest.java index dfd0a204e6c..4c5137baeb2 100644 --- a/android/app/src/com/android/bluetooth/mcp/SearchRequest.java +++ b/android/app/src/com/android/bluetooth/mcp/SearchRequest.java @@ -19,9 +19,7 @@ package com.android.bluetooth.mcp; import android.annotation.NonNull; -/** - * Media search request, from client to Media Player - */ +/** Media search request, from client to Media Player */ public final class SearchRequest { private final int mType; private final String mStringArg; @@ -30,7 +28,7 @@ public final class SearchRequest { * Media search request constructor * * @param type Search request type - * @param arg Search request argument + * @param arg Search request argument */ public SearchRequest(int type, String arg) { this.mType = type; @@ -55,9 +53,7 @@ public final class SearchRequest { return mStringArg; } - /** - * Media search request results definition - */ + /** Media search request results definition */ public enum Results { SUCCESS(0x01), FAILURE(0x02); @@ -73,10 +69,8 @@ public final class SearchRequest { } } - /** - * Media search request types definition - */ - public final static class Types { + /** Media search request types definition */ + public static final class Types { public static final int TRACK_NAME = 0x01; public static final int ARTIST_NAME = 0x02; public static final int ALBUM_NAME = 0x03; @@ -86,9 +80,9 @@ public final class SearchRequest { public static final int GENRE = 0x07; public static final int ONLY_TRACKS = 0x08; public static final int ONLY_GROUPS = 0x09; + private Types() { // not called } } - } diff --git a/android/app/src/com/android/bluetooth/mcp/ServiceFeature.java b/android/app/src/com/android/bluetooth/mcp/ServiceFeature.java index c51ceec9134..d9c23aa8e6c 100644 --- a/android/app/src/com/android/bluetooth/mcp/ServiceFeature.java +++ b/android/app/src/com/android/bluetooth/mcp/ServiceFeature.java @@ -19,9 +19,7 @@ package com.android.bluetooth.mcp; import java.util.BitSet; -/** - * Service features definition - */ +/** Service features definition */ public final class ServiceFeature { // LS word is used for the characteristic support bits public static final long PLAYER_NAME = 0x00000001; @@ -64,8 +62,14 @@ public final class ServiceFeature { // This is set according to the Media Control Service Specification, v1.0, Section 3, // Table 3.1. - public static final long ALL_MANDATORY_SERVICE_FEATURES = PLAYER_NAME | TRACK_CHANGED - | TRACK_TITLE | TRACK_DURATION | TRACK_POSITION | MEDIA_STATE | CONTENT_CONTROL_ID; + public static final long ALL_MANDATORY_SERVICE_FEATURES = + PLAYER_NAME + | TRACK_CHANGED + | TRACK_TITLE + | TRACK_DURATION + | TRACK_POSITION + | MEDIA_STATE + | CONTENT_CONTROL_ID; static String toString(long serviceFeature) { if (serviceFeature == PLAYER_NAME) return "PLAYER_NAME(BIT 1)"; @@ -77,7 +81,8 @@ public final class ServiceFeature { if (serviceFeature == TRACK_POSITION) return "TRACK_POSITION(BIT 7)"; if (serviceFeature == PLAYBACK_SPEED) return "PLAYBACK_SPEED(BIT 8)"; if (serviceFeature == SEEKING_SPEED) return "SEEKING_SPEED(BIT 9)"; - if (serviceFeature == CURRENT_TRACK_SEGMENT_OBJ_ID) return "CURRENT_TRACK_SEGMENT_OBJ_ID(BIT 10)"; + if (serviceFeature == CURRENT_TRACK_SEGMENT_OBJ_ID) + return "CURRENT_TRACK_SEGMENT_OBJ_ID(BIT 10)"; if (serviceFeature == CURRENT_TRACK_OBJ_ID) return "CURRENT_TRACK_OBJ_ID(BIT 11)"; if (serviceFeature == NEXT_TRACK_OBJ_ID) return "NEXT_TRACK_OBJ_ID(BIT 12)"; if (serviceFeature == CURRENT_GROUP_OBJ_ID) return "CURRENT_GROUP_OBJ_ID(BIT 13)"; @@ -86,7 +91,8 @@ public final class ServiceFeature { if (serviceFeature == PLAYING_ORDER_SUPPORTED) return "PLAYING_ORDER_SUPPORTED(BIT 16)"; if (serviceFeature == MEDIA_STATE) return "MEDIA_STATE(BIT 17)"; if (serviceFeature == MEDIA_CONTROL_POINT) return "MEDIA_CONTROL_POINT(BIT 18)"; - if (serviceFeature == MEDIA_CONTROL_POINT_OPCODES_SUPPORTED) return "MEDIA_CONTROL_POINT_OPCODES_SUPPORTED(BIT 19)"; + if (serviceFeature == MEDIA_CONTROL_POINT_OPCODES_SUPPORTED) + return "MEDIA_CONTROL_POINT_OPCODES_SUPPORTED(BIT 19)"; if (serviceFeature == SEARCH_RESULT_OBJ_ID) return "SEARCH_RESULT_OBJ_ID(BIT 20)"; if (serviceFeature == SEARCH_CONTROL_POINT) return "SEARCH_CONTROL_POINT(BIT 21)"; if (serviceFeature == CONTENT_CONTROL_ID) return "CONTENT_CONTROL_ID(BIT 22)"; @@ -101,7 +107,8 @@ public final class ServiceFeature { if (serviceFeature == CURRENT_GROUP_OBJ_ID_NOTIFY) return "CURRENT_GROUP_OBJ_ID_NOTIFY"; if (serviceFeature == PARENT_GROUP_OBJ_ID_NOTIFY) return "PARENT_GROUP_OBJ_ID_NOTIFY"; if (serviceFeature == PLAYING_ORDER_NOTIFY) return "PLAYING_ORDER_NOTIFY"; - if (serviceFeature == MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY) return "MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY"; + if (serviceFeature == MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY) + return "MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY"; return "UNKNOWN(0x" + Long.toHexString(serviceFeature) + ")"; } diff --git a/android/app/src/com/android/bluetooth/mcp/ServiceStatus.java b/android/app/src/com/android/bluetooth/mcp/ServiceStatus.java index 888d5987b3d..6ab0d008c1b 100644 --- a/android/app/src/com/android/bluetooth/mcp/ServiceStatus.java +++ b/android/app/src/com/android/bluetooth/mcp/ServiceStatus.java @@ -17,9 +17,7 @@ package com.android.bluetooth.mcp; -/** - * Service status definition - */ +/** Service status definition */ public enum ServiceStatus { OK, INVALID_FEATURE_FLAGS, diff --git a/android/app/src/com/android/bluetooth/mcp/SupportedPlayingOrder.java b/android/app/src/com/android/bluetooth/mcp/SupportedPlayingOrder.java index 5fa2be62133..1ab2cf4f4aa 100644 --- a/android/app/src/com/android/bluetooth/mcp/SupportedPlayingOrder.java +++ b/android/app/src/com/android/bluetooth/mcp/SupportedPlayingOrder.java @@ -17,9 +17,7 @@ package com.android.bluetooth.mcp; -/** - * Supported playing order definition - */ +/** Supported playing order definition */ public final class SupportedPlayingOrder { public static final int SINGLE_ONCE = 0x0001; public static final int SINGLE_REPEAT = 0x0002; diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppBatch.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppBatch.java index 9e0d03d8f7c..b5e70e17b31 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppBatch.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppBatch.java @@ -42,8 +42,8 @@ import com.android.bluetooth.BluetoothMethodProxy; import java.util.ArrayList; /** - * This class stores information about a batch of OPP shares that should be - * transferred in one session. + * This class stores information about a batch of OPP shares that should be transferred in one + * session. */ /*There are a few cases: 1. create a batch for a single file to send * 2. create a batch for multiple files to send @@ -73,30 +73,29 @@ public class BluetoothOppBatch { private final ArrayList mShares; private final Context mContext; - /** - * An interface for notifying when BluetoothOppTransferBatch is changed - */ + /** An interface for notifying when BluetoothOppTransferBatch is changed */ public interface BluetoothOppBatchListener { /** * Called to notify when a share is added into the batch + * * @param id , BluetoothOppShareInfo.id */ void onShareAdded(int id); /** * Called to notify when a share is deleted from the batch + * * @param id , BluetoothOppShareInfo.id */ void onShareDeleted(int id); - /** - * Called to notify when the batch is canceled - */ + /** Called to notify when the batch is canceled */ void onBatchCanceled(); } /** * A batch is always created with at least one ShareInfo + * * @param context, Context * @param info, BluetoothOppShareInfo */ @@ -113,9 +112,7 @@ public class BluetoothOppBatch { Log.v(TAG, "New Batch created for info " + info.mId); } - /** - * Add one share into the batch. - */ + /** Add one share into the batch. */ /* There are 2 cases: Service scans the databases and it's multiple send * Service receives database update and know additional file should be received */ @@ -126,9 +123,7 @@ public class BluetoothOppBatch { } } - /** - * Cancel the whole batch. - */ + /** Cancel the whole batch. */ /* 1) If the batch is running, stop the transfer * 2) Go through mShares list and mark all incomplete share as CANCELED status * 3) update ContentProvider for these canceled transfer @@ -139,15 +134,15 @@ public class BluetoothOppBatch { if (mListener != null) { mListener.onBatchCanceled(); } - //TODO investigate if below code is redundant + // TODO investigate if below code is redundant for (int i = mShares.size() - 1; i >= 0; i--) { BluetoothOppShareInfo info = mShares.get(i); if (info.mStatus < 200) { if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mUri != null) { - BluetoothMethodProxy.getInstance().contentResolverDelete( - mContext.getContentResolver(), info.mUri, null, null - ); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + mContext.getContentResolver(), info.mUri, null, null); } Log.v(TAG, "Cancel batch for info " + info.mId); @@ -173,6 +168,7 @@ public class BluetoothOppBatch { /** * Get the running status of the batch + * * @return */ @@ -183,8 +179,8 @@ public class BluetoothOppBatch { /** * Get the first pending ShareInfo of the batch - * @return BluetoothOppShareInfo, for the first pending share, or null if - * none exists + * + * @return BluetoothOppShareInfo, for the first pending share, or null if none exists */ public BluetoothOppShareInfo getPendingShare() { for (int i = 0; i < mShares.size(); i++) { diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java index f6f5d751914..58255a4d5b5 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java @@ -45,12 +45,9 @@ import androidx.annotation.VisibleForTesting; import com.android.bluetooth.R; -/** - * This class is designed to show BT enable confirmation dialog; - */ +/** This class is designed to show BT enable confirmation dialog; */ public class BluetoothOppBtEnableActivity extends AlertActivity { - @VisibleForTesting - BluetoothOppManager mOppManager; + @VisibleForTesting BluetoothOppManager mOppManager; @Override protected void onCreate(Bundle savedInstanceState) { @@ -64,8 +61,8 @@ public class BluetoothOppBtEnableActivity extends AlertActivity { mAlertBuilder.setIconAttribute(android.R.attr.alertDialogIcon); mAlertBuilder.setTitle(getString(R.string.bt_enable_title)); mAlertBuilder.setView(createView()); - mAlertBuilder.setPositiveButton(R.string.bt_enable_ok, - (dialog, which) -> onEnableBluetooth()); + mAlertBuilder.setPositiveButton( + R.string.bt_enable_ok, (dialog, which) -> onEnableBluetooth()); mAlertBuilder.setNegativeButton(R.string.bt_enable_cancel, (dialog, which) -> finish()); setupAlert(); } @@ -74,7 +71,9 @@ public class BluetoothOppBtEnableActivity extends AlertActivity { View view = getLayoutInflater().inflate(R.layout.confirm_dialog, null); TextView contentView = (TextView) view.findViewById(R.id.content); contentView.setText( - getString(R.string.bt_enable_line1) + "\n\n" + getString(R.string.bt_enable_line2) + getString(R.string.bt_enable_line1) + + "\n\n" + + getString(R.string.bt_enable_line2) + "\n"); return view; @@ -84,8 +83,8 @@ public class BluetoothOppBtEnableActivity extends AlertActivity { mOppManager.enableBluetooth(); // this is an asyn call mOppManager.mSendingFlag = true; - Toast.makeText(this, getString(R.string.enabling_progress_content), - Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.enabling_progress_content), Toast.LENGTH_SHORT) + .show(); Intent in = new Intent(this, BluetoothOppBtEnablingActivity.class); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java index dd850a775b3..dac2dfd0e08 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java @@ -52,18 +52,13 @@ import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.internal.annotations.VisibleForTesting; -/** - * This class is designed to show BT enabling progress. - */ +/** This class is designed to show BT enabling progress. */ public class BluetoothOppBtEnablingActivity extends AlertActivity { private static final String TAG = "BluetoothOppEnablingActivity"; - - private static final int BT_ENABLING_TIMEOUT = 0; - @VisibleForTesting - static int sBtEnablingTimeoutMs = 20000; + @VisibleForTesting static int sBtEnablingTimeoutMs = 20000; private boolean mRegistered = false; @@ -89,8 +84,8 @@ public class BluetoothOppBtEnablingActivity extends AlertActivity { setupAlert(); // Add timeout for enabling progress - mTimeoutHandler.sendMessageDelayed(mTimeoutHandler.obtainMessage(BT_ENABLING_TIMEOUT), - sBtEnablingTimeoutMs); + mTimeoutHandler.sendMessageDelayed( + mTimeoutHandler.obtainMessage(BT_ENABLING_TIMEOUT), sBtEnablingTimeoutMs); } private View createView() { @@ -120,38 +115,41 @@ public class BluetoothOppBtEnablingActivity extends AlertActivity { } @VisibleForTesting - final Handler mTimeoutHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case BT_ENABLING_TIMEOUT: - Log.v(TAG, "Received BT_ENABLING_TIMEOUT msg."); - cancelSendingProgress(); - break; - default: - break; - } - } - }; + final Handler mTimeoutHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case BT_ENABLING_TIMEOUT: + Log.v(TAG, "Received BT_ENABLING_TIMEOUT msg."); + cancelSendingProgress(); + break; + default: + break; + } + } + }; @VisibleForTesting - final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Log.v(TAG, "Received intent: " + action); - if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - switch (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { - case BluetoothAdapter.STATE_ON: - mTimeoutHandler.removeMessages(BT_ENABLING_TIMEOUT); - finish(); - break; - default: - break; + final BroadcastReceiver mBluetoothReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.v(TAG, "Received intent: " + action); + if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + switch (intent.getIntExtra( + BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { + case BluetoothAdapter.STATE_ON: + mTimeoutHandler.removeMessages(BT_ENABLING_TIMEOUT); + finish(); + break; + default: + break; + } + } } - } - } - }; + }; private void cancelSendingProgress() { BluetoothOppManager mOppManager = BluetoothOppManager.getInstance(this); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java index d2bdc13d569..2a2c906dfa9 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java @@ -42,9 +42,7 @@ import android.widget.TextView; import com.android.bluetooth.R; -/** - * This class is designed to show BT error messages; - */ +/** This class is designed to show BT error messages; */ public class BluetoothOppBtErrorActivity extends AlertActivity { @Override @@ -70,5 +68,4 @@ public class BluetoothOppBtErrorActivity extends AlertActivity { contentView.setText(errorContent); return view; } - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java index c2edf446c45..9867b67a85d 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java @@ -37,8 +37,8 @@ public class BluetoothOppHandoverReceiver extends BroadcastReceiver { String action = intent.getAction(); Log.d(TAG, "Action :" + action); if (action == null) return; - if (action.equals(Constants.ACTION_HANDOVER_SEND) || action.equals( - Constants.ACTION_HANDOVER_SEND_MULTIPLE)) { + if (action.equals(Constants.ACTION_HANDOVER_SEND) + || action.equals(Constants.ACTION_HANDOVER_SEND_MULTIPLE)) { final BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device == null) { @@ -60,15 +60,21 @@ public class BluetoothOppHandoverReceiver extends BroadcastReceiver { if (mimeType != null && uris != null && !uris.isEmpty()) { final Context finalContext = context; final ArrayList finalUris = uris; - Thread t = new Thread(new Runnable() { - @Override - public void run() { - BluetoothOppManager.getInstance(finalContext) - .saveSendingFileInfo(mimeType, finalUris, true /* isHandover */, - true /* fromExternal */); - BluetoothOppManager.getInstance(finalContext).startTransfer(device); - } - }); + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + BluetoothOppManager.getInstance(finalContext) + .saveSendingFileInfo( + mimeType, + finalUris, + true /* isHandover */, + true /* fromExternal */); + BluetoothOppManager.getInstance(finalContext) + .startTransfer(device); + } + }); t.start(); } else { Log.d(TAG, "No mimeType or stream attached to handover request"); @@ -92,12 +98,12 @@ public class BluetoothOppHandoverReceiver extends BroadcastReceiver { Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id); Log.d(TAG, "Stopping handover transfer with Uri " + contentUri); - BluetoothMethodProxy.getInstance().contentResolverDelete( - context.getContentResolver(), contentUri, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + context.getContentResolver(), contentUri, null, null); } } else { Log.d(TAG, "Unknown action: " + action); } } - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java index 50a3f15c9cf..61b8bbdd514 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java @@ -65,11 +65,9 @@ import com.android.internal.annotations.VisibleForTesting; public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { private static final String TAG = "BluetoothIncomingFileConfirmActivity"; - @VisibleForTesting - static final int DISMISS_TIMEOUT_DIALOG = 0; + @VisibleForTesting static final int DISMISS_TIMEOUT_DIALOG = 0; - @VisibleForTesting - static final int DISMISS_TIMEOUT_DIALOG_VALUE = 2000; + @VisibleForTesting static final int DISMISS_TIMEOUT_DIALOG_VALUE = 2000; private static final String PREFERENCE_USER_TIMEOUT = "user_timeout"; @@ -107,9 +105,10 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { mAlertBuilder.setTitle(getString(R.string.incoming_file_confirm_content)); mAlertBuilder.setView(createView()); - mAlertBuilder.setPositiveButton(R.string.incoming_file_confirm_ok, - (dialog, which) -> onIncomingFileConfirmOk()); - mAlertBuilder.setNegativeButton(R.string.incoming_file_confirm_cancel, + mAlertBuilder.setPositiveButton( + R.string.incoming_file_confirm_ok, (dialog, which) -> onIncomingFileConfirmOk()); + mAlertBuilder.setNegativeButton( + R.string.incoming_file_confirm_cancel, (dialog, which) -> onIncomingFileConfirmCancel()); setupAlert(); @@ -120,15 +119,17 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { Log.v(TAG, "BluetoothIncomingFileConfirmActivity: Got uri:" + mUri); - mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (!BluetoothShare.USER_CONFIRMATION_TIMEOUT_ACTION.equals(intent.getAction())) { - return; - } - onTimeout(); - } - }; + mReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!BluetoothShare.USER_CONFIRMATION_TIMEOUT_ACTION.equals( + intent.getAction())) { + return; + } + onTimeout(); + } + }; IntentFilter filter = new IntentFilter(BluetoothShare.USER_CONFIRMATION_TIMEOUT_ACTION); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); registerReceiver(mReceiver, filter); @@ -140,14 +141,11 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { ((TextView) view.findViewById(R.id.from_content)).setText(mTransInfo.mDeviceName); String fileName = mTransInfo.mFileName; if (fileName != null) { - fileName = fileName - .replace('\t', ' ') - .replace('\n', ' ') - .replace('\r', ' '); + fileName = fileName.replace('\t', ' ').replace('\n', ' ').replace('\r', ' '); } ((TextView) view.findViewById(R.id.filename_content)).setText(fileName); - ((TextView) view.findViewById(R.id.size_content)).setText( - Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); + ((TextView) view.findViewById(R.id.size_content)) + .setText(Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); return view; } @@ -156,10 +154,11 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { if (!mTimeout) { // Update database mUpdateValues = new ContentValues(); - mUpdateValues.put(BluetoothShare.USER_CONFIRMATION, - BluetoothShare.USER_CONFIRMATION_CONFIRMED); - BluetoothMethodProxy.getInstance().contentResolverUpdate(this.getContentResolver(), - mUri, mUpdateValues, null, null); + mUpdateValues.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_CONFIRMED); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + this.getContentResolver(), mUri, mUpdateValues, null, null); Toast.makeText(this, getString(R.string.bt_toast_1), Toast.LENGTH_SHORT).show(); } @@ -168,10 +167,10 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { private void onIncomingFileConfirmCancel() { // Update database mUpdateValues = new ContentValues(); - mUpdateValues.put(BluetoothShare.USER_CONFIRMATION, - BluetoothShare.USER_CONFIRMATION_DENIED); - BluetoothMethodProxy.getInstance().contentResolverUpdate(this.getContentResolver(), - mUri, mUpdateValues, null, null); + mUpdateValues.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_DENIED); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(this.getContentResolver(), mUri, mUpdateValues, null, null); } @Override @@ -212,29 +211,30 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { private void onTimeout() { mTimeout = true; - changeTitle(getString( - R.string.incoming_file_confirm_timeout_content, - mTransInfo.mDeviceName)); + changeTitle( + getString(R.string.incoming_file_confirm_timeout_content, mTransInfo.mDeviceName)); changeButtonVisibility(DialogInterface.BUTTON_NEGATIVE, View.GONE); changeButtonText( DialogInterface.BUTTON_POSITIVE, getString(R.string.incoming_file_confirm_timeout_ok)); - BluetoothMethodProxy.getInstance().handlerSendMessageDelayed(mTimeoutHandler, - DISMISS_TIMEOUT_DIALOG, DISMISS_TIMEOUT_DIALOG_VALUE); + BluetoothMethodProxy.getInstance() + .handlerSendMessageDelayed( + mTimeoutHandler, DISMISS_TIMEOUT_DIALOG, DISMISS_TIMEOUT_DIALOG_VALUE); } - private final Handler mTimeoutHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case DISMISS_TIMEOUT_DIALOG: - Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg."); - finish(); - break; - default: - break; - } - } - }; + private final Handler mTimeoutHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case DISMISS_TIMEOUT_DIALOG: + Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg."); + finish(); + break; + default: + break; + } + } + }; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java index fce25238ffb..92af97a491e 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java @@ -95,7 +95,7 @@ public class BluetoothOppLauncherActivity extends Activity { } if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { - //Check if Bluetooth is available in the beginning instead of at the end + // Check if Bluetooth is available in the beginning instead of at the end if (!isBluetoothAllowed()) { Intent in = new Intent(this, BluetoothOppBtErrorActivity.class); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -122,33 +122,47 @@ public class BluetoothOppLauncherActivity extends Activity { // EXTRA_TEXT, we will try send this TEXT out; Currently in // Browser, share one link goes to this case; if (stream != null && type != null) { - Log.v(TAG, - "Get ACTION_SEND intent: Uri = " + stream + "; mimetype = " + type); + Log.v(TAG, "Get ACTION_SEND intent: Uri = " + stream + "; mimetype = " + type); // Save type/stream, will be used when adding transfer // session to DB. - Thread t = new Thread(new Runnable() { - @Override - public void run() { - sendFileInfo(type, stream.toString(), false /* isHandover */, true /* - fromExternal */); - } - }); + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + sendFileInfo( + type, + stream.toString(), + false /* isHandover */, + true /* + fromExternal */); + } + }); t.start(); return; } else if (extraText != null && type != null) { - Log.v(TAG, - "Get ACTION_SEND intent with Extra_text = " + extraText.toString() - + "; mimetype = " + type); - final Uri fileUri = createFileForSharedContent( - this.createCredentialProtectedStorageContext(), extraText); + Log.v( + TAG, + "Get ACTION_SEND intent with Extra_text = " + + extraText.toString() + + "; mimetype = " + + type); + final Uri fileUri = + createFileForSharedContent( + this.createCredentialProtectedStorageContext(), extraText); if (fileUri != null) { - Thread t = new Thread(new Runnable() { - @Override - public void run() { - sendFileInfo(type, fileUri.toString(), false /* isHandover */, - false /* fromExternal */); - } - }); + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + sendFileInfo( + type, + fileUri.toString(), + false /* isHandover */, + false /* fromExternal */); + } + }); t.start(); return; } else { @@ -177,8 +191,12 @@ public class BluetoothOppLauncherActivity extends Activity { final String mimeType = intent.getType(); final ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (mimeType != null && uris != null) { - Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= " - + mimeType); + Log.v( + TAG, + "Get ACTION_SHARE_MULTIPLE intent: uris " + + uris + + "\n Type= " + + mimeType); Thread t = new Thread( new Runnable() { @@ -247,6 +265,7 @@ public class BluetoothOppLauncherActivity extends Activity { /** * Turns on Bluetooth if not already on, or launches device picker if Bluetooth is on + * * @return */ @VisibleForTesting @@ -264,11 +283,12 @@ public class BluetoothOppLauncherActivity extends Activity { Intent in1 = new Intent(BluetoothDevicePicker.ACTION_LAUNCH); in1.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); in1.putExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false); - in1.putExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE, + in1.putExtra( + BluetoothDevicePicker.EXTRA_FILTER_TYPE, BluetoothDevicePicker.FILTER_TYPE_TRANSFER); in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE, getPackageName()); - in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS, - BluetoothOppReceiver.class.getName()); + in1.putExtra( + BluetoothDevicePicker.EXTRA_LAUNCH_CLASS, BluetoothOppReceiver.class.getName()); Log.v(TAG, "Launching " + BluetoothDevicePicker.ACTION_LAUNCH); startActivity(in1); } @@ -289,18 +309,19 @@ public class BluetoothOppLauncherActivity extends Activity { final String airplaneModeRadios = Settings.System.getString(resolver, Settings.Global.AIRPLANE_MODE_RADIOS); final boolean isAirplaneSensitive = - airplaneModeRadios == null || airplaneModeRadios.contains( - Settings.Global.RADIO_BLUETOOTH); + airplaneModeRadios == null + || airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH); if (!isAirplaneSensitive) { return true; } // Check if Bluetooth may be enabled in airplane mode - final String airplaneModeToggleableRadios = Settings.System.getString(resolver, - Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); + final String airplaneModeToggleableRadios = + Settings.System.getString( + resolver, Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); final boolean isAirplaneToggleable = - airplaneModeToggleableRadios != null && airplaneModeToggleableRadios.contains( - Settings.Global.RADIO_BLUETOOTH); + airplaneModeToggleableRadios != null + && airplaneModeToggleableRadios.contains(Settings.Global.RADIO_BLUETOOTH); if (isAirplaneToggleable) { return true; } @@ -324,17 +345,25 @@ public class BluetoothOppLauncherActivity extends Activity { /* * Convert the plain text to HTML */ - StringBuffer sb = new StringBuffer(""); + StringBuffer sb = + new StringBuffer( + ""); // Escape any inadvertent HTML in the text message String text = escapeCharacterToDisplay(shareContent.toString()); // Regex that matches Web URL protocol part as case insensitive. Pattern webUrlProtocol = Pattern.compile("(?i)(http|https)://"); - Pattern pattern = Pattern.compile( - "(" + Patterns.WEB_URL.pattern() + ")|(" + Patterns.EMAIL_ADDRESS.pattern() - + ")|(" + Patterns.PHONE.pattern() + ")"); + Pattern pattern = + Pattern.compile( + "(" + + Patterns.WEB_URL.pattern() + + ")|(" + + Patterns.EMAIL_ADDRESS.pattern() + + ")|(" + + Patterns.PHONE.pattern() + + ")"); // Find any embedded URL's and linkify Matcher m = pattern.matcher(text); while (m.find()) { @@ -347,8 +376,9 @@ public class BluetoothOppLauncherActivity extends Activity { if (proto.find()) { // This is work around to force URL protocol part be lower case, // because WebView could follow only lower case protocol link. - link = proto.group().toLowerCase(Locale.US) + matchStr.substring( - proto.end()); + link = + proto.group().toLowerCase(Locale.US) + + matchStr.substring(proto.end()); } else { // Patterns.WEB_URL matches URL without protocol part, // so added default protocol to link. @@ -461,8 +491,7 @@ public class BluetoothOppLauncherActivity extends Activity { } @VisibleForTesting - void sendFileInfo(String mimeType, String uriString, boolean isHandover, - boolean fromExternal) { + void sendFileInfo(String mimeType, String uriString, boolean isHandover, boolean fromExternal) { BluetoothOppManager manager = BluetoothOppManager.getInstance(getApplicationContext()); try { manager.saveSendingFileInfo(mimeType, uriString, isHandover, fromExternal); @@ -480,12 +509,12 @@ public class BluetoothOppLauncherActivity extends Activity { } private void showToast(final String msg) { - BluetoothOppLauncherActivity.this.runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); - } - }); + BluetoothOppLauncherActivity.this.runOnUiThread( + new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); + } + }); } - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java index c2159105c96..d5c15b63f4b 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java @@ -69,8 +69,7 @@ import java.util.List; public class BluetoothOppManager { private static final String TAG = "BluetoothOppManager"; - @VisibleForTesting - static BluetoothOppManager sInstance; + @VisibleForTesting static BluetoothOppManager sInstance; /** Used when obtaining a reference to the singleton instance. */ private static final Object INSTANCE_LOCK = new Object(); @@ -81,22 +80,17 @@ public class BluetoothOppManager { private BluetoothAdapter mAdapter; - @VisibleForTesting - String mMimeTypeOfSendingFile; + @VisibleForTesting String mMimeTypeOfSendingFile; - @VisibleForTesting - String mUriOfSendingFile; + @VisibleForTesting String mUriOfSendingFile; - @VisibleForTesting - String mMimeTypeOfSendingFiles; + @VisibleForTesting String mMimeTypeOfSendingFiles; - @VisibleForTesting - ArrayList mUrisOfSendingFiles; + @VisibleForTesting ArrayList mUrisOfSendingFiles; private boolean mIsHandoverInitiated; - @VisibleForTesting - static final String OPP_PREFERENCE_FILE = "OPPMGR"; + @VisibleForTesting static final String OPP_PREFERENCE_FILE = "OPPMGR"; private static final String SENDING_FLAG = "SENDINGFLAG"; @@ -112,8 +106,7 @@ public class BluetoothOppManager { private static final String ARRAYLIST_ITEM_SEPERATOR = ";"; - @VisibleForTesting - static final int ALLOWED_INSERT_SHARE_THREAD_NUMBER = 3; + @VisibleForTesting static final int ALLOWED_INSERT_SHARE_THREAD_NUMBER = 3; // used to judge if need continue sending process after received a // ENABLED_ACTION @@ -132,9 +125,7 @@ public class BluetoothOppManager { // The time for which the acceptlist entries remain valid. private static final int ACCEPTLIST_DURATION_MS = 15000; - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static BluetoothOppManager getInstance(Context context) { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -146,17 +137,13 @@ public class BluetoothOppManager { } } - /** - * Set Singleton instance. Intended for testing purpose - */ + /** Set Singleton instance. Intended for testing purpose */ @VisibleForTesting static void setInstance(BluetoothOppManager instance) { sInstance = instance; } - /** - * init - */ + /** init */ private boolean init(Context context) { if (mInitialized) { return true; @@ -176,7 +163,6 @@ public class BluetoothOppManager { return true; } - private void cleanupAcceptlist() { // Removes expired entries long curTime = SystemClock.elapsedRealtime(); @@ -213,9 +199,7 @@ public class BluetoothOppManager { return false; } - /** - * Restore data from preference - */ + /** Restore data from preference */ private void restoreApplicationData() { SharedPreferences settings = mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0); @@ -226,8 +210,13 @@ public class BluetoothOppManager { mMimeTypeOfSendingFiles = settings.getString(MIME_TYPE_MULTIPLE, null); mMultipleFlag = settings.getBoolean(MULTIPLE_FLAG, false); - Log.v(TAG, "restoreApplicationData! " + mSendingFlag + mMultipleFlag - + mMimeTypeOfSendingFile + mUriOfSendingFile); + Log.v( + TAG, + "restoreApplicationData! " + + mSendingFlag + + mMultipleFlag + + mMimeTypeOfSendingFile + + mUriOfSendingFile); String strUris = settings.getString(FILE_URIS, null); mUrisOfSendingFiles = new ArrayList(); @@ -242,9 +231,7 @@ public class BluetoothOppManager { mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0).edit().clear().apply(); } - /** - * Save application data to preference, need restore these data when service restart - */ + /** Save application data to preference, need restore these data when service restart */ private void storeApplicationData() { SharedPreferences.Editor editor = mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0).edit(); @@ -274,16 +261,17 @@ public class BluetoothOppManager { Log.v(TAG, "Application data stored to SharedPreference! "); } - public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover, - boolean fromExternal) throws IllegalArgumentException { + public void saveSendingFileInfo( + String mimeType, String uriString, boolean isHandover, boolean fromExternal) + throws IllegalArgumentException { synchronized (BluetoothOppManager.this) { mMultipleFlag = false; mMimeTypeOfSendingFile = mimeType; mIsHandoverInitiated = isHandover; Uri uri = Uri.parse(uriString); BluetoothOppSendFileInfo sendFileInfo = - BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType, - fromExternal); + BluetoothOppSendFileInfo.generateFileInfo( + mContext, uri, mimeType, fromExternal); uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); mUriOfSendingFile = uri.toString(); @@ -291,8 +279,9 @@ public class BluetoothOppManager { } } - public void saveSendingFileInfo(String mimeType, ArrayList uris, boolean isHandover, - boolean fromExternal) throws IllegalArgumentException { + public void saveSendingFileInfo( + String mimeType, ArrayList uris, boolean isHandover, boolean fromExternal) + throws IllegalArgumentException { synchronized (BluetoothOppManager.this) { mMultipleFlag = true; mMimeTypeOfSendingFiles = mimeType; @@ -300,8 +289,8 @@ public class BluetoothOppManager { mIsHandoverInitiated = isHandover; for (Uri uri : uris) { BluetoothOppSendFileInfo sendFileInfo = - BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType, - fromExternal); + BluetoothOppSendFileInfo.generateFileInfo( + mContext, uri, mimeType, fromExternal); uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); mUrisOfSendingFiles.add(uri); BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); @@ -312,6 +301,7 @@ public class BluetoothOppManager { /** * Get the current status of Bluetooth hardware. + * * @return true if Bluetooth enabled, false otherwise. */ public boolean isEnabled() { @@ -323,27 +313,21 @@ public class BluetoothOppManager { } } - /** - * Enable Bluetooth hardware. - */ + /** Enable Bluetooth hardware. */ public void enableBluetooth() { if (mAdapter != null) { mAdapter.enable(); } } - /** - * Disable Bluetooth hardware. - */ + /** Disable Bluetooth hardware. */ public void disableBluetooth() { if (mAdapter != null) { mAdapter.disable(); } } - /** - * Get device name per bluetooth address. - */ + /** Get device name per bluetooth address. */ public String getDeviceName(BluetoothDevice device) { String deviceName = null; @@ -367,9 +351,7 @@ public class BluetoothOppManager { } } - /** - * Fork a thread to insert share info to db. - */ + /** Fork a thread to insert share info to db. */ public void startTransfer(BluetoothDevice device) { Log.v(TAG, "Active InsertShareThread number is : " + mInsertShareThreadNum); InsertShareInfoThread insertThread; @@ -391,9 +373,15 @@ public class BluetoothOppManager { return; } - insertThread = new InsertShareInfoThread(device, mMultipleFlag, mMimeTypeOfSendingFile, - mUriOfSendingFile, mMimeTypeOfSendingFiles, mUrisOfSendingFiles, - mIsHandoverInitiated); + insertThread = + new InsertShareInfoThread( + device, + mMultipleFlag, + mMimeTypeOfSendingFile, + mUriOfSendingFile, + mMimeTypeOfSendingFiles, + mUrisOfSendingFiles, + mIsHandoverInitiated); if (mMultipleFlag) { mFileNumInBatch = mUrisOfSendingFiles.size(); } @@ -403,12 +391,11 @@ public class BluetoothOppManager { } /** - * Thread to insert share info to db. In multiple files (say 100 files) - * share case, the inserting share info to db operation would be a time - * consuming operation, so need a thread to handle it. This thread allows - * multiple instances to support below case: User select multiple files to - * share to one device (say device 1), and then right away share to second - * device (device 2), we need insert all these share info to db. + * Thread to insert share info to db. In multiple files (say 100 files) share case, the + * inserting share info to db operation would be a time consuming operation, so need a thread to + * handle it. This thread allows multiple instances to support below case: User select multiple + * files to share to one device (say device 1), and then right away share to second device + * (device 2), we need insert all these share info to db. */ private class InsertShareInfoThread extends Thread { private final BluetoothDevice mRemoteDevice; @@ -425,8 +412,13 @@ public class BluetoothOppManager { private final boolean mIsHandoverInitiated; - InsertShareInfoThread(BluetoothDevice device, boolean multiple, String typeOfSingleFile, - String uri, String typeOfMultipleFiles, ArrayList uris, + InsertShareInfoThread( + BluetoothDevice device, + boolean multiple, + String typeOfSingleFile, + String uri, + String typeOfMultipleFiles, + ArrayList uris, boolean handoverInitiated) { super("Insert ShareInfo Thread"); this.mRemoteDevice = device; @@ -466,9 +458,7 @@ public class BluetoothOppManager { } } - /** - * Insert multiple sending sessions to db, only used by Opp application. - */ + /** Insert multiple sending sessions to db, only used by Opp application. */ private void insertMultipleShare() { int count = mUris.size(); Long ts = System.currentTimeMillis(); @@ -492,19 +482,26 @@ public class BluetoothOppManager { : mRemoteDevice.getIdentityAddress()); values.put(BluetoothShare.TIMESTAMP, ts); if (mIsHandoverInitiated) { - values.put(BluetoothShare.USER_CONFIRMATION, + values.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } - final Uri contentUri = BluetoothMethodProxy.getInstance().contentResolverInsert( - mContext.getContentResolver(), BluetoothShare.CONTENT_URI, values); - Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " + getDeviceName( - mRemoteDevice)); + final Uri contentUri = + BluetoothMethodProxy.getInstance() + .contentResolverInsert( + mContext.getContentResolver(), + BluetoothShare.CONTENT_URI, + values); + Log.v( + TAG, + "Insert contentUri: " + + contentUri + + " to device: " + + getDeviceName(mRemoteDevice)); } } - /** - * Insert single sending session to db, only used by Opp application. - */ + /** Insert single sending session to db, only used by Opp application. */ private void insertSingleShare() { ContentValues values = new ContentValues(); values.put(BluetoothShare.URI, mUri); @@ -515,13 +512,22 @@ public class BluetoothOppManager { ? Utils.getBrEdrAddress(mRemoteDevice) : mRemoteDevice.getIdentityAddress()); if (mIsHandoverInitiated) { - values.put(BluetoothShare.USER_CONFIRMATION, + values.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } - final Uri contentUri = BluetoothMethodProxy.getInstance().contentResolverInsert( - mContext.getContentResolver(), BluetoothShare.CONTENT_URI, values); - Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " + getDeviceName( - mRemoteDevice)); + final Uri contentUri = + BluetoothMethodProxy.getInstance() + .contentResolverInsert( + mContext.getContentResolver(), + BluetoothShare.CONTENT_URI, + values); + Log.v( + TAG, + "Insert contentUri: " + + contentUri + + " to device: " + + getDeviceName(mRemoteDevice)); } } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java index 7590ca4b2a6..87145b17d06 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java @@ -58,9 +58,8 @@ import com.google.common.annotations.VisibleForTesting; import java.util.HashMap; /** - * This class handles the updating of the Notification Manager for the cases - * where there is an ongoing transfer, incoming transfer need confirm and - * complete (successful or failed) transfer. + * This class handles the updating of the Notification Manager for the cases where there is an + * ongoing transfer, incoming transfer need confirm and complete (successful or failed) transfer. */ class BluetoothOppNotification { private static final String TAG = "BluetoothOppNotification"; @@ -68,18 +67,38 @@ class BluetoothOppNotification { static final String STATUS = "(" + BluetoothShare.STATUS + " == '192'" + ")"; static final String VISIBLE = - "(" + BluetoothShare.VISIBILITY + " IS NULL OR " + BluetoothShare.VISIBILITY + " == '" - + BluetoothShare.VISIBILITY_VISIBLE + "'" + ")"; + "(" + + BluetoothShare.VISIBILITY + + " IS NULL OR " + + BluetoothShare.VISIBILITY + + " == '" + + BluetoothShare.VISIBILITY_VISIBLE + + "'" + + ")"; - static final String CONFIRM = "(" + BluetoothShare.USER_CONFIRMATION + " == '" - + BluetoothShare.USER_CONFIRMATION_CONFIRMED + "' OR " - + BluetoothShare.USER_CONFIRMATION + " == '" - + BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED + "' OR " - + BluetoothShare.USER_CONFIRMATION + " == '" - + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED + "'" + ")"; + static final String CONFIRM = + "(" + + BluetoothShare.USER_CONFIRMATION + + " == '" + + BluetoothShare.USER_CONFIRMATION_CONFIRMED + + "' OR " + + BluetoothShare.USER_CONFIRMATION + + " == '" + + BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED + + "' OR " + + BluetoothShare.USER_CONFIRMATION + + " == '" + + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED + + "'" + + ")"; - static final String NOT_THROUGH_HANDOVER = "(" + BluetoothShare.USER_CONFIRMATION + " != '" - + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED + "'" + ")"; + static final String NOT_THROUGH_HANDOVER = + "(" + + BluetoothShare.USER_CONFIRMATION + + " != '" + + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED + + "'" + + ")"; static final String WHERE_RUNNING = STATUS + " AND " + VISIBLE + " AND " + CONFIRM; @@ -106,8 +125,12 @@ class BluetoothOppNotification { + ")"; private static final String WHERE_CONFIRM_PENDING = - BluetoothShare.USER_CONFIRMATION + " == '" + BluetoothShare.USER_CONFIRMATION_PENDING - + "'" + " AND " + VISIBLE; + BluetoothShare.USER_CONFIRMATION + + " == '" + + BluetoothShare.USER_CONFIRMATION_PENDING + + "'" + + " AND " + + VISIBLE; public NotificationManager mNotificationMgr; @@ -124,11 +147,9 @@ class BluetoothOppNotification { public static final int NOTIFICATION_ID_PROGRESS = -1000004; - @VisibleForTesting - static final int NOTIFICATION_ID_OUTBOUND_COMPLETE = -1000005; + @VisibleForTesting static final int NOTIFICATION_ID_OUTBOUND_COMPLETE = -1000005; - @VisibleForTesting - static final int NOTIFICATION_ID_INBOUND_COMPLETE = -1000006; + @VisibleForTesting static final int NOTIFICATION_ID_INBOUND_COMPLETE = -1000006; static final int NOTIFICATION_ID_COMPLETE_SUMMARY = -1000007; @@ -143,9 +164,7 @@ class BluetoothOppNotification { private ContentResolver mContentResolver = null; - /** - * This inner class is used to describe some properties for one transfer. - */ + /** This inner class is used to describe some properties for one transfer. */ static class NotificationItem { public int id; // This first field _id in db; @@ -168,24 +187,23 @@ class BluetoothOppNotification { /** * Constructor * - * @param ctx The context to use to obtain access to the Notification - * Service + * @param ctx The context to use to obtain access to the Notification Service */ BluetoothOppNotification(Context ctx) { mContext = ctx; mNotificationMgr = mContext.getSystemService(NotificationManager.class); - mNotificationChannel = new NotificationChannel(OPP_NOTIFICATION_CHANNEL, - mContext.getString(R.string.opp_notification_group), - NotificationManager.IMPORTANCE_HIGH); + mNotificationChannel = + new NotificationChannel( + OPP_NOTIFICATION_CHANNEL, + mContext.getString(R.string.opp_notification_group), + NotificationManager.IMPORTANCE_HIGH); mNotificationMgr.createNotificationChannel(mNotificationChannel); // Get Content Resolver object one time mContentResolver = mContext.getContentResolver(); } - /** - * Update the notification ui. - */ + /** Update the notification ui. */ public void updateNotification() { synchronized (BluetoothOppNotification.this) { mPendingUpdate++; @@ -208,27 +226,30 @@ class BluetoothOppNotification { // 3. Handler sends a delayed message to self // 4. Handler checks if there are any more updates after 1 second. // 5. If there is an update, update it else stop. - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case NOTIFY: - synchronized (BluetoothOppNotification.this) { - if (mPendingUpdate > 0 && mUpdateNotificationThread == null) { - Log.v(TAG, "new notify threadi!"); - mUpdateNotificationThread = new NotificationUpdateThread(); - mUpdateNotificationThread.start(); - Log.v(TAG, "send delay message"); - mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000); - } else if (mPendingUpdate > 0) { - Log.v(TAG, "previous thread is not finished yet"); - mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000); - } - break; + private Handler mHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NOTIFY: + synchronized (BluetoothOppNotification.this) { + if (mPendingUpdate > 0 && mUpdateNotificationThread == null) { + Log.v(TAG, "new notify threadi!"); + mUpdateNotificationThread = new NotificationUpdateThread(); + mUpdateNotificationThread.start(); + Log.v(TAG, "send delay message"); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(NOTIFY), 1000); + } else if (mPendingUpdate > 0) { + Log.v(TAG, "previous thread is not finished yet"); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(NOTIFY), 1000); + } + break; + } } - } - } - }; + } + }; private class NotificationUpdateThread extends Thread { @@ -258,8 +279,15 @@ class BluetoothOppNotification { @VisibleForTesting void updateActiveNotification() { // Active transfers - Cursor cursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mContentResolver, - BluetoothShare.CONTENT_URI, null, WHERE_RUNNING, null, BluetoothShare._ID); + Cursor cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + BluetoothShare.CONTENT_URI, + null, + WHERE_RUNNING, + null, + BluetoothShare._ID); if (cursor == null) { return; } @@ -328,8 +356,16 @@ class BluetoothOppNotification { item.destination = destination; mNotifications.put(batchID, item); - Log.v(TAG, "ID=" + item.id + "; batchID=" + batchID + "; totoalCurrent" - + item.totalCurrent + "; totalTotal=" + item.totalTotal); + Log.v( + TAG, + "ID=" + + item.id + + "; batchID=" + + batchID + + "; totoalCurrent" + + item.totalCurrent + + "; totalTotal=" + + item.totalTotal); } } cursor.close(); @@ -347,10 +383,12 @@ class BluetoothOppNotification { // Let NFC service deal with notifications for this transfer Intent intent = new Intent(Constants.ACTION_BT_OPP_TRANSFER_PROGRESS); if (item.direction == BluetoothShare.DIRECTION_INBOUND) { - intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, + intent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, Constants.DIRECTION_BLUETOOTH_INCOMING); } else { - intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, + intent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, Constants.DIRECTION_BLUETOOTH_OUTGOING); } intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_ID, item.id); @@ -366,17 +404,27 @@ class BluetoothOppNotification { // TODO: split description into two rows with filename in second row Notification.Builder b = new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL); b.setOnlyAlertOnce(true); - b.setColor(mContext.getResources() - .getColor(android.R.color.system_notification_accent_color, - mContext.getTheme())); + b.setColor( + mContext.getResources() + .getColor( + android.R.color.system_notification_accent_color, + mContext.getTheme())); b.setContentTitle(item.description); b.setSubText( BluetoothOppUtility.formatProgressText(item.totalTotal, item.totalCurrent)); if (item.totalTotal != 0) { - Log.v(TAG, "mCurrentBytes: " + item.totalCurrent + " mTotalBytes: " - + item.totalTotal + " (" + (int) ((item.totalCurrent * 100) - / item.totalTotal) + " %)"); - b.setProgress(100, (int) ((item.totalCurrent * 100) / item.totalTotal), + Log.v( + TAG, + "mCurrentBytes: " + + item.totalCurrent + + " mTotalBytes: " + + item.totalTotal + + " (" + + (int) ((item.totalCurrent * 100) / item.totalTotal) + + " %)"); + b.setProgress( + 100, + (int) ((item.totalCurrent * 100) / item.totalTotal), item.totalTotal == -1); } else { b.setProgress(100, 100, item.totalTotal == -1); @@ -395,8 +443,8 @@ class BluetoothOppNotification { Intent intent = new Intent(Constants.ACTION_LIST); intent.setClassName(mContext, BluetoothOppReceiver.class.getName()); intent.setDataAndNormalize(Uri.parse(BluetoothShare.CONTENT_URI + "/" + item.id)); - b.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_IMMUTABLE)); + b.setContentIntent( + PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE)); if (Flags.oppFixMultipleNotificationsIssues()) { b.setGroup(NOTIFICATION_GROUP_KEY_PROGRESS); } @@ -415,9 +463,15 @@ class BluetoothOppNotification { int inboundFailNumber = 0; // Creating outbound notification - Cursor cursor = BluetoothMethodProxy.getInstance() - .contentResolverQuery(mContentResolver, BluetoothShare.CONTENT_URI, null, - WHERE_COMPLETED_OUTBOUND, null, BluetoothShare.TIMESTAMP + " DESC"); + Cursor cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + BluetoothShare.CONTENT_URI, + null, + WHERE_COMPLETED_OUTBOUND, + null, + BluetoothShare.TIMESTAMP + " DESC"); if (cursor == null) { return; } @@ -444,8 +498,9 @@ class BluetoothOppNotification { outboundNum = outboundSuccNumber + outboundFailNumber; // create the outbound notification if (outboundNum > 0) { - String caption = BluetoothOppUtility.formatResultText(outboundSuccNumber, - outboundFailNumber, mContext); + String caption = + BluetoothOppUtility.formatResultText( + outboundSuccNumber, outboundFailNumber, mContext); PendingIntent pi; if (Flags.oppStartActivityDirectlyFromNotification()) { @@ -468,20 +523,24 @@ class BluetoothOppNotification { } Notification.Builder b = - new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( - true) + new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL) + .setOnlyAlertOnce(true) .setContentTitle(mContext.getString(R.string.outbound_noti_title)) .setContentText(caption) .setSmallIcon(android.R.drawable.stat_sys_upload_done) - .setColor(mContext.getResources() - .getColor( - android.R.color - .system_notification_accent_color, - mContext.getTheme())) + .setColor( + mContext.getResources() + .getColor( + android.R.color + .system_notification_accent_color, + mContext.getTheme())) .setContentIntent(pi) .setDeleteIntent( - PendingIntent.getBroadcast(mContext, 0, deleteIntent, - PendingIntent.FLAG_IMMUTABLE)) + PendingIntent.getBroadcast( + mContext, + 0, + deleteIntent, + PendingIntent.FLAG_IMMUTABLE)) .setWhen(timeStamp) .setLocalOnly(true); if (Flags.oppFixMultipleNotificationsIssues()) { @@ -496,9 +555,15 @@ class BluetoothOppNotification { } // Creating inbound notification - cursor = BluetoothMethodProxy.getInstance() - .contentResolverQuery(mContentResolver, BluetoothShare.CONTENT_URI, null, - WHERE_COMPLETED_INBOUND, null, BluetoothShare.TIMESTAMP + " DESC"); + cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + BluetoothShare.CONTENT_URI, + null, + WHERE_COMPLETED_INBOUND, + null, + BluetoothShare.TIMESTAMP + " DESC"); if (cursor == null) { return; } @@ -522,8 +587,9 @@ class BluetoothOppNotification { inboundNum = inboundSuccNumber + inboundFailNumber; // create the inbound notification if (inboundNum > 0) { - String caption = BluetoothOppUtility.formatResultText(inboundSuccNumber, - inboundFailNumber, mContext); + String caption = + BluetoothOppUtility.formatResultText( + inboundSuccNumber, inboundFailNumber, mContext); PendingIntent pi; if (Flags.oppStartActivityDirectlyFromNotification()) { @@ -546,21 +612,24 @@ class BluetoothOppNotification { } Notification.Builder b = - new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( - true) + new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL) + .setOnlyAlertOnce(true) .setContentTitle(mContext.getString(R.string.inbound_noti_title)) .setContentText(caption) .setSmallIcon(android.R.drawable.stat_sys_download_done) - .setColor(mContext.getResources() - .getColor( - android.R.color - .system_notification_accent_color, - mContext.getTheme())) - + .setColor( + mContext.getResources() + .getColor( + android.R.color + .system_notification_accent_color, + mContext.getTheme())) .setContentIntent(pi) .setDeleteIntent( - PendingIntent.getBroadcast(mContext, 0, deleteIntent, - PendingIntent.FLAG_IMMUTABLE)) + PendingIntent.getBroadcast( + mContext, + 0, + deleteIntent, + PendingIntent.FLAG_IMMUTABLE)) .setWhen(timeStamp) .setLocalOnly(true); if (Flags.oppFixMultipleNotificationsIssues()) { @@ -595,9 +664,15 @@ class BluetoothOppNotification { @VisibleForTesting void updateIncomingFileConfirmNotification() { - Cursor cursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mContentResolver, - BluetoothShare.CONTENT_URI, null, WHERE_CONFIRM_PENDING, - null, BluetoothShare._ID); + Cursor cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + BluetoothShare.CONTENT_URI, + null, + WHERE_CONFIRM_PENDING, + null, + BluetoothShare._ID); if (cursor == null) { return; @@ -608,22 +683,32 @@ class BluetoothOppNotification { BluetoothOppUtility.fillRecord(mContext, cursor, info); Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + info.mID); String fileNameSafe = info.mFileName.replaceAll("\\s", "_"); - Intent baseIntent = new Intent().setDataAndNormalize(contentUri) - .setClassName(mContext, - BluetoothOppReceiver.class.getName()); + Intent baseIntent = + new Intent() + .setDataAndNormalize(contentUri) + .setClassName(mContext, BluetoothOppReceiver.class.getName()); Notification.Action actionDecline = - new Notification.Action.Builder(Icon.createWithResource(mContext, - R.drawable.ic_decline), - mContext.getText(R.string.incoming_file_confirm_cancel), - PendingIntent.getBroadcast(mContext, 0, - new Intent(baseIntent).setAction(Constants.ACTION_DECLINE), - PendingIntent.FLAG_IMMUTABLE)).build(); - Notification.Action actionAccept = new Notification.Action.Builder( - Icon.createWithResource(mContext,R.drawable.ic_accept), - mContext.getText(R.string.incoming_file_confirm_ok), - PendingIntent.getBroadcast(mContext, 0, - new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT), - PendingIntent.FLAG_IMMUTABLE)).build(); + new Notification.Action.Builder( + Icon.createWithResource(mContext, R.drawable.ic_decline), + mContext.getText(R.string.incoming_file_confirm_cancel), + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(baseIntent) + .setAction(Constants.ACTION_DECLINE), + PendingIntent.FLAG_IMMUTABLE)) + .build(); + Notification.Action actionAccept = + new Notification.Action.Builder( + Icon.createWithResource(mContext, R.drawable.ic_accept), + mContext.getText(R.string.incoming_file_confirm_ok), + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(baseIntent) + .setAction(Constants.ACTION_ACCEPT), + PendingIntent.FLAG_IMMUTABLE)) + .build(); PendingIntent contentIntent; if (Flags.oppStartActivityDirectlyFromNotification()) { @@ -644,25 +729,35 @@ class BluetoothOppNotification { } Notification.Builder publicNotificationBuilder = - new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( - true) + new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL) + .setOnlyAlertOnce(true) .setOngoing(true) .setWhen(info.mTimeStamp) .setContentIntent(contentIntent) - .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, - new Intent(baseIntent).setAction(Constants.ACTION_HIDE), - PendingIntent.FLAG_IMMUTABLE)) - .setColor(mContext.getResources() - .getColor( - android.R.color - .system_notification_accent_color, - mContext.getTheme())) - .setContentTitle(mContext.getText( - R.string.incoming_file_confirm_Notification_title)) + .setDeleteIntent( + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(baseIntent).setAction(Constants.ACTION_HIDE), + PendingIntent.FLAG_IMMUTABLE)) + .setColor( + mContext.getResources() + .getColor( + android.R.color + .system_notification_accent_color, + mContext.getTheme())) + .setContentTitle( + mContext.getText( + R.string.incoming_file_confirm_Notification_title)) .setContentText(fileNameSafe) - .setStyle(new Notification.BigTextStyle().bigText(mContext.getString( - R.string.incoming_file_confirm_Notification_content, - info.mDeviceName, fileNameSafe))) + .setStyle( + new Notification.BigTextStyle() + .bigText( + mContext.getString( + R.string + .incoming_file_confirm_Notification_content, + info.mDeviceName, + fileNameSafe))) .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes)) .setSmallIcon(R.drawable.ic_bluetooth_file_transfer_notification) .setLocalOnly(true); @@ -671,25 +766,35 @@ class BluetoothOppNotification { } Notification.Builder builder = - new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( - true) + new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL) + .setOnlyAlertOnce(true) .setOngoing(true) .setWhen(info.mTimeStamp) .setContentIntent(contentIntent) - .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, - new Intent(baseIntent).setAction(Constants.ACTION_HIDE), - PendingIntent.FLAG_IMMUTABLE)) - .setColor(mContext.getResources() - .getColor( - android.R.color - .system_notification_accent_color, - mContext.getTheme())) - .setContentTitle(mContext.getText( - R.string.incoming_file_confirm_Notification_title)) + .setDeleteIntent( + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(baseIntent).setAction(Constants.ACTION_HIDE), + PendingIntent.FLAG_IMMUTABLE)) + .setColor( + mContext.getResources() + .getColor( + android.R.color + .system_notification_accent_color, + mContext.getTheme())) + .setContentTitle( + mContext.getText( + R.string.incoming_file_confirm_Notification_title)) .setContentText(fileNameSafe) - .setStyle(new Notification.BigTextStyle().bigText(mContext.getString( - R.string.incoming_file_confirm_Notification_content, - info.mDeviceName, fileNameSafe))) + .setStyle( + new Notification.BigTextStyle() + .bigText( + mContext.getString( + R.string + .incoming_file_confirm_Notification_content, + info.mDeviceName, + fileNameSafe))) .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes)) .setSmallIcon(R.drawable.ic_bluetooth_file_transfer_notification) .setLocalOnly(true) diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java index b97e4d92056..f862ddc3017 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java @@ -77,8 +77,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { private volatile boolean mInterrupted; - @VisibleForTesting - volatile boolean mWaitingForRemote; + @VisibleForTesting volatile boolean mWaitingForRemote; private int mNumFilesAttemptedToSend; @@ -140,8 +139,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { private ObexTransport mTransport1; - @VisibleForTesting - ClientSession mCs; + @VisibleForTesting ClientSession mCs; private WakeLock mWakeLock; @@ -199,8 +197,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { doSend(); } else { try { - Log.d(TAG, "Client thread waiting for next share, sleep for " - + SLEEP_TIME); + Log.d(TAG, "Client thread waiting for next share, sleep for " + SLEEP_TIME); Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { ContentProfileErrorReportUtils.report( @@ -270,7 +267,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { 4); Log.e(TAG, "mTransport.close error"); } - } } @@ -349,9 +345,10 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } Message msg = Message.obtain(mCallbackHandler); - msg.what = (status == BluetoothShare.STATUS_SUCCESS) - ? BluetoothOppObexSession.MSG_SHARE_COMPLETE - : BluetoothOppObexSession.MSG_SESSION_ERROR; + msg.what = + (status == BluetoothShare.STATUS_SUCCESS) + ? BluetoothOppObexSession.MSG_SHARE_COMPLETE + : BluetoothOppObexSession.MSG_SESSION_ERROR; mInfo.mStatus = status; msg.obj = mInfo; msg.sendToTarget(); @@ -380,9 +377,13 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { updateValues.put(BluetoothShare.FILENAME_HINT, fileInfo.mFileName); updateValues.put(BluetoothShare.TOTAL_BYTES, fileInfo.mLength); updateValues.put(BluetoothShare.MIMETYPE, fileInfo.mMimetype); - BluetoothMethodProxy.getInstance().contentResolverUpdate( - mContext1.getContentResolver(), contentUri, updateValues, null, null); - + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext1.getContentResolver(), + contentUri, + updateValues, + null, + null); } return fileInfo; } @@ -409,8 +410,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { request.setHeader(HeaderSet.TYPE, fileInfo.mMimetype); applyRemoteDeviceQuirks(request, mInfo.mDestination, fileInfo.mFileName); - Constants.updateShareStatus(mContext1, mInfo.mId, - BluetoothShare.STATUS_RUNNING); + Constants.updateShareStatus( + mContext1, mInfo.mId, BluetoothShare.STATUS_RUNNING); request.setHeader(HeaderSet.LENGTH, fileInfo.mLength); @@ -520,7 +521,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { okToProceed = true; updateValues = new ContentValues(); updateValues.put(BluetoothShare.CURRENT_BYTES, position); - mContext1.getContentResolver() + mContext1 + .getContentResolver() .update(contentUri, updateValues, null, null); mNumFilesAttemptedToSend++; } else { @@ -544,9 +546,15 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } else { position += readLength; currentTime = SystemClock.elapsedRealtime(); - Log.v(TAG, "Sending file position = " + position - + " readLength " + readLength + " bytes took " - + (currentTime - timestamp) + " ms"); + Log.v( + TAG, + "Sending file position = " + + position + + " readLength " + + readLength + + " bytes took " + + (currentTime - timestamp) + + " ms"); // Update the Progress Bar only if there is change in percentage // or once per a period to notify NFC of this transfer is still alive percent = position * 100 / fileInfo.mLength; @@ -554,7 +562,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { || currentTime - prevTimestamp > Constants.NFC_ALIVE_CHECK_MS) { updateValues = new ContentValues(); updateValues.put(BluetoothShare.CURRENT_BYTES, position); - mContext1.getContentResolver() + mContext1 + .getContentResolver() .update(contentUri, updateValues, null, null); prevPercent = percent; prevTimestamp = currentTime; @@ -564,23 +573,36 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN || responseCode == ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) { - Log.i(TAG, "Remote reject file " + fileInfo.mFileName + " length " - + fileInfo.mLength); + Log.i( + TAG, + "Remote reject file " + + fileInfo.mFileName + + " length " + + fileInfo.mLength); status = BluetoothShare.STATUS_FORBIDDEN; } else if (responseCode == ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE) { Log.i(TAG, "Remote reject file type " + fileInfo.mMimetype); status = BluetoothShare.STATUS_NOT_ACCEPTABLE; } else if (!mInterrupted && position == fileInfo.mLength) { - Log.i(TAG, - "SendFile finished send out file " + fileInfo.mFileName + " length " + Log.i( + TAG, + "SendFile finished send out file " + + fileInfo.mFileName + + " length " + fileInfo.mLength); } else { error = true; status = BluetoothShare.STATUS_CANCELED; putOperation.abort(); /* interrupted */ - Log.i(TAG, "SendFile interrupted when send out file " + fileInfo.mFileName - + " at " + position + " of " + fileInfo.mLength); + Log.i( + TAG, + "SendFile interrupted when send out file " + + fileInfo.mFileName + + " at " + + position + + " of " + + fileInfo.mLength); } } } catch (IOException e) { @@ -676,8 +698,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { Log.e(TAG, "Error when sending file: " + exception); // Update interrupted outbound content resolver entry when // error during transfer. - Constants.updateShareStatus(mContext1, mInfo.mId, - BluetoothShare.STATUS_OBEX_DATA_ERROR); + Constants.updateShareStatus( + mContext1, mInfo.mId, BluetoothShare.STATUS_OBEX_DATA_ERROR); mCallbackHandler.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); } @@ -734,8 +756,13 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { if (modified) { String newFilename = new String(c); request.setHeader(HeaderSet.NAME, newFilename); - Log.i(TAG, "Sending file \"" + filename + "\" as \"" + newFilename - + "\" to workaround Poloroid filename quirk"); + Log.i( + TAG, + "Sending file \"" + + filename + + "\" as \"" + + newFilename + + "\" to workaround Poloroid filename quirk"); } } } @@ -744,5 +771,4 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { public void unblock() { // Not used for client case } - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java index 19b7621bf70..ff4023f94bc 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java @@ -75,51 +75,41 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler private static final String TAG = "BtOppObexServer"; - @VisibleForTesting - public ObexTransport mTransport; + @VisibleForTesting public ObexTransport mTransport; - @VisibleForTesting - public Context mContext; + @VisibleForTesting public Context mContext; - @VisibleForTesting - public Handler mCallback = null; + @VisibleForTesting public Handler mCallback = null; /* status when server is blocking for user/auto confirmation */ - @VisibleForTesting - public boolean mServerBlocking = true; + @VisibleForTesting public boolean mServerBlocking = true; /* the current transfer info */ - @VisibleForTesting - public BluetoothOppShareInfo mInfo; + @VisibleForTesting public BluetoothOppShareInfo mInfo; /* info id when we insert the record */ private int mLocalShareInfoId; - @VisibleForTesting - public int mAccepted = BluetoothShare.USER_CONFIRMATION_PENDING; + @VisibleForTesting public int mAccepted = BluetoothShare.USER_CONFIRMATION_PENDING; private boolean mInterrupted = false; - @VisibleForTesting - public ServerSession mSession; + @VisibleForTesting public ServerSession mSession; private long mTimestamp; - @VisibleForTesting - BluetoothOppReceiveFileInfo mFileInfo; + @VisibleForTesting BluetoothOppReceiveFileInfo mFileInfo; private WakeLock mPartialWakeLock; - @VisibleForTesting - boolean mTimeoutMsgSent = false; + @VisibleForTesting boolean mTimeoutMsgSent = false; - @VisibleForTesting - public BluetoothOppService mBluetoothOppService; + @VisibleForTesting public BluetoothOppService mBluetoothOppService; private int mNumFilesAttemptedToReceive; - public BluetoothOppObexServerSession(Context context, ObexTransport transport, - BluetoothOppService service) { + public BluetoothOppObexServerSession( + Context context, ObexTransport transport, BluetoothOppService service) { mContext = context; mTransport = transport; mBluetoothOppService = service; @@ -134,8 +124,8 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } /** - * Called when connection is accepted from remote, to retrieve the first - * Header then wait for user confirmation + * Called when connection is accepted from remote, to retrieve the first Header then wait for + * user confirmation */ public void preStart() { try { @@ -151,19 +141,16 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } } - /** - * Called from BluetoothOppTransfer to start the "Transfer" - */ + /** Called from BluetoothOppTransfer to start the "Transfer" */ @Override public void start(Handler handler, int numShares) { Log.d(TAG, "Start!"); mCallback = handler; - } /** - * Called from BluetoothOppTransfer to cancel the "Transfer" Otherwise, - * server should end by itself. + * Called from BluetoothOppTransfer to cancel the "Transfer" Otherwise, server should end by + * itself. */ @Override public void stop() { @@ -288,8 +275,10 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } // Reject anything outside the "acceptlist" plus unspecified MIME Types. - if (mimeType == null || (!isAcceptlisted && !Constants.mimeTypeMatches(mimeType, - Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))) { + if (mimeType == null + || (!isAcceptlisted + && !Constants.mimeTypeMatches( + mimeType, Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))) { Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer"); ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, @@ -308,19 +297,24 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler values.put(BluetoothShare.TIMESTAMP, mTimestamp); // It's not first put if !serverBlocking, so we auto accept it - if (!mServerBlocking && (mAccepted == BluetoothShare.USER_CONFIRMATION_CONFIRMED - || mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED)) { - values.put(BluetoothShare.USER_CONFIRMATION, + if (!mServerBlocking + && (mAccepted == BluetoothShare.USER_CONFIRMATION_CONFIRMED + || mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED)) { + values.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED); } if (isAcceptlisted) { - values.put(BluetoothShare.USER_CONFIRMATION, + values.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } - Uri contentUri = BluetoothMethodProxy.getInstance().contentResolverInsert( - mContext.getContentResolver(), BluetoothShare.CONTENT_URI, values); + Uri contentUri = + BluetoothMethodProxy.getInstance() + .contentResolverInsert( + mContext.getContentResolver(), BluetoothShare.CONTENT_URI, values); mLocalShareInfoId = Integer.parseInt(contentUri.getPathSegments().get(1)); Log.v(TAG, "insert contentUri: " + contentUri); @@ -335,7 +329,8 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler wait(1000); if (mCallback != null && !mTimeoutMsgSent) { mTimeoutMsgSent = true; - mCallback.sendMessageDelayed(mCallback.obtainMessage( + mCallback.sendMessageDelayed( + mCallback.obtainMessage( BluetoothOppObexSession.MSG_CONNECT_TIMEOUT), BluetoothOppObexSession.SESSION_TIMEOUT); Log.v(TAG, "MSG_CONNECT_TIMEOUT sent"); @@ -390,7 +385,6 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler mInfo.mStatus = mFileInfo.mStatus; Constants.updateShareStatus(mContext, mInfo.mId, status); obexResponse = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; - } if (mFileInfo.mFileName != null && mFileInfo.mInsertUri != null) { @@ -400,8 +394,13 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler updateValues.put(BluetoothShare._DATA, mFileInfo.mFileName); updateValues.put(BluetoothShare.STATUS, BluetoothShare.STATUS_RUNNING); updateValues.put(BluetoothShare.URI, mFileInfo.mInsertUri.toString()); - BluetoothMethodProxy.getInstance().contentResolverUpdate( - mContext.getContentResolver(), contentUri, updateValues, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext.getContentResolver(), + contentUri, + updateValues, + null, + null); mInfo.mUri = mFileInfo.mInsertUri; status = receiveFile(mFileInfo, op); @@ -428,9 +427,7 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } if (mFileInfo.mInsertUri != null) { - Log.d( - TAG, - "Download failed. Removing the file. Uri=" + mFileInfo.mInsertUri); + Log.d(TAG, "Download failed. Removing the file. Uri=" + mFileInfo.mInsertUri); BluetoothMethodProxy.getInstance() .contentResolverDelete( mContext.getContentResolver(), @@ -451,9 +448,9 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler Log.i(TAG, "Rejected incoming request"); if (mFileInfo.mInsertUri != null) { - BluetoothMethodProxy.getInstance().contentResolverDelete( - mContext.getContentResolver(), mFileInfo.mInsertUri, null, - null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + mContext.getContentResolver(), mFileInfo.mInsertUri, null, null); } // set status as local cancel status = BluetoothShare.STATUS_CANCELED; @@ -495,8 +492,9 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (!error) { ContentValues updateValues = new ContentValues(); updateValues.put(BluetoothShare._DATA, fileInfo.mFileName); - BluetoothMethodProxy.getInstance().contentResolverUpdate(mContext.getContentResolver(), - contentUri, updateValues, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext.getContentResolver(), contentUri, updateValues, null, null); } long position = 0; @@ -505,8 +503,10 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (!error) { try { - os = BluetoothMethodProxy.getInstance().contentResolverOpenOutputStream( - mContext.getContentResolver(), fileInfo.mInsertUri); + os = + BluetoothMethodProxy.getInstance() + .contentResolverOpenOutputStream( + mContext.getContentResolver(), fileInfo.mInsertUri); } catch (FileNotFoundException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, @@ -542,9 +542,15 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler percent = position * 100 / fileInfo.mLength; currentTime = SystemClock.elapsedRealtime(); - Log.v(TAG, - "Receive file position = " + position + " readLength " + readLength - + " bytes took " + (currentTime - timestamp) + " ms"); + Log.v( + TAG, + "Receive file position = " + + position + + " readLength " + + readLength + + " bytes took " + + (currentTime - timestamp) + + " ms"); // Update the Progress Bar only if there is change in percentage // or once per a period to notify NFC of this transfer is still alive @@ -552,9 +558,13 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler || currentTime - prevTimestamp > Constants.NFC_ALIVE_CHECK_MS) { ContentValues updateValues = new ContentValues(); updateValues.put(BluetoothShare.CURRENT_BYTES, position); - BluetoothMethodProxy.getInstance().contentResolverUpdate( - mContext.getContentResolver(), contentUri, updateValues, null, - null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext.getContentResolver(), + contentUri, + updateValues, + null, + null); prevPercent = percent; prevTimestamp = currentTime; } @@ -655,8 +665,8 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (objectCount != null) { intent.putExtra(Constants.EXTRA_BT_OPP_OBJECT_COUNT, objectCount.intValue()); } else { - intent.putExtra(Constants.EXTRA_BT_OPP_OBJECT_COUNT, - Constants.COUNT_HEADER_UNAVAILABLE); + intent.putExtra( + Constants.EXTRA_BT_OPP_OBJECT_COUNT, Constants.COUNT_HEADER_UNAVAILABLE); } intent.putExtra(Constants.EXTRA_BT_OPP_ADDRESS, destination); mContext.sendBroadcast( diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexSession.java index 19c98d2c278..1a52b06dd29 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexSession.java @@ -34,32 +34,25 @@ package com.android.bluetooth.opp; import android.os.Handler; -/** - * Interface for control the state of an OBEX Session. - */ +/** Interface for control the state of an OBEX Session. */ public interface BluetoothOppObexSession { /** - * Message to notify when a transfer is completed For outbound share, it - * means one file has been sent. For inbounds share, it means one file has - * been received. + * Message to notify when a transfer is completed For outbound share, it means one file has been + * sent. For inbounds share, it means one file has been received. */ int MSG_SHARE_COMPLETE = 0; /** - * Message to notify when a session is completed For outbound share, it - * should be a consequence of session.stop() For inbounds share, it should - * be a consequence of remote disconnect + * Message to notify when a session is completed For outbound share, it should be a consequence + * of session.stop() For inbounds share, it should be a consequence of remote disconnect */ int MSG_SESSION_COMPLETE = 1; /** Message to notify when a BluetoothOppObexSession get any error condition */ int MSG_SESSION_ERROR = 2; - /** - * Message to notify when a BluetoothOppObexSession is interrupted when - * waiting for remote - */ + /** Message to notify when a BluetoothOppObexSession is interrupted when waiting for remote */ int MSG_SHARE_INTERRUPTED = 3; int MSG_CONNECT_TIMEOUT = 4; @@ -73,5 +66,4 @@ public interface BluetoothOppObexSession { void addShare(BluetoothOppShareInfo share); void unblock(); - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java index 7171b1c0359..e21d1f95e86 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java @@ -45,8 +45,8 @@ import com.android.bluetooth.flags.Flags; import java.util.HashMap; /** - * This class cache Bluetooth device name and channel locally. Its a temp - * solution which should be replaced by bluetooth_devices in SettingsProvider + * This class cache Bluetooth device name and channel locally. Its a temp solution which should be + * replaced by bluetooth_devices in SettingsProvider */ public class BluetoothOppPreference { private static final String TAG = "BluetoothOppPreference"; @@ -88,11 +88,12 @@ public class BluetoothOppPreference { mContext = context; - mNamePreference = mContext.getSharedPreferences(Constants.BLUETOOTHOPP_NAME_PREFERENCE, - Context.MODE_PRIVATE); + mNamePreference = + mContext.getSharedPreferences( + Constants.BLUETOOTHOPP_NAME_PREFERENCE, Context.MODE_PRIVATE); mChannelPreference = - mContext.getSharedPreferences(Constants.BLUETOOTHOPP_CHANNEL_PREFERENCE, - Context.MODE_PRIVATE); + mContext.getSharedPreferences( + Constants.BLUETOOTHOPP_CHANNEL_PREFERENCE, Context.MODE_PRIVATE); mNames = (HashMap) mNamePreference.getAll(); mChannels = (HashMap) mChannelPreference.getAll(); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java index 19bfaad1e39..26f13a81b48 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java @@ -97,10 +97,9 @@ public final class BluetoothOppProvider extends ContentProvider { private SQLiteOpenHelper mOpenHelper = null; /** - * Creates and updated database on demand when opening it. Helper class to - * create database the first time the provider is initialized and upgrade it - * when a new version of the provider needs an updated version of the - * database. + * Creates and updated database on demand when opening it. Helper class to create database the + * first time the provider is initialized and upgrade it when a new version of the provider + * needs an updated version of the database. */ private static final class DatabaseHelper extends SQLiteOpenHelper { @@ -108,9 +107,7 @@ public final class BluetoothOppProvider extends ContentProvider { super(context, DB_NAME, null, DB_VERSION); } - /** - * Creates database the first time we try to open it. - */ + /** Creates database the first time we try to open it. */ @Override public void onCreate(final SQLiteDatabase db) { Log.v(TAG, "populating new database"); @@ -118,8 +115,8 @@ public final class BluetoothOppProvider extends ContentProvider { } /** - * Updates the database format when a content provider is used with a - * database that was created with a different format. + * Updates the database format when a content provider is used with a database that was + * created with a different format. */ @Override public void onUpgrade(final SQLiteDatabase db, int oldV, final int newV) { @@ -131,26 +128,52 @@ public final class BluetoothOppProvider extends ContentProvider { // Upgrading from NOP_FROM is the same as upgrading from NOP_TO. oldV = DB_VERSION_NOP_UPGRADE_TO; } - Log.i(TAG, "Upgrading downloads database from version " + oldV + " to " + newV - + ", which will destroy all old data"); + Log.i( + TAG, + "Upgrading downloads database from version " + + oldV + + " to " + + newV + + ", which will destroy all old data"); dropTable(db); createTable(db); } - } private static void createTable(SQLiteDatabase db) { try { - db.execSQL("CREATE TABLE " + DB_TABLE + "(" + BluetoothShare._ID - + " INTEGER PRIMARY KEY AUTOINCREMENT," + BluetoothShare.URI + " TEXT, " - + BluetoothShare.FILENAME_HINT + " TEXT, " + BluetoothShare._DATA + " TEXT, " - + BluetoothShare.MIMETYPE + " TEXT, " + BluetoothShare.DIRECTION + " INTEGER, " - + BluetoothShare.DESTINATION + " TEXT, " + BluetoothShare.VISIBILITY - + " INTEGER, " + BluetoothShare.USER_CONFIRMATION + " INTEGER, " - + BluetoothShare.STATUS + " INTEGER, " + BluetoothShare.TOTAL_BYTES - + " INTEGER, " + BluetoothShare.CURRENT_BYTES + " INTEGER, " - + BluetoothShare.TIMESTAMP + " INTEGER," + Constants.MEDIA_SCANNED - + " INTEGER); "); + db.execSQL( + "CREATE TABLE " + + DB_TABLE + + "(" + + BluetoothShare._ID + + " INTEGER PRIMARY KEY AUTOINCREMENT," + + BluetoothShare.URI + + " TEXT, " + + BluetoothShare.FILENAME_HINT + + " TEXT, " + + BluetoothShare._DATA + + " TEXT, " + + BluetoothShare.MIMETYPE + + " TEXT, " + + BluetoothShare.DIRECTION + + " INTEGER, " + + BluetoothShare.DESTINATION + + " TEXT, " + + BluetoothShare.VISIBILITY + + " INTEGER, " + + BluetoothShare.USER_CONFIRMATION + + " INTEGER, " + + BluetoothShare.STATUS + + " INTEGER, " + + BluetoothShare.TOTAL_BYTES + + " INTEGER, " + + BluetoothShare.CURRENT_BYTES + + " INTEGER, " + + BluetoothShare.TIMESTAMP + + " INTEGER," + + Constants.MEDIA_SCANNED + + " INTEGER); "); } catch (SQLException ex) { ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, @@ -213,9 +236,11 @@ public final class BluetoothOppProvider extends ContentProvider { private static void putString(String key, Cursor from, ContentValues to) { to.put(key, from.getString(from.getColumnIndexOrThrow(key))); } + private static void putInteger(String key, Cursor from, ContentValues to) { to.put(key, from.getInt(from.getColumnIndexOrThrow(key))); } + private static void putLong(String key, Cursor from, ContentValues to) { to.put(key, from.getLong(from.getColumnIndexOrThrow(key))); } @@ -227,28 +252,33 @@ public final class BluetoothOppProvider extends ContentProvider { try { ContentValues values = new ContentValues(); - final List stringKeys = new ArrayList<>(Arrays.asList( - BluetoothShare.URI, - BluetoothShare.FILENAME_HINT, - BluetoothShare.MIMETYPE, - BluetoothShare.DESTINATION)); + final List stringKeys = + new ArrayList<>( + Arrays.asList( + BluetoothShare.URI, + BluetoothShare.FILENAME_HINT, + BluetoothShare.MIMETYPE, + BluetoothShare.DESTINATION)); for (String k : stringKeys) { putString(k, cursor, values); } - final List integerKeys = new ArrayList<>(Arrays.asList( - BluetoothShare.VISIBILITY, - BluetoothShare.USER_CONFIRMATION, - BluetoothShare.DIRECTION, - BluetoothShare.STATUS, - Constants.MEDIA_SCANNED)); + final List integerKeys = + new ArrayList<>( + Arrays.asList( + BluetoothShare.VISIBILITY, + BluetoothShare.USER_CONFIRMATION, + BluetoothShare.DIRECTION, + BluetoothShare.STATUS, + Constants.MEDIA_SCANNED)); for (String k : integerKeys) { putInteger(k, cursor, values); } - final List longKeys = new ArrayList<>(Arrays.asList( - BluetoothShare.TOTAL_BYTES, - BluetoothShare.TIMESTAMP)); + final List longKeys = + new ArrayList<>( + Arrays.asList( + BluetoothShare.TOTAL_BYTES, BluetoothShare.TIMESTAMP)); for (String k : longKeys) { putLong(k, cursor, values); } @@ -338,7 +368,11 @@ public final class BluetoothOppProvider extends ContentProvider { } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); @@ -429,28 +463,29 @@ public final class BluetoothOppProvider extends ContentProvider { int match = sURIMatcher.match(uri); switch (match) { case SHARES: - case SHARES_ID: { - String myWhere; - if (selection != null) { - if (match == SHARES) { - myWhere = "( " + selection + " )"; + case SHARES_ID: + { + String myWhere; + if (selection != null) { + if (match == SHARES) { + myWhere = "( " + selection + " )"; + } else { + myWhere = "( " + selection + " ) AND "; + } } else { - myWhere = "( " + selection + " ) AND "; + myWhere = ""; + } + if (match == SHARES_ID) { + String segment = uri.getPathSegments().get(1); + rowId = Long.parseLong(segment); + myWhere += " ( " + BluetoothShare._ID + " = " + rowId + " ) "; } - } else { - myWhere = ""; - } - if (match == SHARES_ID) { - String segment = uri.getPathSegments().get(1); - rowId = Long.parseLong(segment); - myWhere += " ( " + BluetoothShare._ID + " = " + rowId + " ) "; - } - if (values.size() > 0) { - count = db.update(DB_TABLE, values, myWhere, selectionArgs); + if (values.size() > 0) { + count = db.update(DB_TABLE, values, myWhere, selectionArgs); + } + break; } - break; - } default: throw new UnsupportedOperationException("Cannot update unknown URI: " + uri); } @@ -466,26 +501,27 @@ public final class BluetoothOppProvider extends ContentProvider { int match = sURIMatcher.match(uri); switch (match) { case SHARES: - case SHARES_ID: { - String myWhere; - if (selection != null) { - if (match == SHARES) { - myWhere = "( " + selection + " )"; + case SHARES_ID: + { + String myWhere; + if (selection != null) { + if (match == SHARES) { + myWhere = "( " + selection + " )"; + } else { + myWhere = "( " + selection + " ) AND "; + } } else { - myWhere = "( " + selection + " ) AND "; + myWhere = ""; + } + if (match == SHARES_ID) { + String segment = uri.getPathSegments().get(1); + long rowId = Long.parseLong(segment); + myWhere += " ( " + BluetoothShare._ID + " = " + rowId + " ) "; } - } else { - myWhere = ""; - } - if (match == SHARES_ID) { - String segment = uri.getPathSegments().get(1); - long rowId = Long.parseLong(segment); - myWhere += " ( " + BluetoothShare._ID + " = " + rowId + " ) "; - } - count = db.delete(DB_TABLE, myWhere, selectionArgs); - break; - } + count = db.delete(DB_TABLE, myWhere, selectionArgs); + break; + } default: throw new UnsupportedOperationException("Cannot delete unknown URI: " + uri); } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java index 794868db46b..ea61bee0795 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java @@ -61,7 +61,6 @@ public class BluetoothOppReceiveFileInfo { /* To truncate the name of the received file if the length exceeds 237 */ private static final int OPP_LENGTH_OF_FILE_NAME = 237; - /** absolute store file name */ public String mFileName; @@ -97,11 +96,19 @@ public class BluetoothOppReceiveFileInfo { Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id); String hint = null, mimeType = null; long length = 0; - Cursor metadataCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - contentResolver, contentUri, new String[]{ - BluetoothShare.FILENAME_HINT, BluetoothShare.TOTAL_BYTES, - BluetoothShare.MIMETYPE - }, null, null, null); + Cursor metadataCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + contentResolver, + contentUri, + new String[] { + BluetoothShare.FILENAME_HINT, + BluetoothShare.TOTAL_BYTES, + BluetoothShare.MIMETYPE + }, + null, + null, + null); if (metadataCursor != null) { try { if (metadataCursor.moveToFirst()) { @@ -140,13 +147,13 @@ public class BluetoothOppReceiveFileInfo { Log.d(Constants.TAG, " File Name " + filename); if (filename.getBytes().length > OPP_LENGTH_OF_FILE_NAME) { - /* Including extn of the file, Linux supports 255 character as a maximum length of the - * file name to be created. Hence, Instead of sending OBEX_HTTP_INTERNAL_ERROR, - * as a response, truncate the length of the file name and save it. This check majorly - * helps in the case of vcard, where Phone book app supports contact name to be saved - * more than 255 characters, But the server rejects the card just because the length of - * vcf file name received exceeds 255 Characters. - */ + /* Including extn of the file, Linux supports 255 character as a maximum length of the + * file name to be created. Hence, Instead of sending OBEX_HTTP_INTERNAL_ERROR, + * as a response, truncate the length of the file name and save it. This check majorly + * helps in the case of vcard, where Phone book app supports contact name to be saved + * more than 255 characters, But the server rejects the card just because the length of + * vcf file name received exceeds 255 Characters. + */ Log.i(Constants.TAG, " File Name Length :" + filename.length()); Log.i(Constants.TAG, " File Name Length in Bytes:" + filename.getBytes().length); @@ -175,8 +182,8 @@ public class BluetoothOppReceiveFileInfo { ContentValues mediaContentValues = new ContentValues(); mediaContentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fullfilename); mediaContentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType); - mediaContentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, - Environment.DIRECTORY_DOWNLOADS); + mediaContentValues.put( + MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS); Uri insertUri = BluetoothMethodProxy.getInstance() .contentResolverInsert( diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java index 4910cf0a6f1..5a1e7bdcc8a 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java @@ -93,8 +93,9 @@ public class BluetoothOppReceiver extends BroadcastReceiver { String toastMsg; int batchSize = mOppManager.getBatchSize(); if (mOppManager.mMultipleFlag) { - toastMsg = context.getString(R.string.bt_toast_5, Integer.toString(batchSize), - deviceName); + toastMsg = + context.getString( + R.string.bt_toast_5, Integer.toString(batchSize), deviceName); } else { toastMsg = context.getString(R.string.bt_toast_4, deviceName); } @@ -114,8 +115,8 @@ public class BluetoothOppReceiver extends BroadcastReceiver { Uri uri = intent.getData(); ContentValues values = new ContentValues(); values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_DENIED); - BluetoothMethodProxy.getInstance().contentResolverUpdate(context.getContentResolver(), - uri, values, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(context.getContentResolver(), uri, values, null, null); cancelNotification(context, BluetoothOppNotification.NOTIFICATION_ID_PROGRESS); } else if (action.equals(Constants.ACTION_ACCEPT)) { @@ -123,10 +124,10 @@ public class BluetoothOppReceiver extends BroadcastReceiver { Uri uri = intent.getData(); ContentValues values = new ContentValues(); - values.put(BluetoothShare.USER_CONFIRMATION, - BluetoothShare.USER_CONFIRMATION_CONFIRMED); - BluetoothMethodProxy.getInstance().contentResolverUpdate(context.getContentResolver(), - uri, values, null, null); + values.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_CONFIRMED); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(context.getContentResolver(), uri, values, null, null); } else if (action.equals(Constants.ACTION_OPEN) || action.equals(Constants.ACTION_LIST)) { if (action.equals(Constants.ACTION_OPEN)) { Log.v(TAG, "Receiver open for " + intent.getData()); @@ -149,8 +150,12 @@ public class BluetoothOppReceiver extends BroadcastReceiver { if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND && BluetoothShare.isStatusSuccess(transInfo.mStatus)) { // if received file successfully, open this file - BluetoothOppUtility.openReceivedFile(context, transInfo.mFileName, - transInfo.mFileType, transInfo.mTimeStamp, uri); + BluetoothOppUtility.openReceivedFile( + context, + transInfo.mFileName, + transInfo.mFileType, + transInfo.mTimeStamp, + uri); BluetoothOppUtility.updateVisibilityToHidden(context, uri); } else { Intent in = new Intent(context, BluetoothOppTransferActivity.class); @@ -177,8 +182,15 @@ public class BluetoothOppReceiver extends BroadcastReceiver { context.startActivity(in); } else if (action.equals(Constants.ACTION_HIDE)) { Log.v(TAG, "Receiver hide for " + intent.getData()); - Cursor cursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - context.getContentResolver(), intent.getData(), null, null, null, null); + Cursor cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + context.getContentResolver(), + intent.getData(), + null, + null, + null, + null); if (cursor != null) { if (cursor.moveToFirst()) { int visibilityColumn = cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY); @@ -190,9 +202,13 @@ public class BluetoothOppReceiver extends BroadcastReceiver { && visibility == BluetoothShare.VISIBILITY_VISIBLE) { ContentValues values = new ContentValues(); values.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); - BluetoothMethodProxy.getInstance().contentResolverUpdate( - context.getContentResolver(), intent.getData(), values, null, - null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + context.getContentResolver(), + intent.getData(), + values, + null, + null); Log.v(TAG, "Action_hide received and db updated"); } } @@ -203,9 +219,13 @@ public class BluetoothOppReceiver extends BroadcastReceiver { Log.v(TAG, "Receiver ACTION_COMPLETE_HIDE"); ContentValues updateValues = new ContentValues(); updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); - BluetoothMethodProxy.getInstance().contentResolverUpdate( - context.getContentResolver(), BluetoothShare.CONTENT_URI, updateValues, - BluetoothOppNotification.WHERE_COMPLETED, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + context.getContentResolver(), + BluetoothShare.CONTENT_URI, + updateValues, + BluetoothOppNotification.WHERE_COMPLETED, + null); } else if (action.equals(Constants.ACTION_HIDE_COMPLETED_INBOUND_TRANSFER) && Flags.oppFixMultipleNotificationsIssues()) { Log.v(TAG, "Received ACTION_HIDE_COMPLETED_INBOUND_TRANSFER"); @@ -250,24 +270,28 @@ public class BluetoothOppReceiver extends BroadcastReceiver { // Deal with handover-initiated transfers separately Intent handoverIntent = new Intent(Constants.ACTION_BT_OPP_TRANSFER_DONE); if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { - handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, + handoverIntent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, Constants.DIRECTION_BLUETOOTH_INCOMING); } else { - handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, + handoverIntent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, Constants.DIRECTION_BLUETOOTH_OUTGOING); } handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_ID, transInfo.mID); handoverIntent.putExtra(Constants.EXTRA_BT_OPP_ADDRESS, transInfo.mDestAddr); if (BluetoothShare.isStatusSuccess(transInfo.mStatus)) { - handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_STATUS, + handoverIntent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_STATUS, Constants.HANDOVER_TRANSFER_STATUS_SUCCESS); - handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_URI, - transInfo.mFileName); - handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_MIMETYPE, - transInfo.mFileType); + handoverIntent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_URI, transInfo.mFileName); + handoverIntent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_MIMETYPE, transInfo.mFileType); } else { - handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_STATUS, + handoverIntent.putExtra( + Constants.EXTRA_BT_OPP_TRANSFER_STATUS, Constants.HANDOVER_TRANSFER_STATUS_FAILURE); } context.sendBroadcast( diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java index b6af5b35ca0..16056cde792 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java @@ -62,8 +62,6 @@ import java.io.IOException; public class BluetoothOppSendFileInfo { private static final String TAG = "BluetoothOppSendFileInfo"; - - /** Reusable SendFileInfo for error status. */ static final BluetoothOppSendFileInfo SEND_FILE_INFO_ERROR = new BluetoothOppSendFileInfo(null, null, 0, null, BluetoothShare.STATUS_FILE_ERROR); @@ -84,8 +82,8 @@ public class BluetoothOppSendFileInfo { public final long mLength; /** for media file */ - public BluetoothOppSendFileInfo(String fileName, String type, long length, - FileInputStream inputStream, int status) { + public BluetoothOppSendFileInfo( + String fileName, String type, long length, FileInputStream inputStream, int status) { mFileName = fileName; mMimetype = type; mLength = length; @@ -104,8 +102,8 @@ public class BluetoothOppSendFileInfo { mStatus = status; } - public static BluetoothOppSendFileInfo generateFileInfo(Context context, Uri uri, String type, - boolean fromExternal) { + public static BluetoothOppSendFileInfo generateFileInfo( + Context context, Uri uri, String type, boolean fromExternal) { ContentResolver contentResolver = context.getContentResolver(); String scheme = uri.getScheme(); String fileName = null; @@ -129,10 +127,17 @@ public class BluetoothOppSendFileInfo { contentType = contentResolver.getType(uri); Cursor metadataCursor; try { - metadataCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - contentResolver, uri, new String[]{ - OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE - }, null, null, null); + metadataCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + contentResolver, + uri, + new String[] { + OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE + }, + null, + null, + null); } catch (SQLiteException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, @@ -185,8 +190,10 @@ public class BluetoothOppSendFileInfo { } if (fromExternal && !BluetoothOppUtility.isInExternalStorageDir(uri)) { EventLog.writeEvent(0x534e4554, "35310991", -1, uri.getPath()); - Log.e(TAG, "File based URI not in Environment.getExternalStorageDirectory() is not " - + "allowed."); + Log.e( + TAG, + "File based URI not in Environment.getExternalStorageDirectory() is not " + + "allowed."); ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, @@ -209,12 +216,18 @@ public class BluetoothOppSendFileInfo { // right size in _OpenableColumns.SIZE // As a second source of getting the correct file length, // get a file descriptor and get the stat length - AssetFileDescriptor fd = BluetoothMethodProxy.getInstance() - .contentResolverOpenAssetFileDescriptor(contentResolver, uri, "r"); + AssetFileDescriptor fd = + BluetoothMethodProxy.getInstance() + .contentResolverOpenAssetFileDescriptor(contentResolver, uri, "r"); long statLength = fd.getLength(); if (length != statLength && statLength > 0) { - Log.e(TAG, "Content provider length is wrong (" + Long.toString(length) - + "), using stat length (" + Long.toString(statLength) + ")"); + Log.e( + TAG, + "Content provider length is wrong (" + + Long.toString(length) + + "), using stat length (" + + Long.toString(statLength) + + ")"); ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, @@ -242,8 +255,10 @@ public class BluetoothOppSendFileInfo { .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 6); // Reset the stream - fd = BluetoothMethodProxy.getInstance() - .contentResolverOpenAssetFileDescriptor(contentResolver, uri, "r"); + fd = + BluetoothMethodProxy.getInstance() + .contentResolverOpenAssetFileDescriptor( + contentResolver, uri, "r"); is = fd.createInputStream(); } } catch (IOException e) { @@ -284,16 +299,20 @@ public class BluetoothOppSendFileInfo { if (is == null) { try { - is = (FileInputStream) BluetoothMethodProxy.getInstance() - .contentResolverOpenInputStream(contentResolver, uri); + is = + (FileInputStream) + BluetoothMethodProxy.getInstance() + .contentResolverOpenInputStream(contentResolver, uri); // If the database doesn't contain the file size, get the size // by reading through the entire stream if (length == 0) { length = getStreamSize(is); // Reset the stream - is = (FileInputStream) BluetoothMethodProxy.getInstance() - .contentResolverOpenInputStream(contentResolver, uri); + is = + (FileInputStream) + BluetoothMethodProxy.getInstance() + .contentResolverOpenInputStream(contentResolver, uri); } } catch (FileNotFoundException e) { ContentProfileErrorReportUtils.report( @@ -327,8 +346,8 @@ public class BluetoothOppSendFileInfo { BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, 14); - throw new IllegalArgumentException(context - .getString(R.string.bluetooth_opp_file_limit_exceeded)); + throw new IllegalArgumentException( + context.getString(R.string.bluetooth_opp_file_limit_exceeded)); } return new BluetoothOppSendFileInfo(fileName, contentType, length, is, 0); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java index 41d875ef56d..306faf6182d 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java @@ -86,11 +86,9 @@ import java.util.Locale; // Next tag value for ContentProfileErrorReportUtils.report(): 22 public class BluetoothOppService extends ProfileService implements IObexConnectionHandler { - /** - * Owned providers and activities - */ - private static final String OPP_PROVIDER = - BluetoothOppProvider.class.getCanonicalName(); + /** Owned providers and activities */ + private static final String OPP_PROVIDER = BluetoothOppProvider.class.getCanonicalName(); + private static final String INCOMING_FILE_CONFIRM_ACTIVITY = BluetoothOppIncomingFileConfirmActivity.class.getCanonicalName(); private static final String TRANSFER_ACTIVITY = @@ -99,17 +97,16 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti BluetoothOppTransferHistory.class.getCanonicalName(); // Normally we would dynamically define and create these but they need to be manifest receivers // because they rely on explicit intents. Explicit intents don't work with dynamic receivers. - private static final String OPP_RECEIVER = - BluetoothOppReceiver.class.getCanonicalName(); + private static final String OPP_RECEIVER = BluetoothOppReceiver.class.getCanonicalName(); private static final String OPP_HANDOFF_RECEIVER = BluetoothOppHandoverReceiver.class.getCanonicalName(); private static final byte[] SUPPORTED_OPP_FORMAT = { - 0x01 /* vCard 2.1 */, - 0x02 /* vCard 3.0 */, - 0x03 /* vCal 1.0 */, - 0x04 /* iCal 2.0 */, - (byte) 0xFF /* Any type of object */ + 0x01 /* vCard 2.1 */, + 0x02 /* vCard 3.0 */, + 0x03 /* vCal 1.0 */, + 0x04 /* iCal 2.0 */, + (byte) 0xFF /* Any type of object */ }; private class BluetoothShareContentObserver extends ContentObserver { @@ -148,13 +145,10 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti private int mBatchId = 1; - /** - * Array used when extracting strings from content provider - */ + /** Array used when extracting strings from content provider */ private CharArrayBuffer mOldChars; - /** - * Array used when extracting strings from content provider - */ + + /** Array used when extracting strings from content provider */ private CharArrayBuffer mNewChars; private boolean mListenStarted; @@ -175,13 +169,23 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti BluetoothShare.VISIBILITY + "=" + BluetoothShare.VISIBILITY_HIDDEN; private static final String WHERE_INBOUND_SUCCESS = - BluetoothShare.DIRECTION + "=" + BluetoothShare.DIRECTION_INBOUND + " AND " - + BluetoothShare.STATUS + "=" + BluetoothShare.STATUS_SUCCESS + " AND " + BluetoothShare.DIRECTION + + "=" + + BluetoothShare.DIRECTION_INBOUND + + " AND " + + BluetoothShare.STATUS + + "=" + + BluetoothShare.STATUS_SUCCESS + + " AND " + INVISIBLE; private static final String WHERE_CONFIRM_PENDING_INBOUND = - BluetoothShare.DIRECTION + "=" + BluetoothShare.DIRECTION_INBOUND + " AND " - + BluetoothShare.USER_CONFIRMATION + "=" + BluetoothShare.DIRECTION + + "=" + + BluetoothShare.DIRECTION_INBOUND + + " AND " + + BluetoothShare.USER_CONFIRMATION + + "=" + BluetoothShare.USER_CONFIRMATION_PENDING; @VisibleForTesting @@ -311,8 +315,14 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti String dir = info.mDirection == BluetoothShare.DIRECTION_OUTBOUND ? " -> " : " <- "; SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US); Date date = new Date(info.mTimestamp); - println(sb, " " + format.format(date) + dir + info.mCurrentBytes + "/" - + info.mTotalBytes); + println( + sb, + " " + + format.format(date) + + dir + + info.mCurrentBytes + + "/" + + info.mTotalBytes); } } } @@ -614,49 +624,60 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti private void createServerSession(ObexTransport transport) { mServerSession = new BluetoothOppObexServerSession(this, transport, this); mServerSession.preStart(); - Log.d(TAG, "Get ServerSession " + mServerSession.toString() + " for incoming connection" - + transport.toString()); + Log.d( + TAG, + "Get ServerSession " + + mServerSession.toString() + + " for incoming connection" + + transport.toString()); } - private final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - switch (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { - case BluetoothAdapter.STATE_ON: - Log.v(TAG, "Bluetooth state changed: STATE_ON"); - startListener(); - // If this is within a sending process, continue the handle - // logic to display device picker dialog. - synchronized (this) { - if (BluetoothOppManager.getInstance(context).mSendingFlag) { - // reset the flags - BluetoothOppManager.getInstance(context).mSendingFlag = false; - - Intent in1 = new Intent(BluetoothDevicePicker.ACTION_LAUNCH); - in1.putExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false); - in1.putExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE, - BluetoothDevicePicker.FILTER_TYPE_TRANSFER); - in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE, - getPackageName()); - in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS, - BluetoothOppReceiver.class.getName()); - - in1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(in1); - } - } + private final BroadcastReceiver mBluetoothReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + switch (intent.getIntExtra( + BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { + case BluetoothAdapter.STATE_ON: + Log.v(TAG, "Bluetooth state changed: STATE_ON"); + startListener(); + // If this is within a sending process, continue the handle + // logic to display device picker dialog. + synchronized (this) { + if (BluetoothOppManager.getInstance(context).mSendingFlag) { + // reset the flags + BluetoothOppManager.getInstance(context).mSendingFlag = + false; + + Intent in1 = + new Intent(BluetoothDevicePicker.ACTION_LAUNCH); + in1.putExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false); + in1.putExtra( + BluetoothDevicePicker.EXTRA_FILTER_TYPE, + BluetoothDevicePicker.FILTER_TYPE_TRANSFER); + in1.putExtra( + BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE, + getPackageName()); + in1.putExtra( + BluetoothDevicePicker.EXTRA_LAUNCH_CLASS, + BluetoothOppReceiver.class.getName()); + + in1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(in1); + } + } - break; - case BluetoothAdapter.STATE_TURNING_OFF: - Log.v(TAG, "Bluetooth state changed: STATE_TURNING_OFF"); - break; + break; + case BluetoothAdapter.STATE_TURNING_OFF: + Log.v(TAG, "Bluetooth state changed: STATE_TURNING_OFF"); + break; + } + } } - } - } - }; + }; private void updateFromProvider() { synchronized (BluetoothOppService.this) { @@ -684,7 +705,6 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti super.interrupt(); } - @Override public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); @@ -696,8 +716,14 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti throw new IllegalStateException( "multiple UpdateThreads in BluetoothOppService"); } - Log.v(TAG, "pendingUpdate is " + mPendingUpdate + " sListenStarted is " - + mListenStarted + " isInterrupted :" + mIsInterrupted); + Log.v( + TAG, + "pendingUpdate is " + + mPendingUpdate + + " sListenStarted is " + + mListenStarted + + " isInterrupted :" + + mIsInterrupted); if (!mPendingUpdate) { mUpdateThread = null; mUpdateThreadRunning = false; @@ -706,8 +732,13 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti mPendingUpdate = false; } Cursor cursor = - getContentResolver().query(BluetoothShare.CONTENT_URI, null, null, null, - BluetoothShare._ID); + getContentResolver() + .query( + BluetoothShare.CONTENT_URI, + null, + null, + null, + BluetoothShare._ID); if (cursor == null) { mUpdateThreadRunning = false; @@ -741,8 +772,12 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti // We're beyond the end of the cursor but there's still some // stuff in the local array, which can only be junk if (mShares.size() != 0) { - Log.v(TAG, "Array update: trimming " + mShares.get(arrayPos).mId - + " @ " + arrayPos); + Log.v( + TAG, + "Array update: trimming " + + mShares.get(arrayPos).mId + + " @ " + + arrayPos); } deleteShare(arrayPos); // this advances in the array @@ -762,8 +797,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } if (arrayId < id) { - Log.v(TAG, - "Array update: removing " + arrayId + " @ " + arrayPos); + Log.v(TAG, "Array update: removing " + arrayId + " @ " + arrayPos); deleteShare(arrayPos); } else if (arrayId == id) { // This cursor row already exists in the stored array. @@ -810,21 +844,25 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, 13); } - BluetoothOppShareInfo info = new BluetoothOppShareInfo( - cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)), uri, - cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)), - cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare._DATA)), - cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.MIMETYPE)), - cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION)), - cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.DESTINATION)), - cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY)), - cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION)), - cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.STATUS)), - cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES)), - cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES)), - cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP)), - cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) - != Constants.MEDIA_SCANNED_NOT_SCANNED); + BluetoothOppShareInfo info = + new BluetoothOppShareInfo( + cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)), + uri, + cursor.getString( + cursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)), + cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare._DATA)), + cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.MIMETYPE)), + cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION)), + cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.DESTINATION)), + cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY)), + cursor.getInt( + cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION)), + cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.STATUS)), + cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES)), + cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES)), + cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP)), + cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) + != Constants.MEDIA_SCANNED_NOT_SCANNED); Log.v(TAG, "Service adding new entry"); Log.v(TAG, "ID : " + info.mId); @@ -883,33 +921,52 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti mBatchId++; mBatches.add(newBatch); if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { - Log.v(TAG, - "Service create new Batch " + newBatch.mId + " for OUTBOUND info " + Log.v( + TAG, + "Service create new Batch " + + newBatch.mId + + " for OUTBOUND info " + info.mId); mTransfer = new BluetoothOppTransfer(mAdapterService, newBatch); } else if (info.mDirection == BluetoothShare.DIRECTION_INBOUND) { - Log.v(TAG, "Service create new Batch " + newBatch.mId + " for INBOUND info " - + info.mId); + Log.v( + TAG, + "Service create new Batch " + + newBatch.mId + + " for INBOUND info " + + info.mId); mServerTransfer = new BluetoothOppTransfer(mAdapterService, newBatch, mServerSession); } if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND && mTransfer != null) { - Log.v(TAG, "Service start transfer new Batch " + newBatch.mId + " for info " - + info.mId); + Log.v( + TAG, + "Service start transfer new Batch " + + newBatch.mId + + " for info " + + info.mId); mTransfer.start(); } else if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && mServerTransfer != null) { - Log.v(TAG, "Service start server transfer new Batch " + newBatch.mId - + " for info " + info.mId); + Log.v( + TAG, + "Service start server transfer new Batch " + + newBatch.mId + + " for info " + + info.mId); mServerTransfer.start(); } } else { int i = findBatchWithTimeStamp(info.mTimestamp); if (i != -1) { - Log.v(TAG, "Service add info " + info.mId + " to existing batch " + mBatches - .get(i).mId); + Log.v( + TAG, + "Service add info " + + info.mId + + " to existing batch " + + mBatches.get(i).mId); mBatches.get(i).addShare(info); } else { // There is ongoing batch @@ -917,8 +974,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti newBatch.mId = mBatchId; mBatchId++; mBatches.add(newBatch); - Log.v(TAG, - "Service add new Batch " + newBatch.mId + " for info " + info.mId); + Log.v(TAG, "Service add new Batch " + newBatch.mId + " for info " + info.mId); } } } @@ -954,8 +1010,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION)); if (info.mVisibility == BluetoothShare.VISIBILITY_VISIBLE - && newVisibility != BluetoothShare.VISIBILITY_VISIBLE && ( - BluetoothShare.isStatusCompleted(info.mStatus) + && newVisibility != BluetoothShare.VISIBILITY_VISIBLE + && (BluetoothShare.isStatusCompleted(info.mStatus) || newConfirm == BluetoothShare.USER_CONFIRMATION_PENDING)) { mNotifier.mNotificationMgr.cancel(info.mId); } @@ -979,8 +1035,9 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti info.mCurrentBytes = cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES)); info.mTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP)); - info.mMediaScanned = (cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) - != Constants.MEDIA_SCANNED_NOT_SCANNED); + info.mMediaScanned = + (cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) + != Constants.MEDIA_SCANNED_NOT_SCANNED); if (confirmUpdated) { Log.v(TAG, "Service handle info " + info.mId + " confirmation updated"); @@ -990,7 +1047,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti BluetoothOppBatch batch = mBatches.get(i); if (mServerTransfer != null && batch.mId == mServerTransfer.getBatchId()) { mServerTransfer.confirmStatusChanged(); - } //TODO need to think about else + } // TODO need to think about else } } int i = findBatchWithTimeStamp(info.mTimestamp); @@ -1011,8 +1068,12 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } else if (batch.mId == mTransfer.getBatchId()) { mTransfer.stop(); } else { - Log.e(TAG, "Unexpected error! batch id " + batch.mId - + " doesn't match mTransfer id " + mTransfer.getBatchId()); + Log.e( + TAG, + "Unexpected error! batch id " + + batch.mId + + " doesn't match mTransfer id " + + mTransfer.getBatchId()); ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, @@ -1033,9 +1094,12 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } else if (batch.mId == mServerTransfer.getBatchId()) { mServerTransfer.stop(); } else { - Log.e(TAG, "Unexpected error! batch id " + batch.mId - + " doesn't match mServerTransfer id " - + mServerTransfer.getBatchId()); + Log.e( + TAG, + "Unexpected error! batch id " + + batch.mId + + " doesn't match mServerTransfer id " + + mServerTransfer.getBatchId()); ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, @@ -1138,7 +1202,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti mServerTransfer.start(); if (nextBatch.getPendingShare() != null && nextBatch.getPendingShare().mConfirm - == BluetoothShare.USER_CONFIRMATION_CONFIRMED) { + == BluetoothShare.USER_CONFIRMATION_CONFIRMED) { mServerTransfer.confirmStatusChanged(); } return; @@ -1150,9 +1214,11 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti private void scanFileIfNeeded(int arrayPos) { BluetoothOppShareInfo info = mShares.get(arrayPos); - boolean isFileReceived = BluetoothShare.isStatusSuccess(info.mStatus) - && info.mDirection == BluetoothShare.DIRECTION_INBOUND && !info.mMediaScanned - && info.mConfirm != BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED; + boolean isFileReceived = + BluetoothShare.isStatusSuccess(info.mStatus) + && info.mDirection == BluetoothShare.DIRECTION_INBOUND + && !info.mMediaScanned + && info.mConfirm != BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED; if (!isFileReceived) { return; } @@ -1326,9 +1392,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti mHandler.sendMessage(mHandler.obtainMessage(START_LISTENER)); } - /** - * Set mAcceptNewConnections to true to allow new connections. - */ + /** Set mAcceptNewConnections to true to allow new connections. */ void acceptNewConnections() { mAcceptNewConnections = true; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppShareInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppShareInfo.java index 59632f6159f..99db01fbeb4 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppShareInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppShareInfo.java @@ -35,8 +35,8 @@ package com.android.bluetooth.opp; import android.net.Uri; /** - * This class stores information about a single OBEX share, e.g. one object - * send/receive to a destination address. + * This class stores information about a single OBEX share, e.g. one object send/receive to a + * destination address. */ public class BluetoothOppShareInfo { @@ -68,9 +68,21 @@ public class BluetoothOppShareInfo { public boolean mMediaScanned; - public BluetoothOppShareInfo(int id, Uri uri, String hint, String filename, String mimetype, - int direction, String destination, int visibility, int confirm, int status, - long totalBytes, long currentBytes, long timestamp, boolean mediaScanned) { + public BluetoothOppShareInfo( + int id, + Uri uri, + String hint, + String filename, + String mimetype, + int direction, + String destination, + int visibility, + int confirm, + int status, + long totalBytes, + long currentBytes, + long timestamp, + boolean mediaScanned) { mId = id; mUri = uri; mHint = hint; @@ -98,7 +110,7 @@ public class BluetoothOppShareInfo { } } else if (mDirection == BluetoothShare.DIRECTION_INBOUND) { if (mStatus == BluetoothShare.STATUS_PENDING) { - //&& mConfirm != BluetoothShare.USER_CONFIRMATION_PENDING) { + // && mConfirm != BluetoothShare.USER_CONFIRMATION_PENDING) { return true; } } @@ -115,9 +127,7 @@ public class BluetoothOppShareInfo { return false; } - /** - * Check if a ShareInfo is invalid because of previous error - */ + /** Check if a ShareInfo is invalid because of previous error */ public boolean isObsolete() { if (BluetoothShare.STATUS_RUNNING == mStatus) { return true; @@ -129,5 +139,4 @@ public class BluetoothOppShareInfo { public String toString() { return "BluetoothOppShareInfo"; } - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java index ebecc663b8f..1c8f09f6677 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java @@ -73,16 +73,11 @@ import java.io.IOException; public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatchListener { private static final String TAG = "BtOppTransfer"; + @VisibleForTesting static final int TRANSPORT_ERROR = 10; + @VisibleForTesting static final int TRANSPORT_CONNECTED = 11; - @VisibleForTesting - static final int TRANSPORT_ERROR = 10; - - @VisibleForTesting - static final int TRANSPORT_CONNECTED = 11; - - @VisibleForTesting - static final int SOCKET_ERROR_RETRY = 13; + @VisibleForTesting static final int SOCKET_ERROR_RETRY = 13; private static final String SOCKET_LINK_KEY_ERROR = "Invalid exchange"; @@ -92,22 +87,19 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch private BluetoothAdapter mAdapter; - @VisibleForTesting - BluetoothDevice mDevice; + @VisibleForTesting BluetoothDevice mDevice; private final BluetoothOppBatch mBatch; private BluetoothOppObexSession mSession; - @VisibleForTesting - BluetoothOppShareInfo mCurrentShare; + @VisibleForTesting BluetoothOppShareInfo mCurrentShare; private ObexTransport mTransport; private HandlerThread mHandlerThread; - @VisibleForTesting - EventHandler mSessionHandler; + @VisibleForTesting EventHandler mSessionHandler; private long mTimestamp; @@ -154,15 +146,19 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch + mBatch.mDestination + " \n mCurrentShare.mConfirm == " + mCurrentShare.mConfirm); - if ((device.equals(mBatch.mDestination)) && (mCurrentShare.mConfirm - == BluetoothShare.USER_CONFIRMATION_PENDING)) { - Log.v(TAG, "ACTION_ACL_DISCONNECTED to be processed for batch: " - + mBatch.mId); + if ((device.equals(mBatch.mDestination)) + && (mCurrentShare.mConfirm + == BluetoothShare.USER_CONFIRMATION_PENDING)) { + Log.v( + TAG, + "ACTION_ACL_DISCONNECTED to be processed for batch: " + mBatch.mId); // Remove the timeout message triggered earlier during Obex Put mSessionHandler.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); // Now reuse the same message to clean up the session. - BluetoothMethodProxy.getInstance().handlerSendEmptyMessage(mSessionHandler, - BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); + BluetoothMethodProxy.getInstance() + .handlerSendEmptyMessage( + mSessionHandler, + BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); } } catch (Exception e) { ContentProfileErrorReportUtils.report( @@ -194,7 +190,8 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } String deviceIdentityAddress = getBrEdrAddress(device); String transferDeviceIdentityAddress = getBrEdrAddress(mDevice); - if (deviceIdentityAddress == null || transferDeviceIdentityAddress == null + if (deviceIdentityAddress == null + || transferDeviceIdentityAddress == null || !deviceIdentityAddress.equalsIgnoreCase( transferDeviceIdentityAddress)) { Log.w(TAG, " OPP SDP search for wrong device, ignoring!!"); @@ -241,7 +238,6 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch mBatch.registerListener(this); mAdapter = BluetoothAdapter.getDefaultAdapter(); - } public BluetoothOppTransfer(Context context, BluetoothOppBatch batch) { @@ -273,9 +269,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch break; case TRANSPORT_ERROR: /* - * RFCOMM connect fail is for outbound share only! Mark batch - * failed, and all shares in batch failed - */ + * RFCOMM connect fail is for outbound share only! Mark batch + * failed, and all shares in batch failed + */ Log.v(TAG, "receive TRANSPORT_ERROR msg"); synchronized (INSTANCE_LOCK) { mConnectThread = null; @@ -286,9 +282,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch break; case TRANSPORT_CONNECTED: /* - * RFCOMM connected is for outbound share only! Create - * BluetoothOppObexClientSession and start it - */ + * RFCOMM connected is for outbound share only! Create + * BluetoothOppObexClientSession and start it + */ Log.v(TAG, "Transfer receive TRANSPORT_CONNECTED msg"); synchronized (INSTANCE_LOCK) { mConnectThread = null; @@ -299,12 +295,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch break; case BluetoothOppObexSession.MSG_SHARE_COMPLETE: /* - * Put next share if available,or finish the transfer. - * For outbound session, call session.addShare() to send next file, - * or call session.stop(). - * For inbounds session, do nothing. If there is next file to receive,it - * will be notified through onShareAdded() - */ + * Put next share if available,or finish the transfer. + * For outbound session, call session.addShare() to send next file, + * or call session.stop(). + * For inbounds session, do nothing. If there is next file to receive,it + * will be notified through onShareAdded() + */ BluetoothOppShareInfo info = (BluetoothOppShareInfo) msg.obj; Log.v(TAG, "receive MSG_SHARE_COMPLETE for info=" + info); if (mBatch.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { @@ -312,8 +308,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch if (mCurrentShare != null) { /* we have additional share to process */ - Log.v(TAG, "continue session for info " + mCurrentShare.mId - + " from batch " + mBatch.mId); + Log.v( + TAG, + "continue session for info " + + mCurrentShare.mId + + " from batch " + + mBatch.mId); processCurrentShare(); } else { /* for outbound transfer, all shares are processed */ @@ -324,9 +324,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch break; case BluetoothOppObexSession.MSG_SESSION_COMPLETE: /* - * Handle session completed status Set batch status to - * finished - */ + * Handle session completed status Set batch status to + * finished + */ cleanUp(); BluetoothOppShareInfo info1 = (BluetoothOppShareInfo) msg.obj; Log.v(TAG, "receive MSG_SESSION_COMPLETE for batch " + mBatch.mId); @@ -437,10 +437,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch private void markShareTimeout(BluetoothOppShareInfo share) { Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + share.mId); ContentValues updateValues = new ContentValues(); - updateValues.put(BluetoothShare.USER_CONFIRMATION, - BluetoothShare.USER_CONFIRMATION_TIMEOUT); - BluetoothMethodProxy.getInstance().contentResolverUpdate(mContext.getContentResolver(), - contentUri, updateValues, null, null); + updateValues.put( + BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_TIMEOUT); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext.getContentResolver(), contentUri, updateValues, null, null); } private void markBatchFailed(int failReason) { @@ -465,8 +466,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } if (mCurrentShare.mDirection == BluetoothShare.DIRECTION_INBOUND && mCurrentShare.mUri != null) { - BluetoothMethodProxy.getInstance().contentResolverDelete( - mContext.getContentResolver(), mCurrentShare.mUri, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + mContext.getContentResolver(), mCurrentShare.mUri, null, null); } } @@ -492,17 +494,22 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } } else { if (info.mStatus < 200 && info.mUri != null) { - BluetoothMethodProxy.getInstance().contentResolverDelete( - mContext.getContentResolver(), info.mUri, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + mContext.getContentResolver(), info.mUri, null, null); } } - BluetoothMethodProxy.getInstance().contentResolverUpdate( - mContext.getContentResolver(), contentUri, updateValues, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext.getContentResolver(), + contentUri, + updateValues, + null, + null); Constants.sendIntentIfCompleted(mContext, contentUri, info.mStatus); } info = mBatch.getPendingShare(); } - } /* @@ -523,9 +530,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch * 3) Start the session and process the first share in batch */ - /** - * Start the transfer - */ + /** Start the transfer */ public void start() { /* check Bluetooth enable status */ /* @@ -562,12 +567,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch startObexSession(); } } - } - /** - * Stop the transfer - */ + /** Stop the transfer */ public void stop() { Log.v(TAG, "stop"); if (mSession != null) { @@ -687,21 +689,19 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } } - /** - * Set transfer confirmed status. It should only be called for inbound - * transfer - */ + /** Set transfer confirmed status. It should only be called for inbound transfer */ public void confirmStatusChanged() { /* unblock server session */ - final Thread notifyThread = new Thread("Server Unblock thread") { - @Override - public void run() { - synchronized (mSession) { - mSession.unblock(); - mSession.notify(); - } - } - }; + final Thread notifyThread = + new Thread("Server Unblock thread") { + @Override + public void run() { + synchronized (mSession) { + mSession.unblock(); + mSession.notify(); + } + } + }; Log.v(TAG, "confirmStatusChanged to unblock mSession" + mSession.toString()); notifyThread.start(); } @@ -718,13 +718,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } } - @VisibleForTesting - SocketConnectThread mConnectThread; + @VisibleForTesting SocketConnectThread mConnectThread; @VisibleForTesting class SocketConnectThread extends Thread { - @VisibleForTesting - final BluetoothDevice mDevice; + @VisibleForTesting final BluetoothDevice mDevice; private int mL2cChannel = 0; @@ -734,8 +732,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch private boolean mSdpInitiated = false; - @VisibleForTesting - boolean mIsInterrupted = false; + @VisibleForTesting boolean mIsInterrupted = false; /* create a Rfcomm/L2CAP Socket */ SocketConnectThread(BluetoothDevice device, boolean retry) { @@ -746,8 +743,8 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } /* create a Rfcomm/L2CAP Socket */ - SocketConnectThread(BluetoothDevice device, boolean retry, boolean sdpInitiated, - int l2capChannel) { + SocketConnectThread( + BluetoothDevice device, boolean retry, boolean sdpInitiated, int l2capChannel) { super("Socket Connect Thread"); this.mDevice = device; mRetry = retry; @@ -782,8 +779,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch markConnectionFailed(mBtSocket); return; } - mBtSocket = mDevice.createInsecureRfcommSocketToServiceRecord( - BluetoothUuid.OBEX_OBJECT_PUSH.getUuid()); + mBtSocket = + mDevice.createInsecureRfcommSocketToServiceRecord( + BluetoothUuid.OBEX_OBJECT_PUSH.getUuid()); } catch (IOException e1) { ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, @@ -797,14 +795,16 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch try { mBtSocket.connect(); - Log.v(TAG, - "Rfcomm socket connection attempt took " + (System.currentTimeMillis() - - mTimestamp) + " ms"); + Log.v( + TAG, + "Rfcomm socket connection attempt took " + + (System.currentTimeMillis() - mTimestamp) + + " ms"); BluetoothObexTransport transport; transport = new BluetoothObexTransport(mBtSocket); - BluetoothOppPreference.getInstance(mContext).setName(mDevice, - Utils.getName(mDevice)); + BluetoothOppPreference.getInstance(mContext) + .setName(mDevice, Utils.getName(mDevice)); Log.v(TAG, "Send transport message " + transport.toString()); @@ -876,12 +876,15 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } try { mBtSocket.connect(); - Log.v(TAG, "L2cap socket connection attempt took " + (System.currentTimeMillis() - - mTimestamp) + " ms"); + Log.v( + TAG, + "L2cap socket connection attempt took " + + (System.currentTimeMillis() - mTimestamp) + + " ms"); BluetoothObexTransport transport; transport = new BluetoothObexTransport(mBtSocket); - BluetoothOppPreference.getInstance(mContext).setName(mDevice, - Utils.getName(mDevice)); + BluetoothOppPreference.getInstance(mContext) + .setName(mDevice, Utils.getName(mDevice)); Log.v(TAG, "Send transport message " + transport.toString()); mSessionHandler.obtainMessage(TRANSPORT_CONNECTED, transport).sendToTarget(); } catch (IOException e) { @@ -922,8 +925,8 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch 22); Log.e(TAG, "Error when close socket"); } - BluetoothMethodProxy.getInstance().handlerSendEmptyMessage(mSessionHandler, - TRANSPORT_ERROR); + BluetoothMethodProxy.getInstance() + .handlerSendEmptyMessage(mSessionHandler, TRANSPORT_ERROR); return; } @@ -936,8 +939,9 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + share.mId); ContentValues updateValues = new ContentValues(); updateValues.put(BluetoothShare.DIRECTION, share.mDirection); - BluetoothMethodProxy.getInstance().contentResolverUpdate(mContext.getContentResolver(), - contentUri, updateValues, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + mContext.getContentResolver(), contentUri, updateValues, null, null); } /* @@ -948,9 +952,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch * mSession */ - /** - * Process when a share is added to current transfer - */ + /** Process when a share is added to current transfer */ @Override public void onShareAdded(int id) { BluetoothOppShareInfo info = mBatch.getPendingShare(); @@ -959,13 +961,17 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch /* * TODO what if it's not auto confirmed? */ - if (mCurrentShare != null && ( - mCurrentShare.mConfirm == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED + if (mCurrentShare != null + && (mCurrentShare.mConfirm == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED || mCurrentShare.mConfirm - == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)) { + == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)) { /* have additional auto confirmed share to process */ - Log.v(TAG, "Transfer continue session for info " + mCurrentShare.mId - + " from batch " + mBatch.mId); + Log.v( + TAG, + "Transfer continue session for info " + + mCurrentShare.mId + + " from batch " + + mBatch.mId); processCurrentShare(); confirmStatusChanged(); } @@ -980,17 +986,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch * delete share means the current receiving file should be canceled. */ - /** - * Process when a share is deleted from current transfer - */ + /** Process when a share is deleted from current transfer */ @Override - public void onShareDeleted(int id) { - - } + public void onShareDeleted(int id) {} - /** - * Process when current transfer is canceled - */ + /** Process when current transfer is canceled */ @Override public void onBatchCanceled() { Log.v(TAG, "Transfer on Batch canceled"); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java index 0b075dae255..86ac40b4819 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java @@ -85,8 +85,7 @@ public class BluetoothOppTransferActivity extends AlertActivity private TextView mLine1View, mLine2View, mLine3View, mLine5View; - @VisibleForTesting - int mWhichDialog; + @VisibleForTesting int mWhichDialog; // Dialogs definition: // Receive progress dialog @@ -155,8 +154,8 @@ public class BluetoothOppTransferActivity extends AlertActivity // update progress bar for ongoing transfer if (!mIsComplete) { mObserver = new BluetoothTransferContentObserver(); - getContentResolver().registerContentObserver(BluetoothShare.CONTENT_URI, true, - mObserver); + getContentResolver() + .registerContentObserver(BluetoothShare.CONTENT_URI, true, mObserver); } if (mWhichDialog != DIALOG_SEND_ONGOING && mWhichDialog != DIALOG_RECEIVE_ONGOING) { @@ -207,8 +206,13 @@ public class BluetoothOppTransferActivity extends AlertActivity } } - Log.v(TAG, " WhichDialog/dir/isComplete/failOrSuccess" + mWhichDialog + direction - + isComplete + isSuccess); + Log.v( + TAG, + " WhichDialog/dir/isComplete/failOrSuccess" + + mWhichDialog + + direction + + isComplete + + isSuccess); } private void setUpDialog() { @@ -247,9 +251,7 @@ public class BluetoothOppTransferActivity extends AlertActivity return mView; } - /** - * customize the content of view - */ + /** customize the content of view */ private void customizeViewContent() { String tmp; @@ -262,8 +264,10 @@ public class BluetoothOppTransferActivity extends AlertActivity tmp = getString(R.string.download_line2, mTransInfo.mFileName); mLine2View.setText(tmp); mLine3View = (TextView) mView.findViewById(R.id.line3_view); - tmp = getString(R.string.download_line3, - Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); + tmp = + getString( + R.string.download_line3, + Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); mLine3View.setText(tmp); mLine5View = (TextView) mView.findViewById(R.id.line5_view); if (mWhichDialog == DIALOG_RECEIVE_ONGOING) { @@ -281,8 +285,11 @@ public class BluetoothOppTransferActivity extends AlertActivity tmp = getString(R.string.download_line2, mTransInfo.mFileName); mLine2View.setText(tmp); mLine3View = (TextView) mView.findViewById(R.id.line3_view); - tmp = getString(R.string.upload_line3, mTransInfo.mFileType, - Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); + tmp = + getString( + R.string.upload_line3, + mTransInfo.mFileType, + Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); mLine3View.setText(tmp); mLine5View = (TextView) mView.findViewById(R.id.line5_view); if (mWhichDialog == DIALOG_SEND_ONGOING) { @@ -294,17 +301,20 @@ public class BluetoothOppTransferActivity extends AlertActivity } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) { if (mTransInfo.mStatus == BluetoothShare.STATUS_ERROR_SDCARD_FULL) { mLine1View = (TextView) mView.findViewById(R.id.line1_view); - int id = BluetoothOppUtility.deviceHasNoSdCard() - ? R.string.bt_sm_2_1_nosdcard - : R.string.bt_sm_2_1_default; + int id = + BluetoothOppUtility.deviceHasNoSdCard() + ? R.string.bt_sm_2_1_nosdcard + : R.string.bt_sm_2_1_default; tmp = getString(id); mLine1View.setText(tmp); mLine2View = (TextView) mView.findViewById(R.id.line2_view); tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName); mLine2View.setText(tmp); mLine3View = (TextView) mView.findViewById(R.id.line3_view); - tmp = getString(R.string.bt_sm_2_2, - Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); + tmp = + getString( + R.string.bt_sm_2_2, + Formatter.formatFileSize(this, mTransInfo.mTotalBytes)); mLine3View.setText(tmp); } else { mLine1View = (TextView) mView.findViewById(R.id.line1_view); @@ -314,9 +324,11 @@ public class BluetoothOppTransferActivity extends AlertActivity tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName); mLine2View.setText(tmp); mLine3View = (TextView) mView.findViewById(R.id.line3_view); - tmp = getString(R.string.download_fail_line3, - BluetoothOppUtility.getStatusDescription(this, mTransInfo.mStatus, - mTransInfo.mDeviceName)); + tmp = + getString( + R.string.download_fail_line3, + BluetoothOppUtility.getStatusDescription( + this, mTransInfo.mStatus, mTransInfo.mDeviceName)); mLine3View.setText(tmp); } mLine5View = (TextView) mView.findViewById(R.id.line5_view); @@ -329,9 +341,11 @@ public class BluetoothOppTransferActivity extends AlertActivity tmp = getString(R.string.upload_fail_line1_2, mTransInfo.mFileName); mLine2View.setText(tmp); mLine3View = (TextView) mView.findViewById(R.id.line3_view); - tmp = getString(R.string.download_fail_line3, - BluetoothOppUtility.getStatusDescription(this, mTransInfo.mStatus, - mTransInfo.mDeviceName)); + tmp = + getString( + R.string.download_fail_line3, + BluetoothOppUtility.getStatusDescription( + this, mTransInfo.mStatus, mTransInfo.mDeviceName)); mLine3View.setText(tmp); mLine5View = (TextView) mView.findViewById(R.id.line5_view); mLine5View.setVisibility(View.GONE); @@ -349,8 +363,12 @@ public class BluetoothOppTransferActivity extends AlertActivity case DialogInterface.BUTTON_POSITIVE: if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { // "Open" - open receive file - BluetoothOppUtility.openReceivedFile(this, mTransInfo.mFileName, - mTransInfo.mFileType, mTransInfo.mTimeStamp, mUri); + BluetoothOppUtility.openReceivedFile( + this, + mTransInfo.mFileName, + mTransInfo.mFileType, + mTransInfo.mTimeStamp, + mUri); // make current transfer "hidden" BluetoothOppUtility.updateVisibilityToHidden(this, mUri); @@ -386,9 +404,7 @@ public class BluetoothOppTransferActivity extends AlertActivity finish(); } - /** - * Update progress bar per data got from content provider - */ + /** Update progress bar per data got from content provider */ private void updateProgressbar() { mTransInfo = BluetoothOppUtility.queryRecord(this, mUri); if (mTransInfo == null) { @@ -405,23 +421,31 @@ public class BluetoothOppTransferActivity extends AlertActivity mProgressTransfer.setMax(100); if (mTransInfo.mTotalBytes != 0) { - Log.v(TAG, "mCurrentBytes: " + mTransInfo.mCurrentBytes + " mTotalBytes: " - + mTransInfo.mTotalBytes + " (" + (int) ((mTransInfo.mCurrentBytes * 100) - / mTransInfo.mTotalBytes) + "%)"); + Log.v( + TAG, + "mCurrentBytes: " + + mTransInfo.mCurrentBytes + + " mTotalBytes: " + + mTransInfo.mTotalBytes + + " (" + + (int) ((mTransInfo.mCurrentBytes * 100) / mTransInfo.mTotalBytes) + + "%)"); mProgressTransfer.setProgress( (int) ((mTransInfo.mCurrentBytes * 100) / mTransInfo.mTotalBytes)); } else { mProgressTransfer.setProgress(100); } - mPercentView.setText(BluetoothOppUtility.formatProgressText(mTransInfo.mTotalBytes, - mTransInfo.mCurrentBytes)); + mPercentView.setText( + BluetoothOppUtility.formatProgressText( + mTransInfo.mTotalBytes, mTransInfo.mCurrentBytes)); // Handle the case when DIALOG_RECEIVE_ONGOING evolve to // DIALOG_RECEIVE_COMPLETE_SUCCESS/DIALOG_RECEIVE_COMPLETE_FAIL // Handle the case when DIALOG_SEND_ONGOING evolve to // DIALOG_SEND_COMPLETE_SUCCESS/DIALOG_SEND_COMPLETE_FAIL - if (!mIsComplete && BluetoothShare.isStatusCompleted(mTransInfo.mStatus) + if (!mIsComplete + && BluetoothShare.isStatusCompleted(mTransInfo.mStatus) && mNeedUpdateButton) { if (mObserver != null) { getContentResolver().unregisterContentObserver(mObserver); @@ -433,31 +457,22 @@ public class BluetoothOppTransferActivity extends AlertActivity } } - /** - * Update button when one transfer goto complete from ongoing - */ + /** Update button when one transfer goto complete from ongoing */ private void updateButton() { if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { changeButtonVisibility(DialogInterface.BUTTON_NEGATIVE, View.GONE); - changeButtonText( - DialogInterface.BUTTON_POSITIVE, - getString(R.string.download_succ_ok)); + changeButtonText(DialogInterface.BUTTON_POSITIVE, getString(R.string.download_succ_ok)); } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) { changeIconAttribute(android.R.attr.alertDialogIcon); changeButtonVisibility(DialogInterface.BUTTON_NEGATIVE, View.GONE); - changeButtonText( - DialogInterface.BUTTON_POSITIVE, - getString(R.string.download_fail_ok)); + changeButtonText(DialogInterface.BUTTON_POSITIVE, getString(R.string.download_fail_ok)); } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) { changeButtonVisibility(DialogInterface.BUTTON_NEGATIVE, View.GONE); - changeButtonText( - DialogInterface.BUTTON_POSITIVE, - getString(R.string.upload_succ_ok)); + changeButtonText(DialogInterface.BUTTON_POSITIVE, getString(R.string.upload_succ_ok)); } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) { changeIconAttribute(android.R.attr.alertDialogIcon); changeButtonText( - DialogInterface.BUTTON_NEGATIVE, - getString(R.string.upload_fail_cancel)); + DialogInterface.BUTTON_NEGATIVE, getString(R.string.upload_fail_cancel)); } } } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferAdapter.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferAdapter.java index 134b2d68574..c9e6c98ecfc 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferAdapter.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferAdapter.java @@ -50,15 +50,14 @@ import com.android.bluetooth.R; import java.util.Date; /** - * This class is used to represent the data for the transfer history list box. - * The only real work done by this class is to construct a custom view for the - * line items. + * This class is used to represent the data for the transfer history list box. The only real work + * done by this class is to construct a custom view for the line items. */ public class BluetoothOppTransferAdapter extends ResourceCursorAdapter { private Context mContext; public BluetoothOppTransferAdapter(Context context, int layout, Cursor c) { - super(context, layout, c, true /* autoRequery */ ); + super(context, layout, c, true /* autoRequery */); mContext = context; } @@ -107,11 +106,15 @@ public class BluetoothOppTransferAdapter extends ResourceCursorAdapter { } else { String completeText; if (dir == BluetoothShare.DIRECTION_INBOUND) { - completeText = r.getString(R.string.download_success, - Formatter.formatFileSize(mContext, totalBytes)); + completeText = + r.getString( + R.string.download_success, + Formatter.formatFileSize(mContext, totalBytes)); } else { - completeText = r.getString(R.string.upload_success, - Formatter.formatFileSize(mContext, totalBytes)); + completeText = + r.getString( + R.string.upload_success, + Formatter.formatFileSize(mContext, totalBytes)); } tv.setText(completeText); } @@ -120,7 +123,8 @@ public class BluetoothOppTransferAdapter extends ResourceCursorAdapter { long time = cursor.getLong(dateColumnId); Date d = new Date(time); CharSequence str = - DateUtils.isToday(time) ? DateFormat.getTimeFormat(mContext).format(d) + DateUtils.isToday(time) + ? DateFormat.getTimeFormat(mContext).format(d) : DateFormat.getDateFormat(mContext).format(d); tv = (TextView) view.findViewById(R.id.complete_date); tv.setVisibility(View.VISIBLE); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java index 46e6a59ca86..68c5eac10c4 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java @@ -69,7 +69,6 @@ public class BluetoothOppTransferHistory extends Activity implements View.OnCreateContextMenuListener, OnItemClickListener { private static final String TAG = "BluetoothOppTransferHistory"; - private ListView mListView; private Cursor mTransferCursor; @@ -106,32 +105,54 @@ public class BluetoothOppTransferHistory extends Activity if (isOutbound) { setTitle(getText(R.string.outbound_history_title)); - direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_OUTBOUND - + ")"; + direction = + "(" + + BluetoothShare.DIRECTION + + " == " + + BluetoothShare.DIRECTION_OUTBOUND + + ")"; } else { setTitle(getText(R.string.inbound_history_title)); - direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_INBOUND - + ")"; + direction = + "(" + + BluetoothShare.DIRECTION + + " == " + + BluetoothShare.DIRECTION_INBOUND + + ")"; } - String selection = BluetoothShare.STATUS + " >= '200' AND " + direction + " AND (" - + BluetoothShare.VISIBILITY + " IS NULL OR " - + BluetoothShare.VISIBILITY + " == '" + BluetoothShare.VISIBILITY_VISIBLE - + "')"; + String selection = + BluetoothShare.STATUS + + " >= '200' AND " + + direction + + " AND (" + + BluetoothShare.VISIBILITY + + " IS NULL OR " + + BluetoothShare.VISIBILITY + + " == '" + + BluetoothShare.VISIBILITY_VISIBLE + + "')"; final String sortOrder = BluetoothShare.TIMESTAMP + " DESC"; - mTransferCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - getContentResolver(), BluetoothShare.CONTENT_URI, new String[]{ - "_id", - BluetoothShare.FILENAME_HINT, - BluetoothShare.STATUS, - BluetoothShare.TOTAL_BYTES, - BluetoothShare._DATA, - BluetoothShare.TIMESTAMP, - BluetoothShare.VISIBILITY, - BluetoothShare.DESTINATION, - BluetoothShare.DIRECTION - }, selection, null, sortOrder); + mTransferCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + getContentResolver(), + BluetoothShare.CONTENT_URI, + new String[] { + "_id", + BluetoothShare.FILENAME_HINT, + BluetoothShare.STATUS, + BluetoothShare.TOTAL_BYTES, + BluetoothShare._DATA, + BluetoothShare.TIMESTAMP, + BluetoothShare.VISIBILITY, + BluetoothShare.DESTINATION, + BluetoothShare.DIRECTION + }, + selection, + null, + sortOrder); // only attach everything to the listbox if we can access // the transfer database. Otherwise, just show it empty @@ -139,8 +160,8 @@ public class BluetoothOppTransferHistory extends Activity mIdColumnId = mTransferCursor.getColumnIndexOrThrow(BluetoothShare._ID); // Create a list "controller" for the data mTransferAdapter = - new BluetoothOppTransferAdapter(this, R.layout.bluetooth_transfer_item, - mTransferCursor); + new BluetoothOppTransferAdapter( + this, R.layout.bluetooth_transfer_item, mTransferCursor); mListView.setAdapter(mTransferAdapter); mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); mListView.setOnCreateContextMenuListener(this); @@ -215,8 +236,9 @@ public class BluetoothOppTransferHistory extends Activity mTransferCursor.moveToPosition(info.position); mContextMenuPosition = info.position; - String fileName = mTransferCursor.getString( - mTransferCursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)); + String fileName = + mTransferCursor.getString( + mTransferCursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)); if (fileName == null) { fileName = this.getString(R.string.unknown_file); } @@ -225,31 +247,30 @@ public class BluetoothOppTransferHistory extends Activity } } - /** - * Prompt the user if they would like to clear the transfer history - */ + /** Prompt the user if they would like to clear the transfer history */ private void promptClearList() { - new AlertDialog.Builder(this).setTitle(R.string.transfer_clear_dlg_title) + new AlertDialog.Builder(this) + .setTitle(R.string.transfer_clear_dlg_title) .setMessage(R.string.transfer_clear_dlg_msg) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - clearAllDownloads(); - } - }) + .setPositiveButton( + android.R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + clearAllDownloads(); + } + }) .setNegativeButton(android.R.string.cancel, null) .show(); } - /** - * Returns true if the device has finished transfers, including error and success. - */ + /** Returns true if the device has finished transfers, including error and success. */ private boolean isTransferComplete() { try { if (mTransferCursor.moveToFirst()) { while (!mTransferCursor.isAfterLast()) { - int statusColumnId = mTransferCursor - .getColumnIndexOrThrow(BluetoothShare.STATUS); + int statusColumnId = + mTransferCursor.getColumnIndexOrThrow(BluetoothShare.STATUS); int status = mTransferCursor.getInt(statusColumnId); if (BluetoothShare.isStatusCompleted(status)) { return true; @@ -267,9 +288,7 @@ public class BluetoothOppTransferHistory extends Activity return false; } - /** - * Clear all finished transfers, error and success transfer items. - */ + /** Clear all finished transfers, error and success transfer items. */ private void clearAllDownloads() { if (mTransferCursor.moveToFirst()) { while (!mTransferCursor.isAfterLast()) { @@ -302,8 +321,8 @@ public class BluetoothOppTransferHistory extends Activity } /** - * Open the selected finished transfer. mDownloadCursor must be moved to - * appropriate position before calling this function + * Open the selected finished transfer. mDownloadCursor must be moved to appropriate position + * before calling this function */ private void openCompleteTransfer() { int sessionId = mTransferCursor.getInt(mIdColumnId); @@ -322,8 +341,12 @@ public class BluetoothOppTransferHistory extends Activity && BluetoothShare.isStatusSuccess(transInfo.mStatus)) { // if received file successfully, open this file BluetoothOppUtility.updateVisibilityToHidden(this, contentUri); - BluetoothOppUtility.openReceivedFile(this, transInfo.mFileName, transInfo.mFileType, - transInfo.mTimeStamp, contentUri); + BluetoothOppUtility.openReceivedFile( + this, + transInfo.mFileName, + transInfo.mFileType, + transInfo.mTimeStamp, + contentUri); } else { Intent in = new Intent(this, BluetoothOppTransferActivity.class); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -333,8 +356,8 @@ public class BluetoothOppTransferHistory extends Activity } /** - * When Bluetooth is disabled, notification can not be updated by - * ContentObserver in OppService, so need update manually. + * When Bluetooth is disabled, notification can not be updated by ContentObserver in OppService, + * so need update manually. */ private void updateNotificationWhenBtDisabled() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferInfo.java index cf50979a2e3..157d0e2a860 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferInfo.java @@ -33,8 +33,8 @@ package com.android.bluetooth.opp; /** - * This is currently used by Application codes. This class stores information - * about a single OBEX transfer (operation) + * This is currently used by Application codes. This class stores information about a single OBEX + * transfer (operation) */ public class BluetoothOppTransferInfo { int mID; diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java index f62080d2500..32bbe515c05 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java @@ -76,6 +76,7 @@ import java.util.concurrent.ConcurrentHashMap; // Next tag value for ContentProfileErrorReportUtils.report(): 10 public class BluetoothOppUtility { private static final String TAG = "BluetoothOppUtility"; + /** Whether the device has the "nosdcard" characteristic, or null if not-yet-known. */ private static Boolean sNoSdCard = null; @@ -93,9 +94,10 @@ public class BluetoothOppUtility { public static BluetoothOppTransferInfo queryRecord(Context context, Uri uri) { BluetoothOppTransferInfo info = new BluetoothOppTransferInfo(); - Cursor cursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - context.getContentResolver(), uri, null, null, null, null - ); + Cursor cursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + context.getContentResolver(), uri, null, null, null, null); if (cursor != null) { if (cursor.moveToFirst()) { fillRecord(context, cursor, info); @@ -153,27 +155,27 @@ public class BluetoothOppUtility { Log.v(TAG, "Get data from db:" + info.mFileName + info.mFileType + info.mDestAddr); } - /** - * Organize Array list for transfers in one batch - */ + /** Organize Array list for transfers in one batch */ // This function is used when UI show batch transfer. Currently only show single transfer. public static ArrayList queryTransfersInBatch(Context context, Long timeStamp) { ArrayList uris = new ArrayList(); final String where = BluetoothShare.TIMESTAMP + " == " + timeStamp; - Cursor metadataCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - context.getContentResolver(), - BluetoothShare.CONTENT_URI, - new String[]{BluetoothShare._DATA}, - where, - null, - BluetoothShare._ID - ); + Cursor metadataCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + context.getContentResolver(), + BluetoothShare.CONTENT_URI, + new String[] {BluetoothShare._DATA}, + where, + null, + BluetoothShare._ID); if (metadataCursor == null) { return null; } - for (metadataCursor.moveToFirst(); !metadataCursor.isAfterLast(); + for (metadataCursor.moveToFirst(); + !metadataCursor.isAfterLast(); metadataCursor.moveToNext()) { String fileName = metadataCursor.getString(0); Uri path = Uri.parse(fileName); @@ -189,11 +191,11 @@ public class BluetoothOppUtility { } /** - * Open the received file with appropriate application, if can not find - * application to handle, display error dialog. + * Open the received file with appropriate application, if can not find application to handle, + * display error dialog. */ - public static void openReceivedFile(Context context, String fileName, String mimetype, - Long timeStamp, Uri uri) { + public static void openReceivedFile( + Context context, String fileName, String mimetype, Long timeStamp, Uri uri) { if (fileName == null || mimetype == null) { Log.e(TAG, "ERROR: Para fileName ==null, or mimetype == null"); ContentProfileErrorReportUtils.report( @@ -215,10 +217,15 @@ public class BluetoothOppUtility { } Uri path = null; - Cursor metadataCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - context.getContentResolver(), uri, new String[]{BluetoothShare.URI}, - null, null, null - ); + Cursor metadataCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + context.getContentResolver(), + uri, + new String[] {BluetoothShare.URI}, + null, + null, + null); if (metadataCursor != null) { try { if (metadataCursor.moveToFirst()) { @@ -249,8 +256,8 @@ public class BluetoothOppUtility { // Due to the file is not existing, delete related info in btopp db // to prevent this file from appearing in live folder Log.v(TAG, "This uri will be deleted: " + uri); - BluetoothMethodProxy.getInstance().contentResolverDelete(context.getContentResolver(), - uri, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverDelete(context.getContentResolver(), uri, null, null); return; } @@ -299,10 +306,7 @@ public class BluetoothOppUtility { return false; } - /** - * To judge if the file type supported (can be handled by some app) by phone - * system. - */ + /** To judge if the file type supported (can be handled by some app) by phone system. */ public static boolean isRecognizedFileType(Context context, Uri fileUri, String mimetype) { boolean ret = true; @@ -310,8 +314,9 @@ public class BluetoothOppUtility { Intent mimetypeIntent = new Intent(Intent.ACTION_VIEW); mimetypeIntent.setDataAndTypeAndNormalize(fileUri, mimetype); - List list = context.getPackageManager() - .queryIntentActivities(mimetypeIntent, PackageManager.MATCH_DEFAULT_ONLY); + List list = + context.getPackageManager() + .queryIntentActivities(mimetypeIntent, PackageManager.MATCH_DEFAULT_ONLY); if (list.size() == 0) { Log.d(TAG, "NO application to handle MIME type " + mimetype); @@ -320,19 +325,15 @@ public class BluetoothOppUtility { return ret; } - /** - * update visibility to Hidden - */ + /** update visibility to Hidden */ public static void updateVisibilityToHidden(Context context, Uri uri) { ContentValues updateValues = new ContentValues(); updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); - BluetoothMethodProxy.getInstance().contentResolverUpdate(context.getContentResolver(), uri, - updateValues, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate(context.getContentResolver(), uri, updateValues, null, null); } - /** - * Helper function to build the progress text. - */ + /** Helper function to build the progress text. */ public static String formatProgressText(long totalBytes, long currentBytes) { DecimalFormat df = new DecimalFormat("0%"); df.setRoundingMode(RoundingMode.DOWN); @@ -343,9 +344,7 @@ public class BluetoothOppUtility { return df.format(percent); } - /** - * Helper function to build the result notification text content. - */ + /** Helper function to build the result notification text content. */ static String formatResultText(int countSuccess, int countUnsuccessful, Context context) { if (context == null) { return null; @@ -356,16 +355,22 @@ public class BluetoothOppUtility { Map mapSuccess = new HashMap<>(); mapSuccess.put("count", countSuccess); - return new MessageFormat(context.getResources().getString(R.string.noti_caption_success, - new MessageFormat(context.getResources().getString( - R.string.noti_caption_unsuccessful), - Locale.getDefault()).format(mapUnsuccessful)), - Locale.getDefault()).format(mapSuccess); + return new MessageFormat( + context.getResources() + .getString( + R.string.noti_caption_success, + new MessageFormat( + context.getResources() + .getString( + R.string + .noti_caption_unsuccessful), + Locale.getDefault()) + .format(mapUnsuccessful)), + Locale.getDefault()) + .format(mapSuccess); } - /** - * Whether the device has the "nosdcard" characteristic or not. - */ + /** Whether the device has the "nosdcard" characteristic or not. */ public static boolean deviceHasNoSdCard() { if (sNoSdCard == null) { String characteristics = SystemProperties.get("ro.build.characteristics", ""); @@ -374,9 +379,7 @@ public class BluetoothOppUtility { return sNoSdCard; } - /** - * Get status description according to status code. - */ + /** Get status description according to status code. */ public static String getStatusDescription(Context context, int statusCode, String deviceName) { String ret; if (statusCode == BluetoothShare.STATUS_PENDING) { @@ -394,20 +397,21 @@ public class BluetoothOppUtility { } else if (statusCode == BluetoothShare.STATUS_FILE_ERROR) { ret = context.getString(R.string.status_file_error); } else if (statusCode == BluetoothShare.STATUS_ERROR_NO_SDCARD) { - int id = deviceHasNoSdCard() - ? R.string.status_no_sd_card_nosdcard - : R.string.status_no_sd_card_default; + int id = + deviceHasNoSdCard() + ? R.string.status_no_sd_card_nosdcard + : R.string.status_no_sd_card_default; ret = context.getString(id); } else if (statusCode == BluetoothShare.STATUS_CONNECTION_ERROR) { ret = context.getString(R.string.status_connection_error); } else if (statusCode == BluetoothShare.STATUS_ERROR_SDCARD_FULL) { int id = deviceHasNoSdCard() ? R.string.bt_sm_2_1_nosdcard : R.string.bt_sm_2_1_default; ret = context.getString(id); - } else if ((statusCode == BluetoothShare.STATUS_BAD_REQUEST) || (statusCode - == BluetoothShare.STATUS_LENGTH_REQUIRED) || (statusCode - == BluetoothShare.STATUS_PRECONDITION_FAILED) || (statusCode - == BluetoothShare.STATUS_UNHANDLED_OBEX_CODE) || (statusCode - == BluetoothShare.STATUS_OBEX_DATA_ERROR)) { + } else if ((statusCode == BluetoothShare.STATUS_BAD_REQUEST) + || (statusCode == BluetoothShare.STATUS_LENGTH_REQUIRED) + || (statusCode == BluetoothShare.STATUS_PRECONDITION_FAILED) + || (statusCode == BluetoothShare.STATUS_UNHANDLED_OBEX_CODE) + || (statusCode == BluetoothShare.STATUS_OBEX_DATA_ERROR)) { ret = context.getString(R.string.status_protocol_error); } else { ret = context.getString(R.string.status_unknown_error); @@ -415,9 +419,7 @@ public class BluetoothOppUtility { return ret; } - /** - * Retry the failed transfer: Will insert a new transfer session to db - */ + /** Retry the failed transfer: Will insert a new transfer session to db */ public static void retryTransfer(Context context, BluetoothOppTransferInfo transInfo) { ContentValues values = new ContentValues(); values.put(BluetoothShare.URI, transInfo.mFileUri); @@ -426,8 +428,7 @@ public class BluetoothOppUtility { final Uri contentUri = context.getContentResolver().insert(BluetoothShare.CONTENT_URI, values); - Log.v(TAG, - "Insert contentUri: " + contentUri + " to device: " + transInfo.mDeviceName); + Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " + transInfo.mDeviceName); } static Uri originalUri(Uri uri) { @@ -486,9 +487,8 @@ public class BluetoothOppUtility { } /** - * Checks if the URI is in Environment.getExternalStorageDirectory() as it - * is the only directory that is possibly readable by both the sender and - * the Bluetooth process. + * Checks if the URI is in Environment.getExternalStorageDirectory() as it is the only directory + * that is possibly readable by both the sender and the Bluetooth process. */ static boolean isInExternalStorageDir(Uri uri) { if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { @@ -514,22 +514,22 @@ public class BluetoothOppUtility { canonicalPath = uri.getPath(); } File file = new File(canonicalPath); - //if emulated + // if emulated if (Environment.isExternalStorageEmulated()) { - //Gets legacy external storage path - final String legacyPath = new File( - System.getenv("EXTERNAL_STORAGE")).toString(); + // Gets legacy external storage path + final String legacyPath = new File(System.getenv("EXTERNAL_STORAGE")).toString(); // Splice in user-specific path when legacy path is found if (canonicalPath.startsWith(legacyPath)) { - file = new File( - Environment.getExternalStorageDirectory().toString(), - canonicalPath.substring(legacyPath.length() + 1)); + file = + new File( + Environment.getExternalStorageDirectory().toString(), + canonicalPath.substring(legacyPath.length() + 1)); } } return isSameOrSubDirectory(Environment.getExternalStorageDirectory(), file); } - return isSameOrSubDirectory(Environment.getExternalStorageDirectory(), - new File(uri.getPath())); + return isSameOrSubDirectory( + Environment.getExternalStorageDirectory(), new File(uri.getPath())); } static boolean isForbiddenContent(Uri uri) { @@ -540,8 +540,8 @@ public class BluetoothOppUtility { } /** - * Checks, whether the child directory is the same as, or a sub-directory of the base - * directory. Neither base nor child should be null. + * Checks, whether the child directory is the same as, or a sub-directory of the base directory. + * Neither base nor child should be null. */ static boolean isSameOrSubDirectory(File base, File child) { try { @@ -570,5 +570,4 @@ public class BluetoothOppUtility { NotificationManager nm = ctx.getSystemService(NotificationManager.class); nm.cancel(BluetoothOppNotification.NOTIFICATION_ID_PROGRESS); } - } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothShare.java b/android/app/src/com/android/bluetooth/opp/BluetoothShare.java index 9eec5e35311..1e539a37016 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothShare.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothShare.java @@ -35,385 +35,292 @@ package com.android.bluetooth.opp; import android.net.Uri; import android.provider.BaseColumns; -/** - * Exposes constants used to interact with the Bluetooth Share manager's content - * provider. - */ - +/** Exposes constants used to interact with the Bluetooth Share manager's content provider. */ public final class BluetoothShare implements BaseColumns { - private BluetoothShare() { - } + private BluetoothShare() {} - /** - * The permission to access the Bluetooth Share Manager - */ + /** The permission to access the Bluetooth Share Manager */ public static final String PERMISSION_ACCESS = "android.permission.ACCESS_BLUETOOTH_SHARE"; - /** - * The content:// URI for the data table in the provider - */ + /** The content:// URI for the data table in the provider */ public static final Uri CONTENT_URI = Uri.parse("content://com.android.bluetooth.opp/btopp"); /** - * Broadcast Action: this is sent by the Bluetooth Share component to - * transfer complete. The request detail could be retrieved by app * as _ID - * is specified in the intent's data. + * Broadcast Action: this is sent by the Bluetooth Share component to transfer complete. The + * request detail could be retrieved by app * as _ID is specified in the intent's data. */ public static final String TRANSFER_COMPLETED_ACTION = "android.btopp.intent.action.TRANSFER_COMPLETE"; /** - * This is sent by the Bluetooth Share component to indicate there is an - * incoming file request timeout and need update UI. + * This is sent by the Bluetooth Share component to indicate there is an incoming file request + * timeout and need update UI. */ public static final String USER_CONFIRMATION_TIMEOUT_ACTION = "android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT"; /** - * The name of the column containing the URI of the file being - * sent/received. - *

- * Type: TEXT - *

- *

- * Owner can Init/Read - *

+ * The name of the column containing the URI of the file being sent/received. + * + *

Type: TEXT + * + *

Owner can Init/Read */ public static final String URI = "uri"; /** - * The name of the column containing the filename that the incoming file - * request recommends. When possible, the Bluetooth Share manager will - * attempt to use this filename, or a variation, as the actual name for the - * file. - *

- * Type: TEXT - *

- *

- * Owner can Init/Read - *

+ * The name of the column containing the filename that the incoming file request recommends. + * When possible, the Bluetooth Share manager will attempt to use this filename, or a variation, + * as the actual name for the file. + * + *

Type: TEXT + * + *

Owner can Init/Read */ public static final String FILENAME_HINT = "hint"; /** - * The name of the column containing the filename where the shared file was - * actually stored. - *

- * Type: TEXT - *

- *

- * Owner can Read - *

+ * The name of the column containing the filename where the shared file was actually stored. + * + *

Type: TEXT + * + *

Owner can Read */ public static final String _DATA = "_data"; /** * The name of the column containing the MIME type of the shared file. - *

- * Type: TEXT - *

- *

- * Owner can Init/Read - *

+ * + *

Type: TEXT + * + *

Owner can Init/Read */ public static final String MIMETYPE = "mimetype"; /** - * The name of the column containing the direction (Inbound/Outbound) of the - * transfer. See the DIRECTION_* constants for a list of legal values. - *

- * Type: INTEGER - *

- *

- * Owner can Init/Read - *

+ * The name of the column containing the direction (Inbound/Outbound) of the transfer. See the + * DIRECTION_* constants for a list of legal values. + * + *

Type: INTEGER + * + *

Owner can Init/Read */ public static final String DIRECTION = "direction"; /** - * The name of the column containing Bluetooth Device Address that the - * transfer is associated with. - *

- * Type: TEXT - *

- *

- * Owner can Init/Read - *

+ * The name of the column containing Bluetooth Device Address that the transfer is associated + * with. + * + *

Type: TEXT + * + *

Owner can Init/Read */ public static final String DESTINATION = "destination"; /** - * The name of the column containing the flags that controls whether the - * transfer is displayed by the UI. See the VISIBILITY_* constants for a - * list of legal values. - *

- * Type: INTEGER - *

- *

- * Owner can Init/Read/Write - *

+ * The name of the column containing the flags that controls whether the transfer is displayed + * by the UI. See the VISIBILITY_* constants for a list of legal values. + * + *

Type: INTEGER + * + *

Owner can Init/Read/Write */ public static final String VISIBILITY = "visibility"; /** - * The name of the column containing the current user confirmation state of - * the transfer. Applications can write to this to confirm the transfer. the - * USER_CONFIRMATION_* constants for a list of legal values. - *

- * Type: INTEGER - *

- *

- * Owner can Init/Read/Write - *

+ * The name of the column containing the current user confirmation state of the transfer. + * Applications can write to this to confirm the transfer. the USER_CONFIRMATION_* constants for + * a list of legal values. + * + *

Type: INTEGER + * + *

Owner can Init/Read/Write */ public static final String USER_CONFIRMATION = "confirm"; /** - * The name of the column containing the current status of the transfer. - * Applications can read this to follow the progress of each download. See - * the STATUS_* constants for a list of legal values. - *

- * Type: INTEGER - *

- *

- * Owner can Read - *

+ * The name of the column containing the current status of the transfer. Applications can read + * this to follow the progress of each download. See the STATUS_* constants for a list of legal + * values. + * + *

Type: INTEGER + * + *

Owner can Read */ public static final String STATUS = "status"; /** - * The name of the column containing the total size of the file being - * transferred. - *

- * Type: INTEGER - *

- *

- * Owner can Read - *

+ * The name of the column containing the total size of the file being transferred. + * + *

Type: INTEGER + * + *

Owner can Read */ public static final String TOTAL_BYTES = "total_bytes"; /** - * The name of the column containing the size of the part of the file that - * has been transferred so far. - *

- * Type: INTEGER - *

- *

- * Owner can Read - *

+ * The name of the column containing the size of the part of the file that has been transferred + * so far. + * + *

Type: INTEGER + * + *

Owner can Read */ public static final String CURRENT_BYTES = "current_bytes"; /** - * The name of the column containing the timestamp when the transfer is - * initialized. - *

- * Type: INTEGER - *

- *

- * Owner can Read - *

+ * The name of the column containing the timestamp when the transfer is initialized. + * + *

Type: INTEGER + * + *

Owner can Read */ public static final String TIMESTAMP = "timestamp"; - /** - * This transfer is outbound, e.g. share file to other device. - */ + /** This transfer is outbound, e.g. share file to other device. */ public static final int DIRECTION_OUTBOUND = 0; - /** - * This transfer is inbound, e.g. receive file from other device. - */ + /** This transfer is inbound, e.g. receive file from other device. */ public static final int DIRECTION_INBOUND = 1; - /** - * This transfer is waiting for user confirmation. - */ + /** This transfer is waiting for user confirmation. */ public static final int USER_CONFIRMATION_PENDING = 0; - /** - * This transfer is confirmed by user. - */ + /** This transfer is confirmed by user. */ public static final int USER_CONFIRMATION_CONFIRMED = 1; - /** - * This transfer is auto-confirmed per previous user confirmation. - */ + /** This transfer is auto-confirmed per previous user confirmation. */ public static final int USER_CONFIRMATION_AUTO_CONFIRMED = 2; - /** - * This transfer is denied by user. - */ + /** This transfer is denied by user. */ public static final int USER_CONFIRMATION_DENIED = 3; - /** - * This transfer is timeout before user action. - */ + /** This transfer is timeout before user action. */ public static final int USER_CONFIRMATION_TIMEOUT = 4; /** - * This transfer was initiated by a connection handover - * (for example WIFI, NFC) and has been auto-confirmed. + * This transfer was initiated by a connection handover (for example WIFI, NFC) and has been + * auto-confirmed. */ public static final int USER_CONFIRMATION_HANDOVER_CONFIRMED = 5; /** - * This transfer is visible and shows in the notifications while in progress - * and after completion. + * This transfer is visible and shows in the notifications while in progress and after + * completion. */ public static final int VISIBILITY_VISIBLE = 0; - /** - * This transfer doesn't show in the notifications. - */ + /** This transfer doesn't show in the notifications. */ public static final int VISIBILITY_HIDDEN = 1; - /** - * Returns whether the status is informational (i.e. 1xx). - */ + /** Returns whether the status is informational (i.e. 1xx). */ public static boolean isStatusInformational(int status) { return (status >= 100 && status < 200); } /** - * Returns whether the transfer is suspended. (i.e. whether the transfer - * won't complete without some action from outside the transfer manager). + * Returns whether the transfer is suspended. (i.e. whether the transfer won't complete without + * some action from outside the transfer manager). */ public static boolean isStatusSuspended(int status) { return (status == STATUS_PENDING); } - /** - * Returns whether the status is a success (i.e. 2xx). - */ + /** Returns whether the status is a success (i.e. 2xx). */ public static boolean isStatusSuccess(int status) { return (status >= 200 && status < 300); } - /** - * Returns whether the status is an error (i.e. 4xx or 5xx). - */ + /** Returns whether the status is an error (i.e. 4xx or 5xx). */ public static boolean isStatusError(int status) { return (status >= 400 && status < 600); } - /** - * Returns whether the status is a client error (i.e. 4xx). - */ + /** Returns whether the status is a client error (i.e. 4xx). */ public static boolean isStatusClientError(int status) { return (status >= 400 && status < 500); } - /** - * Returns whether the status is a server error (i.e. 5xx). - */ + /** Returns whether the status is a server error (i.e. 5xx). */ public static boolean isStatusServerError(int status) { return (status >= 500 && status < 600); } - /** - * Returns whether the transfer has completed (either with success or - * error). - */ + /** Returns whether the transfer has completed (either with success or error). */ public static boolean isStatusCompleted(int status) { return (status >= 200 && status < 300) || (status >= 400 && status < 600); } - /** - * This transfer hasn't stated yet - */ + /** This transfer hasn't stated yet */ public static final int STATUS_PENDING = 190; - /** - * This transfer has started - */ + /** This transfer has started */ public static final int STATUS_RUNNING = 192; /** - * This transfer has successfully completed. Warning: there might be other - * status values that indicate success in the future. Use isSucccess() to - * capture the entire category. + * This transfer has successfully completed. Warning: there might be other status values that + * indicate success in the future. Use isSucccess() to capture the entire category. */ public static final int STATUS_SUCCESS = 200; /** - * This request couldn't be parsed. This is also used when processing - * requests with unknown/unsupported URI schemes. + * This request couldn't be parsed. This is also used when processing requests with + * unknown/unsupported URI schemes. */ public static final int STATUS_BAD_REQUEST = 400; - /** - * This transfer is forbidden by target device. - */ + /** This transfer is forbidden by target device. */ public static final int STATUS_FORBIDDEN = 403; - /** - * This transfer can't be performed because the content cannot be handled. - */ + /** This transfer can't be performed because the content cannot be handled. */ public static final int STATUS_NOT_ACCEPTABLE = 406; /** - * This transfer cannot be performed because the length cannot be determined - * accurately. This is the code for the HTTP error "Length Required", which - * is typically used when making requests that require a content length but - * don't have one, and it is also used in the client when a response is - * received whose length cannot be determined accurately (therefore making - * it impossible to know when a transfer completes). + * This transfer cannot be performed because the length cannot be determined accurately. This is + * the code for the HTTP error "Length Required", which is typically used when making requests + * that require a content length but don't have one, and it is also used in the client when a + * response is received whose length cannot be determined accurately (therefore making it + * impossible to know when a transfer completes). */ public static final int STATUS_LENGTH_REQUIRED = 411; /** - * This transfer was interrupted and cannot be resumed. This is the code for - * the OBEX error "Precondition Failed", and it is also used in situations - * where the client doesn't have an ETag at all. + * This transfer was interrupted and cannot be resumed. This is the code for the OBEX error + * "Precondition Failed", and it is also used in situations where the client doesn't have an + * ETag at all. */ public static final int STATUS_PRECONDITION_FAILED = 412; - /** - * This transfer was canceled - */ + /** This transfer was canceled */ public static final int STATUS_CANCELED = 490; /** - * This transfer has completed with an error. Warning: there will be other - * status values that indicate errors in the future. Use isStatusError() to - * capture the entire category. + * This transfer has completed with an error. Warning: there will be other status values that + * indicate errors in the future. Use isStatusError() to capture the entire category. */ public static final int STATUS_UNKNOWN_ERROR = 491; /** - * This transfer couldn't be completed because of a storage issue. - * Typically, that's because the file system is missing or full. + * This transfer couldn't be completed because of a storage issue. Typically, that's because the + * file system is missing or full. */ public static final int STATUS_FILE_ERROR = 492; - /** - * This transfer couldn't be completed because of no sdcard. - */ + /** This transfer couldn't be completed because of no sdcard. */ public static final int STATUS_ERROR_NO_SDCARD = 493; - /** - * This transfer couldn't be completed because of sdcard full. - */ + /** This transfer couldn't be completed because of sdcard full. */ public static final int STATUS_ERROR_SDCARD_FULL = 494; - /** - * This transfer couldn't be completed because of an unspecified un-handled - * OBEX code. - */ + /** This transfer couldn't be completed because of an unspecified un-handled OBEX code. */ public static final int STATUS_UNHANDLED_OBEX_CODE = 495; /** - * This transfer couldn't be completed because of an error receiving or - * processing data at the OBEX level. + * This transfer couldn't be completed because of an error receiving or processing data at the + * OBEX level. */ public static final int STATUS_OBEX_DATA_ERROR = 496; - /** - * This transfer couldn't be completed because of an error when establishing - * connection. - */ + /** This transfer couldn't be completed because of an error when establishing connection. */ public static final int STATUS_CONNECTION_ERROR = 497; - } diff --git a/android/app/src/com/android/bluetooth/opp/Constants.java b/android/app/src/com/android/bluetooth/opp/Constants.java index c559628f720..d19162e46e2 100644 --- a/android/app/src/com/android/bluetooth/opp/Constants.java +++ b/android/app/src/com/android/bluetooth/opp/Constants.java @@ -56,11 +56,11 @@ public class Constants { /** the permission required for others to send us handover broadcasts */ static final String PERMISSION_ALLOWLIST_BLUETOOTH_DEVICE = - "com.android.permission.ALLOWLIST_BLUETOOTH_DEVICE"; + "com.android.permission.ALLOWLIST_BLUETOOTH_DEVICE"; /** - * The intent that gets sent when the service must wake up for a retry - * Note: Only retry Outbound transfers + * The intent that gets sent when the service must wake up for a retry Note: Only retry Outbound + * transfers */ static final String ACTION_RETRY = "android.btopp.intent.action.RETRY"; @@ -95,7 +95,7 @@ public class Constants { static final String ACTION_HANDOVER_SEND_MULTIPLE = "android.nfc.handover.intent.action.HANDOVER_SEND_MULTIPLE"; - /** the intent that is used for indicating an incoming transfer*/ + /** the intent that is used for indicating an incoming transfer */ static final String ACTION_HANDOVER_STARTED = "android.nfc.handover.intent.action.HANDOVER_STARTED"; @@ -186,31 +186,31 @@ public class Constants { static final int MEDIA_SCANNED_SCANNED_FAILED = 2; /** - * The MIME type(s) of we could accept from other device. - * This is in essence a "acceptlist" of acceptable types. - * Today, restricted to images, audio, video and certain text types. + * The MIME type(s) of we could accept from other device. This is in essence a "acceptlist" of + * acceptable types. Today, restricted to images, audio, video and certain text types. */ - static final String[] ACCEPTABLE_SHARE_INBOUND_TYPES = new String[]{ - "image/*", - "video/*", - "audio/*", - "text/x-vcard", - "text/x-vcalendar", - "text/calendar", - "text/plain", - "text/html", - "text/xml", - "application/epub+zip", - "application/zip", - "application/vnd.ms-excel", - "application/msword", - "application/vnd.ms-powerpoint", - "application/pdf", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - "application/vnd.openxmlformats-officedocument.presentationml.presentation", - "application/x-hwp", - }; + static final String[] ACCEPTABLE_SHARE_INBOUND_TYPES = + new String[] { + "image/*", + "video/*", + "audio/*", + "text/x-vcard", + "text/x-vcalendar", + "text/calendar", + "text/plain", + "text/html", + "text/xml", + "application/epub+zip", + "application/zip", + "application/vnd.ms-excel", + "application/msword", + "application/vnd.ms-powerpoint", + "application/pdf", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "application/x-hwp", + }; /** Where we store received files */ static final String DEFAULT_STORE_SUBDIR = "/bluetooth"; @@ -219,11 +219,9 @@ public class Constants { static final int NFC_ALIVE_CHECK_MS = 10000; /** - * To log debug/verbose in OPP, use the command "setprop log.tag.BluetoothOpp DEBUG" or - * "setprop log.tag.BluetoothOpp VERBOSE" and then "adb root" + "adb shell "stop; start"" - **/ - - + * To log debug/verbose in OPP, use the command "setprop log.tag.BluetoothOpp DEBUG" or "setprop + * log.tag.BluetoothOpp VERBOSE" and then "adb root" + "adb shell "stop; start"" + */ static final int MAX_RECORDS_IN_DATABASE = 50; static final int BATCH_STATUS_PENDING = 0; @@ -244,8 +242,9 @@ public class Constants { Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id); ContentValues updateValues = new ContentValues(); updateValues.put(BluetoothShare.STATUS, status); - BluetoothMethodProxy.getInstance().contentResolverUpdate(context.getContentResolver(), - contentUri, updateValues, null, null); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + context.getContentResolver(), contentUri, updateValues, null, null); Constants.sendIntentIfCompleted(context, contentUri, status); } diff --git a/android/app/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java b/android/app/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java index 8691f762f3f..93979d35b3b 100644 --- a/android/app/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java +++ b/android/app/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java @@ -37,9 +37,8 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; /** - * This class tracks the data connection associated with Bluetooth - * reverse tethering. PanService calls it when a reverse tethered - * connection needs to be activated or deactivated. + * This class tracks the data connection associated with Bluetooth reverse tethering. PanService + * calls it when a reverse tethered connection needs to be activated or deactivated. */ public class BluetoothTetheringNetworkFactory extends NetworkFactory { private static final String NETWORK_TYPE = "Bluetooth Tethering"; @@ -52,8 +51,10 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory { // All accesses to these must be synchronized(this). private IIpClient mIpClient; + @GuardedBy("this") private int mIpClientStartIndex = 0; + private String mInterfaceName; private NetworkAgent mNetworkAgent; @@ -85,10 +86,12 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory { } mIpClient = ipClient; try { - mIpClient.startProvisioning(new ProvisioningConfiguration.Builder() - .withoutMultinetworkPolicyTracker() - .withoutIpReachabilityMonitor() - .build().toStableParcelable()); + mIpClient.startProvisioning( + new ProvisioningConfiguration.Builder() + .withoutMultinetworkPolicyTracker() + .withoutIpReachabilityMonitor() + .build() + .toStableParcelable()); } catch (RemoteException e) { Log.e(TAG, "Error starting IpClient provisioning", e); } @@ -133,55 +136,74 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory { // TODO: Figure out how to replace this thread with simple invocations // of IpClient. This will likely necessitate a rethink about // NetworkAgent and associated instance lifetimes. - Thread ipProvisioningThread = new Thread(new Runnable() { - @Override - public void run() { - final WaitForProvisioningCallbacks ipcCallback; - final int ipClientStartIndex; + Thread ipProvisioningThread = + new Thread( + new Runnable() { + @Override + public void run() { + final WaitForProvisioningCallbacks ipcCallback; + final int ipClientStartIndex; - synchronized (BluetoothTetheringNetworkFactory.this) { - if (TextUtils.isEmpty(mInterfaceName)) { - Log.e(TAG, "attempted to reverse tether without interface name"); - return; - } - log("ipProvisioningThread(+" + mInterfaceName + ") start IP provisioning"); - ipcCallback = startIpClientLocked(); - ipClientStartIndex = mIpClientStartIndex; - } + synchronized (BluetoothTetheringNetworkFactory.this) { + if (TextUtils.isEmpty(mInterfaceName)) { + Log.e( + TAG, + "attempted to reverse tether without interface" + + " name"); + return; + } + log( + "ipProvisioningThread(+" + + mInterfaceName + + ") start IP provisioning"); + ipcCallback = startIpClientLocked(); + ipClientStartIndex = mIpClientStartIndex; + } - final LinkProperties linkProperties = ipcCallback.waitForProvisioning(); - if (linkProperties == null) { - Log.e(TAG, "IP provisioning error."); - synchronized (BluetoothTetheringNetworkFactory.this) { - stopIpClientLocked(); - setScoreFilter(-1); - } - return; - } - final NetworkAgentConfig config = new NetworkAgentConfig.Builder() - .setLegacyType(ConnectivityManager.TYPE_BLUETOOTH) - .setLegacyTypeName(NETWORK_TYPE) - .build(); + final LinkProperties linkProperties = + ipcCallback.waitForProvisioning(); + if (linkProperties == null) { + Log.e(TAG, "IP provisioning error."); + synchronized (BluetoothTetheringNetworkFactory.this) { + stopIpClientLocked(); + setScoreFilter(-1); + } + return; + } + final NetworkAgentConfig config = + new NetworkAgentConfig.Builder() + .setLegacyType(ConnectivityManager.TYPE_BLUETOOTH) + .setLegacyTypeName(NETWORK_TYPE) + .build(); - synchronized (BluetoothTetheringNetworkFactory.this) { - // Reverse tethering has been stopped, and stopping won the race : there is - // no point in creating the agent (and it would be leaked), so bail. - if (ipClientStartIndex != mIpClientStartIndex) return; - // Create our NetworkAgent. - mNetworkAgent = - new NetworkAgent(mContext, getLooper(), NETWORK_TYPE, - mNetworkCapabilities, linkProperties, NETWORK_SCORE, - config, getProvider()) { - @Override - public void onNetworkUnwanted() { - BluetoothTetheringNetworkFactory.this.onCancelRequest(); + synchronized (BluetoothTetheringNetworkFactory.this) { + // Reverse tethering has been stopped, and stopping won the race + // : there is + // no point in creating the agent (and it would be leaked), so + // bail. + if (ipClientStartIndex != mIpClientStartIndex) return; + // Create our NetworkAgent. + mNetworkAgent = + new NetworkAgent( + mContext, + getLooper(), + NETWORK_TYPE, + mNetworkCapabilities, + linkProperties, + NETWORK_SCORE, + config, + getProvider()) { + @Override + public void onNetworkUnwanted() { + BluetoothTetheringNetworkFactory.this + .onCancelRequest(); + } + }; + mNetworkAgent.register(); + mNetworkAgent.markConnected(); } - }; - mNetworkAgent.register(); - mNetworkAgent.markConnected(); - } - } - }); + } + }); ipProvisioningThread.start(); } @@ -243,17 +265,18 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory { } private NetworkCapabilities initNetworkCapabilities() { - final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH) - .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) - // Bluetooth v3 and v4 go up to 24 Mbps. - // TODO: Adjust this to actual connection bandwidth. - .setLinkUpstreamBandwidthKbps(24 * 1000) - .setLinkDownstreamBandwidthKbps(24 * 1000); + final NetworkCapabilities.Builder builder = + new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH) + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) + // Bluetooth v3 and v4 go up to 24 Mbps. + // TODO: Adjust this to actual connection bandwidth. + .setLinkUpstreamBandwidthKbps(24 * 1000) + .setLinkDownstreamBandwidthKbps(24 * 1000); return builder.build(); } } diff --git a/android/app/src/com/android/bluetooth/pan/PanService.java b/android/app/src/com/android/bluetooth/pan/PanService.java index 5967021f82f..418df87936e 100644 --- a/android/app/src/com/android/bluetooth/pan/PanService.java +++ b/android/app/src/com/android/bluetooth/pan/PanService.java @@ -58,28 +58,22 @@ import java.util.List; import java.util.Map; import java.util.Objects; -/** - * Provides Bluetooth Pan Device profile, as a service in - * the Bluetooth application. - */ +/** Provides Bluetooth Pan Device profile, as a service in the Bluetooth application. */ public class PanService extends ProfileService { private static final String TAG = PanService.class.getSimpleName(); private static PanService sPanService; private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5; - @VisibleForTesting - HashMap mPanDevices; + @VisibleForTesting HashMap mPanDevices; private int mMaxPanDevices; private String mPanIfName; - @VisibleForTesting - boolean mIsTethering = false; + @VisibleForTesting boolean mIsTethering = false; private HashMap mBluetoothTetheringCallbacks; private TetheringManager mTetheringManager; private DatabaseManager mDatabaseManager; - @VisibleForTesting - UserManager mUserManager; + @VisibleForTesting UserManager mUserManager; private static final int MESSAGE_CONNECT = 1; private static final int MESSAGE_DISCONNECT = 2; @@ -143,10 +137,14 @@ public class PanService extends ProfileService { @Override public void start() { - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when PanService starts"); - mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), - "DatabaseManager cannot be null when PanService starts"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when PanService starts"); + mDatabaseManager = + Objects.requireNonNull( + AdapterService.getAdapterService().getDatabase(), + "DatabaseManager cannot be null when PanService starts"); mNativeInterface = Objects.requireNonNull( PanNativeInterface.getInstance(), @@ -155,8 +153,9 @@ public class PanService extends ProfileService { mBluetoothTetheringCallbacks = new HashMap<>(); mPanDevices = new HashMap(); try { - mMaxPanDevices = getResources().getInteger( - com.android.bluetooth.R.integer.config_max_pan_devices); + mMaxPanDevices = + getResources() + .getInteger(com.android.bluetooth.R.integer.config_max_pan_devices); } catch (NotFoundException e) { mMaxPanDevices = BLUETOOTH_MAX_PAN_CONNECTIONS; } @@ -193,17 +192,22 @@ public class PanService extends ProfileService { mUserManager = null; if (mPanDevices != null) { - int[] desiredStates = {BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTING}; - List devList = - getDevicesMatchingConnectionStates(desiredStates); - for (BluetoothDevice device : devList) { + int[] desiredStates = { + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTING + }; + List devList = getDevicesMatchingConnectionStates(desiredStates); + for (BluetoothDevice device : devList) { BluetoothPanDevice panDevice = mPanDevices.get(device); Log.d(TAG, "panDevice: " + panDevice + " device address: " + device); if (panDevice != null) { - handlePanDeviceStateChange(device, mPanIfName, - BluetoothProfile.STATE_DISCONNECTED, - panDevice.mLocalRole, panDevice.mRemoteRole); + handlePanDeviceStateChange( + device, + mPanIfName, + BluetoothProfile.STATE_DISCONNECTED, + panDevice.mLocalRole, + panDevice.mRemoteRole); } } mPanDevices.clear(); @@ -284,12 +288,9 @@ public class PanService extends ProfileService { } }; - /** - * Handlers for incoming service calls - */ + /** Handlers for incoming service calls */ @VisibleForTesting - static class BluetoothPanBinder extends IBluetoothPan.Stub - implements IProfileServiceBinder { + static class BluetoothPanBinder extends IBluetoothPan.Stub implements IProfileServiceBinder { private PanService mService; BluetoothPanBinder(PanService svc) { @@ -442,17 +443,17 @@ public class PanService extends ProfileService { return mTetherOn; } - @RequiresPermission(allOf = { - android.Manifest.permission.BLUETOOTH_PRIVILEGED, - android.Manifest.permission.TETHER_PRIVILEGED, - }) - void setBluetoothTethering(IBluetoothPanCallback callback, int id, int callerUid, - boolean value) { + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + android.Manifest.permission.TETHER_PRIVILEGED, + }) + void setBluetoothTethering( + IBluetoothPanCallback callback, int id, int callerUid, boolean value) { Log.d(TAG, "setBluetoothTethering: " + value + ", mTetherOn: " + mTetherOn); enforceCallingOrSelfPermission( BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); - enforceCallingOrSelfPermission( - TETHER_PRIVILEGED, "Need TETHER_PRIVILEGED permission"); + enforceCallingOrSelfPermission(TETHER_PRIVILEGED, "Need TETHER_PRIVILEGED permission"); UserManager um = getSystemService(UserManager.class); if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING) && value) { @@ -478,29 +479,29 @@ public class PanService extends ProfileService { } } if (mTetherOn != value) { - //drop any existing panu or pan-nap connection when changing the tethering state + // drop any existing panu or pan-nap connection when changing the tethering state mTetherOn = value; List devList = getConnectedDevices(); for (BluetoothDevice dev : devList) { disconnect(dev); } Intent intent = new Intent(BluetoothPan.ACTION_TETHERING_STATE_CHANGED); - intent.putExtra(BluetoothPan.EXTRA_TETHERING_STATE, + intent.putExtra( + BluetoothPan.EXTRA_TETHERING_STATE, mTetherOn ? BluetoothPan.TETHERING_STATE_ON : BluetoothPan.TETHERING_STATE_OFF); sendBroadcast(intent, null, Utils.getTempBroadcastOptions().toBundle()); } } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -512,8 +513,8 @@ public class PanService extends ProfileService { BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.PAN, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.PAN, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -527,17 +528,15 @@ public class PanService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ public int getConnectionPolicy(BluetoothDevice device) { - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.PAN); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.PAN); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) @@ -545,7 +544,7 @@ public class PanService extends ProfileService { enforceCallingOrSelfPermission( BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); List devices = - getDevicesMatchingConnectionStates(new int[]{BluetoothProfile.STATE_CONNECTED}); + getDevicesMatchingConnectionStates(new int[] {BluetoothProfile.STATE_CONNECTED}); return devices; } @@ -581,10 +580,16 @@ public class PanService extends ProfileService { public int remote_role; } - void onConnectStateChanged(byte[] address, int state, int error, int localRole, - int remoteRole) { - Log.d(TAG, "onConnectStateChanged: " + state + ", local role:" + localRole - + ", remoteRole: " + remoteRole); + void onConnectStateChanged( + byte[] address, int state, int error, int localRole, int remoteRole) { + Log.d( + TAG, + "onConnectStateChanged: " + + state + + ", local role:" + + localRole + + ", remoteRole: " + + remoteRole); Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_STATE_CHANGED); msg.obj = new ConnectState(address, state, error, localRole, remoteRole); mHandler.sendMessage(msg); @@ -592,19 +597,30 @@ public class PanService extends ProfileService { @VisibleForTesting void onControlStateChanged(int localRole, int state, int error, String ifname) { - Log.d(TAG, "onControlStateChanged: " + state + ", error: " + error + ", ifname: " - + ifname); + Log.d(TAG, "onControlStateChanged: " + state + ", error: " + error + ", ifname: " + ifname); if (error == 0) { mPanIfName = ifname; } } - - void handlePanDeviceStateChange(BluetoothDevice device, String iface, int state, - @LocalPanRole int localRole, @RemotePanRole int remoteRole) { - Log.d(TAG, "handlePanDeviceStateChange: device: " + device + ", iface: " + iface - + ", state: " + state + ", localRole:" + localRole + ", remoteRole:" - + remoteRole); + void handlePanDeviceStateChange( + BluetoothDevice device, + String iface, + int state, + @LocalPanRole int localRole, + @RemotePanRole int remoteRole) { + Log.d( + TAG, + "handlePanDeviceStateChange: device: " + + device + + ", iface: " + + iface + + ", state: " + + state + + ", localRole:" + + localRole + + ", remoteRole:" + + remoteRole); int prevState; BluetoothPanDevice panDevice = mPanDevices.get(device); @@ -639,8 +655,10 @@ public class PanService extends ProfileService { if (remoteRole == BluetoothPan.LOCAL_PANU_ROLE) { if (state == BluetoothProfile.STATE_CONNECTED) { if ((!mTetherOn) || (localRole == BluetoothPan.LOCAL_PANU_ROLE)) { - Log.d(TAG, "handlePanDeviceStateChange BT tethering is off/Local role" - + " is PANU drop the connection"); + Log.d( + TAG, + "handlePanDeviceStateChange BT tethering is off/Local role" + + " is PANU drop the connection"); mPanDevices.remove(device); mNativeInterface.disconnect(Utils.getByteAddress(device)); return; @@ -658,8 +676,10 @@ public class PanService extends ProfileService { } } else if (state == BluetoothProfile.STATE_DISCONNECTED) { mPanDevices.remove(device); - Log.i(TAG, "remote(PANU) is disconnected, Remaining connected PANU devices: " - + mPanDevices.size()); + Log.i( + TAG, + "remote(PANU) is disconnected, Remaining connected PANU devices: " + + mPanDevices.size()); if (mIsTethering && mPanDevices.size() == 0) { try { for (IBluetoothPanCallback cb : mBluetoothTetheringCallbacks.values()) { @@ -674,11 +694,16 @@ public class PanService extends ProfileService { } else if (mStarted) { // PANU Role = reverse Tether - Log.d(TAG, "handlePanDeviceStateChange LOCAL_PANU_ROLE:REMOTE_NAP_ROLE state = " + state - + ", prevState = " + prevState); + Log.d( + TAG, + "handlePanDeviceStateChange LOCAL_PANU_ROLE:REMOTE_NAP_ROLE state = " + + state + + ", prevState = " + + prevState); if (state == BluetoothProfile.STATE_CONNECTED) { - mNetworkFactory = new BluetoothTetheringNetworkFactory( - getBaseContext(), getMainLooper(), this); + mNetworkFactory = + new BluetoothTetheringNetworkFactory( + getBaseContext(), getMainLooper(), this); mNetworkFactory.startReverseTether(iface); } else if (state == BluetoothProfile.STATE_DISCONNECTED) { if (mNetworkFactory != null) { @@ -696,8 +721,8 @@ public class PanService extends ProfileService { device, BluetoothProfile.PAN, state, prevState); /* Notifying the connection state change of the profile before sending the intent for - connection state change, as it was causing a race condition, with the UI not being - updated with the correct connection state. */ + connection state change, as it was causing a race condition, with the UI not being + updated with the correct connection state. */ Log.d(TAG, "Pan Device state : device: " + device + " State:" + prevState + "->" + state); Intent intent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java index 7f15266f861..0d49e8f09d1 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java @@ -54,11 +54,9 @@ public class BluetoothPbapActivity extends AlertActivity implements Preference.OnPreferenceChangeListener, TextWatcher { private static final String TAG = "BluetoothPbapActivity"; - private static final int BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH = 16; - @VisibleForTesting - static final int DIALOG_YES_NO_AUTH = 1; + @VisibleForTesting static final int DIALOG_YES_NO_AUTH = 1; private static final String KEY_USER_TIMEOUT = "user_timeout"; @@ -70,8 +68,7 @@ public class BluetoothPbapActivity extends AlertActivity private String mSessionKey = ""; - @VisibleForTesting - int mCurrentDialog; + @VisibleForTesting int mCurrentDialog; private boolean mTimeout = false; @@ -82,15 +79,17 @@ public class BluetoothPbapActivity extends AlertActivity private BluetoothDevice mDevice; @VisibleForTesting - BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (!BluetoothPbapService.USER_CONFIRM_TIMEOUT_ACTION.equals(intent.getAction())) { - return; - } - onTimeout(); - } - }; + BroadcastReceiver mReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!BluetoothPbapService.USER_CONFIRM_TIMEOUT_ACTION.equals( + intent.getAction())) { + return; + } + onTimeout(); + } + }; @Override protected void onCreate(Bundle savedInstanceState) { @@ -125,10 +124,10 @@ public class BluetoothPbapActivity extends AlertActivity case DIALOG_YES_NO_AUTH: mAlertBuilder.setTitle(getString(R.string.pbap_session_key_dialog_header)); mAlertBuilder.setView(createView(DIALOG_YES_NO_AUTH)); - mAlertBuilder.setPositiveButton(android.R.string.ok, - (dialog, which) -> onPositive()); - mAlertBuilder.setNegativeButton(android.R.string.cancel, - (dialog, which) -> onNegative()); + mAlertBuilder.setPositiveButton( + android.R.string.ok, (dialog, which) -> onPositive()); + mAlertBuilder.setNegativeButton( + android.R.string.cancel, (dialog, which) -> onNegative()); setupAlert(); changeButtonEnabled(DialogInterface.BUTTON_POSITIVE, false); break; @@ -155,9 +154,8 @@ public class BluetoothPbapActivity extends AlertActivity mMessageView.setText(createDisplayText(id)); mKeyView = (EditText) mView.findViewById(R.id.text); mKeyView.addTextChangedListener(this); - mKeyView.setFilters(new InputFilter[]{ - new LengthFilter(BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH) - }); + mKeyView.setFilters( + new InputFilter[] {new LengthFilter(BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH)}); return mView; default: return null; @@ -172,8 +170,10 @@ public class BluetoothPbapActivity extends AlertActivity if (!mTimeout) { if (mCurrentDialog == DIALOG_YES_NO_AUTH) { - sendIntentToReceiver(BluetoothPbapService.AUTH_RESPONSE_ACTION, - BluetoothPbapService.EXTRA_SESSION_KEY, mSessionKey); + sendIntentToReceiver( + BluetoothPbapService.AUTH_RESPONSE_ACTION, + BluetoothPbapService.EXTRA_SESSION_KEY, + mSessionKey); mKeyView.removeTextChangedListener(this); } } @@ -190,8 +190,8 @@ public class BluetoothPbapActivity extends AlertActivity finish(); } - private void sendIntentToReceiver(final String intentName, final String extraName, - final String extraValue) { + private void sendIntentToReceiver( + final String intentName, final String extraName, final String extraValue) { Intent intent = new Intent(intentName); intent.setPackage(getPackageName()); intent.putExtra(BluetoothPbapService.EXTRA_DEVICE, mDevice); @@ -246,12 +246,10 @@ public class BluetoothPbapActivity extends AlertActivity } @Override - public void beforeTextChanged(CharSequence s, int start, int before, int after) { - } + public void beforeTextChanged(CharSequence s, int start, int before, int after) {} @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } + public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(android.text.Editable s) { @@ -260,17 +258,18 @@ public class BluetoothPbapActivity extends AlertActivity } } - private final Handler mTimeoutHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case DISMISS_TIMEOUT_DIALOG: - Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg."); - finish(); - break; - default: - break; - } - } - }; + private final Handler mTimeoutHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case DISMISS_TIMEOUT_DIALOG: + Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg."); + finish(); + break; + default: + break; + } + } + }; } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java index 3e98bf4aaa9..3bd52969869 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java @@ -61,7 +61,8 @@ public class BluetoothPbapAuthenticator implements Authenticator { private void waitUserConfirmation() { mPbapStateMachine.sendMessage(PbapStateMachine.CREATE_NOTIFICATION); - mPbapStateMachine.sendMessageDelayed(PbapStateMachine.REMOVE_NOTIFICATION, + mPbapStateMachine.sendMessageDelayed( + PbapStateMachine.REMOVE_NOTIFICATION, BluetoothPbapService.USER_CONFIRM_TIMEOUT_VALUE); synchronized (this) { while (!mChallenged && !mAuthCancelled) { @@ -81,8 +82,8 @@ public class BluetoothPbapAuthenticator implements Authenticator { } @Override - public PasswordAuthentication onAuthenticationChallenge(final String description, - final boolean isUserIdRequired, final boolean isFullAccess) { + public PasswordAuthentication onAuthenticationChallenge( + final String description, final boolean isUserIdRequired, final boolean isFullAccess) { waitUserConfirmation(); if (mSessionKey.trim().length() != 0) { return new PasswordAuthentication(null, mSessionKey.getBytes()); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java index b60f1a38c17..47d26ab15c9 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java @@ -61,19 +61,20 @@ public class BluetoothPbapCallLogComposer { static final String FAILURE_REASON_UNSUPPORTED_URI = "The Uri vCard composer received is not supported by the composer."; - @VisibleForTesting - static final String NO_ERROR = "No error"; + @VisibleForTesting static final String NO_ERROR = "No error"; /** The projection to use when querying the call log table */ - private static final String[] sCallLogProjection = new String[]{ - Calls.NUMBER, - Calls.DATE, - Calls.TYPE, - Calls.CACHED_NAME, - Calls.CACHED_NUMBER_TYPE, - Calls.CACHED_NUMBER_LABEL, - Calls.NUMBER_PRESENTATION - }; + private static final String[] sCallLogProjection = + new String[] { + Calls.NUMBER, + Calls.DATE, + Calls.TYPE, + Calls.CACHED_NAME, + Calls.CACHED_NUMBER_TYPE, + Calls.CACHED_NUMBER_LABEL, + Calls.NUMBER_PRESENTATION + }; + private static final int NUMBER_COLUMN_INDEX = 0; private static final int DATE_COLUMN_INDEX = 1; private static final int CALL_TYPE_COLUMN_INDEX = 2; @@ -101,7 +102,10 @@ public class BluetoothPbapCallLogComposer { mContext = context; } - public boolean init(final Uri contentUri, final String selection, final String[] selectionArgs, + public boolean init( + final Uri contentUri, + final String selection, + final String[] selectionArgs, final String sortOrder) { final String[] projection; if (CallLog.Calls.CONTENT_URI.equals(contentUri)) { @@ -111,9 +115,15 @@ public class BluetoothPbapCallLogComposer { return false; } - mCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - mContext.getContentResolver(), contentUri, projection, selection, selectionArgs, - sortOrder); + mCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContext.getContentResolver(), + contentUri, + projection, + selection, + selectionArgs, + sortOrder); if (mCursor == null) { mErrorReason = FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO; @@ -153,9 +163,11 @@ public class BluetoothPbapCallLogComposer { } private String createOneCallLogEntryInternal(boolean vcardVer21) { - final int vcardType = (vcardVer21 ? VCardConfig.VCARD_TYPE_V21_GENERIC - : VCardConfig.VCARD_TYPE_V30_GENERIC) - | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; + final int vcardType = + (vcardVer21 + ? VCardConfig.VCARD_TYPE_V21_GENERIC + : VCardConfig.VCARD_TYPE_V30_GENERIC) + | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; final VCardBuilder builder = new VCardBuilder(vcardType); String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX); String number = mCursor.getString(NUMBER_COLUMN_INDEX); @@ -185,14 +197,14 @@ public class BluetoothPbapCallLogComposer { return builder.toString(); } - /** - * This static function is to compose vCard for phone own number - */ - public static String composeVCardForPhoneOwnNumber(int phonetype, String phoneName, - String phoneNumber, boolean vcardVer21) { - final int vcardType = (vcardVer21 ? VCardConfig.VCARD_TYPE_V21_GENERIC - : VCardConfig.VCARD_TYPE_V30_GENERIC) - | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; + /** This static function is to compose vCard for phone own number */ + public static String composeVCardForPhoneOwnNumber( + int phonetype, String phoneName, String phoneNumber, boolean vcardVer21) { + final int vcardType = + (vcardVer21 + ? VCardConfig.VCARD_TYPE_V21_GENERIC + : VCardConfig.VCARD_TYPE_V30_GENERIC) + | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; final VCardBuilder builder = new VCardBuilder(vcardType); boolean needCharset = false; if (!(VCardUtils.containsOnlyPrintableAscii(phoneName))) { @@ -209,10 +221,7 @@ public class BluetoothPbapCallLogComposer { return builder.toString(); } - /** - * Format according to RFC 2445 DATETIME type. - * The format is: ("%Y%m%dT%H%M%S"). - */ + /** Format according to RFC 2445 DATETIME type. The format is: ("%Y%m%dT%H%M%S"). */ private String toRfc2455Format(final long millSecs) { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(millSecs); @@ -221,8 +230,8 @@ public class BluetoothPbapCallLogComposer { } /** - * Try to append the property line for a call history time stamp field if possible. - * Do nothing if the call log type gotton from the database is invalid. + * Try to append the property line for a call history time stamp field if possible. Do nothing + * if the call log type gotton from the database is invalid. */ private void tryAppendCallHistoryTimeStampField(final VCardBuilder builder) { // Extension for call history as defined in @@ -237,28 +246,32 @@ public class BluetoothPbapCallLogComposer { final String callLogTypeStr; switch (callLogType) { case Calls.REJECTED_TYPE: - case Calls.INCOMING_TYPE: { - callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING; - break; - } - case Calls.OUTGOING_TYPE: { - callLogTypeStr = VCARD_PROPERTY_CALLTYPE_OUTGOING; - break; - } - case Calls.MISSED_TYPE: { - callLogTypeStr = VCARD_PROPERTY_CALLTYPE_MISSED; - break; - } - default: { - Log.w(TAG, "Call log type not correct."); - ContentProfileErrorReportUtils.report( - BluetoothProfile.PBAP, - BluetoothProtoEnums.BLUETOOTH_PBAP_CALL_LOG_COMPOSER, - BluetoothStatsLog - .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, - 1); - return; - } + case Calls.INCOMING_TYPE: + { + callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING; + break; + } + case Calls.OUTGOING_TYPE: + { + callLogTypeStr = VCARD_PROPERTY_CALLTYPE_OUTGOING; + break; + } + case Calls.MISSED_TYPE: + { + callLogTypeStr = VCARD_PROPERTY_CALLTYPE_MISSED; + break; + } + default: + { + Log.w(TAG, "Call log type not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_CALL_LOG_COMPOSER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); + return; + } } final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java index 0ea493b85fe..60d393a254e 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java @@ -58,15 +58,14 @@ public class BluetoothPbapConfig { } } - /** - * If true, owner vcard will be generated from the "Me" profile - */ + /** If true, owner vcard will be generated from the "Me" profile */ public static boolean useProfileForOwnerVcard() { return sUseProfileForOwnerVcard; } /** * If true, include photos in contact information returned to PCE + * * @return */ public static boolean includePhotosInVcard() { diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java index 3e66815f199..19c7b13e420 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java @@ -53,8 +53,6 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String TAG = "BluetoothPbapObexServer"; - - private static final int UUID_LENGTH = 16; public static final long INVALID_VALUE_PARAMETER = -1; @@ -64,102 +62,89 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // 128 bit UUID for PBAP @VisibleForTesting - public static final byte[] PBAP_TARGET = new byte[]{ - 0x79, - 0x61, - 0x35, - (byte) 0xf0, - (byte) 0xf0, - (byte) 0xc5, - 0x11, - (byte) 0xd8, - 0x09, - 0x66, - 0x08, - 0x00, - 0x20, - 0x0c, - (byte) 0x9a, - 0x66 - }; + public static final byte[] PBAP_TARGET = + new byte[] { + 0x79, + 0x61, + 0x35, + (byte) 0xf0, + (byte) 0xf0, + (byte) 0xc5, + 0x11, + (byte) 0xd8, + 0x09, + 0x66, + 0x08, + 0x00, + 0x20, + 0x0c, + (byte) 0x9a, + 0x66 + }; private static final String[] LEGAL_PATH = { - "/telecom", - "/telecom/pb", - "/telecom/fav", - "/telecom/ich", - "/telecom/och", - "/telecom/mch", - "/telecom/cch", + "/telecom", + "/telecom/pb", + "/telecom/fav", + "/telecom/ich", + "/telecom/och", + "/telecom/mch", + "/telecom/cch", }; // SIM card is only supported when SIM feature is enabled // (i.e. when the property bluetooth.profile.pbap.sim.enabled is set to true) private static final String[] LEGAL_PATH_WITH_SIM = { - "/telecom", - "/telecom/pb", - "/telecom/fav", - "/telecom/ich", - "/telecom/och", - "/telecom/mch", - "/telecom/cch", - "/SIM1", - "/SIM1/telecom", - "/SIM1/telecom/ich", - "/SIM1/telecom/och", - "/SIM1/telecom/mch", - "/SIM1/telecom/cch", - "/SIM1/telecom/pb" + "/telecom", + "/telecom/pb", + "/telecom/fav", + "/telecom/ich", + "/telecom/och", + "/telecom/mch", + "/telecom/cch", + "/SIM1", + "/SIM1/telecom", + "/SIM1/telecom/ich", + "/SIM1/telecom/och", + "/SIM1/telecom/mch", + "/SIM1/telecom/cch", + "/SIM1/telecom/pb" }; // SIM card - @VisibleForTesting - public static final String SIM1 = "SIM1"; + @VisibleForTesting public static final String SIM1 = "SIM1"; // missed call history - @VisibleForTesting - public static final String MCH = "mch"; + @VisibleForTesting public static final String MCH = "mch"; // incoming call history - @VisibleForTesting - public static final String ICH = "ich"; + @VisibleForTesting public static final String ICH = "ich"; // outgoing call history - @VisibleForTesting - public static final String OCH = "och"; + @VisibleForTesting public static final String OCH = "och"; // combined call history - @VisibleForTesting - public static final String CCH = "cch"; + @VisibleForTesting public static final String CCH = "cch"; // phone book - @VisibleForTesting - public static final String PB = "pb"; + @VisibleForTesting public static final String PB = "pb"; // favorites - @VisibleForTesting - public static final String FAV = "fav"; + @VisibleForTesting public static final String FAV = "fav"; - @VisibleForTesting - public static final String TELECOM_PATH = "/telecom"; + @VisibleForTesting public static final String TELECOM_PATH = "/telecom"; - @VisibleForTesting - public static final String ICH_PATH = "/telecom/ich"; + @VisibleForTesting public static final String ICH_PATH = "/telecom/ich"; - @VisibleForTesting - public static final String OCH_PATH = "/telecom/och"; + @VisibleForTesting public static final String OCH_PATH = "/telecom/och"; - @VisibleForTesting - public static final String MCH_PATH = "/telecom/mch"; + @VisibleForTesting public static final String MCH_PATH = "/telecom/mch"; - @VisibleForTesting - public static final String CCH_PATH = "/telecom/cch"; + @VisibleForTesting public static final String CCH_PATH = "/telecom/cch"; - @VisibleForTesting - public static final String PB_PATH = "/telecom/pb"; + @VisibleForTesting public static final String PB_PATH = "/telecom/pb"; - @VisibleForTesting - public static final String FAV_PATH = "/telecom/fav"; + @VisibleForTesting public static final String FAV_PATH = "/telecom/fav"; // SIM Support private static final String SIM_PATH = "/SIM1/telecom"; @@ -175,19 +160,16 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String SIM_PB_PATH = "/SIM1/telecom/pb"; // type for list vcard objects - @VisibleForTesting - public static final String TYPE_LISTING = "x-bt/vcard-listing"; + @VisibleForTesting public static final String TYPE_LISTING = "x-bt/vcard-listing"; // type for get single vcard object - @VisibleForTesting - public static final String TYPE_VCARD = "x-bt/vcard"; + @VisibleForTesting public static final String TYPE_VCARD = "x-bt/vcard"; // to indicate if need send body besides headers private static final int NEED_SEND_BODY = -1; // type for download all vcard objects - @VisibleForTesting - public static final String TYPE_PB = "x-bt/phonebook"; + @VisibleForTesting public static final String TYPE_PB = "x-bt/phonebook"; // The number of indexes in the phone book. private boolean mNeedPhonebookSize = false; @@ -234,7 +216,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private BluetoothMethodProxy mPbapMethodProxy; private enum ContactsType { - TYPE_PHONEBOOK , TYPE_SIM ; + TYPE_PHONEBOOK, + TYPE_SIM; } public static class ContentType { @@ -253,8 +236,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { public static final int SIM_PHONEBOOK = 7; } - public BluetoothPbapObexServer(Handler callback, Context context, - PbapStateMachine stateMachine) { + public BluetoothPbapObexServer( + Handler callback, Context context, PbapStateMachine stateMachine) { super(); mCallback = callback; mContext = context; @@ -376,7 +359,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } @Override - public int onSetPath(final HeaderSet request, final HeaderSet reply, final boolean backup, + public int onSetPath( + final HeaderSet request, + final HeaderSet reply, + final boolean backup, final boolean create) { logHeader(request); Log.d(TAG, "before setPath, mCurrentPath == " + mCurrentPath); @@ -456,8 +442,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { request = op.getReceivedHeader(); type = (String) mPbapMethodProxy.getHeader(request, HeaderSet.TYPE); name = (String) mPbapMethodProxy.getHeader(request, HeaderSet.NAME); - appParam = (byte[]) mPbapMethodProxy.getHeader( - request, HeaderSet.APPLICATION_PARAMETER); + appParam = + (byte[]) mPbapMethodProxy.getHeader(request, HeaderSet.APPLICATION_PARAMETER); } catch (IOException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, @@ -503,9 +489,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { boolean isSimEnabled = BluetoothPbapService.isSimEnabled(); if (!validName || (validName && type.equals(TYPE_VCARD))) { - Log.d( - TAG, - "Guess what carkit actually want from current path (" + mCurrentPath + ")"); + Log.d(TAG, "Guess what carkit actually want from current path (" + mCurrentPath + ")"); if (mCurrentPath.equals(PB_PATH)) { appParamValue.needTag = ContentType.PHONEBOOK; @@ -553,8 +537,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // we have weak name checking here to provide better // compatibility with other devices,although unique name such as // "pb.vcf" is required by SIG spec. - if (mVcardSimManager.isSimPhoneBook(name, type, PB, SIM1, - TYPE_PB, TYPE_LISTING, mCurrentPath)) { + if (mVcardSimManager.isSimPhoneBook( + name, type, PB, SIM1, TYPE_PB, TYPE_LISTING, mCurrentPath)) { appParamValue.needTag = ContentType.SIM_PHONEBOOK; Log.d(TAG, "download SIM phonebook request"); if (!isSimEnabled) { @@ -660,8 +644,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (str.length() == 0) { return true; } - String[] legal_paths = BluetoothPbapService.isSimEnabled() - ? LEGAL_PATH_WITH_SIM : LEGAL_PATH; + String[] legal_paths = + BluetoothPbapService.isSimEnabled() ? LEGAL_PATH_WITH_SIM : LEGAL_PATH; for (int i = 0; i < legal_paths.length; i++) { if (str.equals(legal_paths[i])) { @@ -713,21 +697,35 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { order = ""; needTag = 0x00; vcard21 = true; - //Filter is not set by default + // Filter is not set by default ignorefilter = true; vCardSelectorOperator = "0"; - propertySelector = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - vCardSelector = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - supportedFeature = new byte[]{0x00, 0x00, 0x00, 0x00}; + propertySelector = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + vCardSelector = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + supportedFeature = new byte[] {0x00, 0x00, 0x00, 0x00}; } @Override public String toString() { - return "AppParamValue"; + return "AppParamValue"; } } @@ -850,8 +848,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } /** Form and Send an XML format String to client for Phone book listing */ - private int sendVcardListingXml(AppParamValue appParamValue, Operation op, int needSendBody, - int size) { + private int sendVcardListingXml( + AppParamValue appParamValue, Operation op, int needSendBody, int size) { StringBuilder result = new StringBuilder(); int itemsFound = 0; result.append(""); @@ -867,33 +865,50 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { type = "number"; } if (type.length() > 0) { - itemsFound = createList(appParamValue, needSendBody, size, result, type, - ContactsType.TYPE_PHONEBOOK); + itemsFound = + createList( + appParamValue, + needSendBody, + size, + result, + type, + ContactsType.TYPE_PHONEBOOK); } else { return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } - // SIM Phonebook listing Request + // SIM Phonebook listing Request } else if (appParamValue.needTag == ContentType.SIM_PHONEBOOK) { type = mVcardSimManager.getType(appParamValue.searchAttr); if (type.length() > 0) { - itemsFound = createList(appParamValue, needSendBody, size, result, type, - ContactsType.TYPE_SIM); + itemsFound = + createList( + appParamValue, + needSendBody, + size, + result, + type, + ContactsType.TYPE_SIM); } else { return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } - // Call history listing request + // Call history listing request } else { ArrayList nameList = mVcardManager.loadCallHistoryList(appParamValue.needTag); int requestSize = - nameList.size() >= appParamValue.maxListCount ? appParamValue.maxListCount + nameList.size() >= appParamValue.maxListCount + ? appParamValue.maxListCount : nameList.size(); int startPoint = appParamValue.listStartOffset; int endPoint = startPoint + requestSize; if (endPoint > nameList.size()) { endPoint = nameList.size(); } - Log.d(TAG, "call log list, size=" + requestSize + " offset=" - + appParamValue.listStartOffset); + Log.d( + TAG, + "call log list, size=" + + requestSize + + " offset=" + + appParamValue.listStartOffset); for (int j = startPoint; j < endPoint; j++) { writeVCardEntry(j + 1, nameList.get(j), result); @@ -906,44 +921,63 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pushBytes(op, result.toString()); } - private int createList(AppParamValue appParamValue, int needSendBody, int size, - StringBuilder result, String type, ContactsType contactType) { + private int createList( + AppParamValue appParamValue, + int needSendBody, + int size, + StringBuilder result, + String type, + ContactsType contactType) { int itemsFound = 0; ArrayList nameList = null; if (mVcardSelector) { if (contactType == ContactsType.TYPE_PHONEBOOK) { - nameList = mVcardManager.getSelectedPhonebookNameList(mOrderBy, - appParamValue.vcard21, needSendBody, size, appParamValue.vCardSelector, - appParamValue.vCardSelectorOperator); - } else if(contactType == ContactsType.TYPE_SIM) { + nameList = + mVcardManager.getSelectedPhonebookNameList( + mOrderBy, + appParamValue.vcard21, + needSendBody, + size, + appParamValue.vCardSelector, + appParamValue.vCardSelectorOperator); + } else if (contactType == ContactsType.TYPE_SIM) { nameList = mVcardSimManager.getSIMPhonebookNameList(mOrderBy); } } else { if (contactType == ContactsType.TYPE_PHONEBOOK) { nameList = mVcardManager.getPhonebookNameList(mOrderBy); - } else if( contactType == ContactsType.TYPE_SIM) { + } else if (contactType == ContactsType.TYPE_SIM) { nameList = mVcardSimManager.getSIMPhonebookNameList(mOrderBy); } } final int requestSize = - nameList.size() >= appParamValue.maxListCount ? appParamValue.maxListCount + nameList.size() >= appParamValue.maxListCount + ? appParamValue.maxListCount : nameList.size(); final int listSize = nameList.size(); String compareValue = "", currentValue; - Log.d(TAG, "search by " + type + ", requestSize=" + requestSize + " offset=" - + appParamValue.listStartOffset + " searchValue=" + appParamValue.searchValue); + Log.d( + TAG, + "search by " + + type + + ", requestSize=" + + requestSize + + " offset=" + + appParamValue.listStartOffset + + " searchValue=" + + appParamValue.searchValue); if (type.equals("number")) { ArrayList savedPosList = new ArrayList<>(); ArrayList selectedNameList = new ArrayList(); // query the number, to get the names - ArrayList names = new ArrayList<>(); + ArrayList names = new ArrayList<>(); if (contactType == ContactsType.TYPE_PHONEBOOK) { names = mVcardManager.getContactNamesByNumber(appParamValue.searchValue); - } else if(contactType== ContactsType.TYPE_SIM) { + } else if (contactType == ContactsType.TYPE_SIM) { names = mVcardSimManager.getSIMContactNamesByNumber(appParamValue.searchValue); } if (mOrderBy == ORDER_BY_ALPHABETICAL) Collections.sort(names); @@ -964,7 +998,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } for (int j = appParamValue.listStartOffset; - j < selectedNameList.size() && itemsFound < requestSize; j++) { + j < selectedNameList.size() && itemsFound < requestSize; + j++) { itemsFound++; writeVCardEntry(savedPosList.get(j), selectedNameList.get(j), result); } @@ -986,7 +1021,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (appParamValue.searchValue != null) { if (appParamValue.searchValue.isEmpty() || ((currentValue.toLowerCase()) - .startsWith(compareValue.toLowerCase()))) { + .startsWith(compareValue.toLowerCase()))) { selectedNameList.add(currentValue); savedPosList.add(pos); } @@ -994,7 +1029,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } for (int i = appParamValue.listStartOffset; - i < selectedNameList.size() && itemsFound < requestSize; i++) { + i < selectedNameList.size() && itemsFound < requestSize; + i++) { itemsFound++; writeVCardEntry(savedPosList.get(i), selectedNameList.get(i), result); } @@ -1002,10 +1038,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return itemsFound; } - /** - * Function to send obex header back to client such as get phonebook size - * request - */ + /** Function to send obex header back to client such as get phonebook size request */ @VisibleForTesting static int pushHeader(final Operation op, final HeaderSet reply) { OutputStream outputStream = null; @@ -1064,13 +1097,15 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pushResult; } - private int handleAppParaForResponse(AppParamValue appParamValue, int size, HeaderSet reply, - Operation op, String name) { + private int handleAppParaForResponse( + AppParamValue appParamValue, int size, HeaderSet reply, Operation op, String name) { byte[] misnum = new byte[1]; ApplicationParameter ap = new ApplicationParameter(); boolean needSendCallHistoryVersionCounters = false; - if (isNameMatchTarget(name, MCH) || isNameMatchTarget(name, ICH) || isNameMatchTarget(name, - OCH) || isNameMatchTarget(name, CCH)) { + if (isNameMatchTarget(name, MCH) + || isNameMatchTarget(name, ICH) + || isNameMatchTarget(name, OCH) + || isNameMatchTarget(name, CCH)) { needSendCallHistoryVersionCounters = checkPbapFeatureSupport(mFolderVersionCounterbitMask); } @@ -1090,8 +1125,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { pbsize[0] = (byte) ((size / 256) & 0xff); // HIGH VALUE pbsize[1] = (byte) ((size % 256) & 0xff); // LOW VALUE - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.PHONEBOOKSIZE_TAGID, - ApplicationParameter.TRIPLET_LENGTH.PHONEBOOKSIZE_LENGTH, pbsize); + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.PHONEBOOKSIZE_TAGID, + ApplicationParameter.TRIPLET_LENGTH.PHONEBOOKSIZE_LENGTH, + pbsize); if (mNeedNewMissedCallsNum) { mNeedNewMissedCallsNum = false; @@ -1099,10 +1136,18 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { ContentResolver contentResolver; contentResolver = mContext.getContentResolver(); - Cursor c = contentResolver.query(Calls.CONTENT_URI, null, - Calls.TYPE + " = " + Calls.MISSED_TYPE + " AND " - + android.provider.CallLog.Calls.NEW + " = 1", null, - Calls.DEFAULT_SORT_ORDER); + Cursor c = + contentResolver.query( + Calls.CONTENT_URI, + null, + Calls.TYPE + + " = " + + Calls.MISSED_TYPE + + " AND " + + android.provider.CallLog.Calls.NEW + + " = 1", + null, + Calls.DEFAULT_SORT_ORDER); if (c != null) { nmnum = c.getCount(); @@ -1111,10 +1156,13 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { nmnum = nmnum > 0 ? nmnum : 0; misnum[0] = (byte) nmnum; - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.NEWMISSEDCALLS_TAGID, - ApplicationParameter.TRIPLET_LENGTH.NEWMISSEDCALLS_LENGTH, misnum); - Log.d(TAG, "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " - + nmnum); + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.NEWMISSEDCALLS_TAGID, + ApplicationParameter.TRIPLET_LENGTH.NEWMISSEDCALLS_LENGTH, + misnum); + Log.d( + TAG, + "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); } if (checkPbapFeatureSupport(mDatabaseIdentifierBitMask)) { @@ -1143,10 +1191,18 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { ContentResolver contentResolver; contentResolver = mContext.getContentResolver(); - Cursor c = contentResolver.query(Calls.CONTENT_URI, null, - Calls.TYPE + " = " + Calls.MISSED_TYPE + " AND " - + android.provider.CallLog.Calls.NEW + " = 1", null, - Calls.DEFAULT_SORT_ORDER); + Cursor c = + contentResolver.query( + Calls.CONTENT_URI, + null, + Calls.TYPE + + " = " + + Calls.MISSED_TYPE + + " AND " + + android.provider.CallLog.Calls.NEW + + " = 1", + null, + Calls.DEFAULT_SORT_ORDER); if (c != null) { nmnum = c.getCount(); @@ -1155,14 +1211,14 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { nmnum = nmnum > 0 ? nmnum : 0; misnum[0] = (byte) nmnum; - Log.d(TAG, - "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); + Log.d(TAG, "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.NEWMISSEDCALLS_TAGID, - ApplicationParameter.TRIPLET_LENGTH.NEWMISSEDCALLS_LENGTH, misnum); + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.NEWMISSEDCALLS_TAGID, + ApplicationParameter.TRIPLET_LENGTH.NEWMISSEDCALLS_LENGTH, + misnum); reply.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getHeader()); - Log.d(TAG, - "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); + Log.d(TAG, "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); // Only Specifies the headers, not write for now, will write to PCE // together with Body @@ -1271,8 +1327,9 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (TextUtils.isEmpty(orderPara)) { // If order parameter is not set by PCE, set default value per spec. orderPara = "0"; - Log.d(TAG, "Order parameter is not set by PCE. " - + "Assume order by 'Indexed' by default"); + Log.d( + TAG, + "Order parameter is not set by PCE. " + "Assume order by 'Indexed' by default"); } else if (!orderPara.equals("0") && !orderPara.equals("1")) { Log.d(TAG, "Order parameter is not supported: " + appParamValue.order); if (orderPara.equals("2")) { @@ -1349,8 +1406,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_NOT_FOUND; } else if ((intIndex == 0) && (appParamValue.needTag == ContentType.PHONEBOOK)) { // For PB_PATH, 0.vcf is the phone number of this phone. - String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, - appParamValue.ignorefilter ? null : appParamValue.propertySelector); + String ownerVcard = + mVcardManager.getOwnerPhoneNumberVcard( + vcard21, + appParamValue.ignorefilter ? null : appParamValue.propertySelector); return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookOneVcard( @@ -1373,8 +1432,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_NOT_FOUND; } else if (intIndex == 0) { // For PB_PATH, 0.vcf is the phone number of this phone. - String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, - appParamValue.ignorefilter ? null : appParamValue.propertySelector); + String ownerVcard = + mVcardManager.getOwnerPhoneNumberVcard( + vcard21, + appParamValue.ignorefilter ? null : appParamValue.propertySelector); return pushBytes(op, ownerVcard); } else { return BluetoothPbapSimVcardManager.composeAndSendSIMPhonebookOneVcard( @@ -1393,10 +1454,19 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // For others (ich/och/cch/mch), 0.vcf is meaningless, and must // begin from 1.vcf if (intIndex >= 1) { - return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op, - intIndex, intIndex, vcard21, needSendBody, size, appParamValue.ignorefilter, - appParamValue.propertySelector, appParamValue.vCardSelector, - appParamValue.vCardSelectorOperator, mVcardSelector); + return mVcardManager.composeAndSendSelectedCallLogVcards( + appParamValue.needTag, + op, + intIndex, + intIndex, + vcard21, + needSendBody, + size, + appParamValue.ignorefilter, + appParamValue.propertySelector, + appParamValue.vCardSelector, + appParamValue.vCardSelectorOperator, + mVcardSelector); } } return ResponseCodes.OBEX_HTTP_OK; @@ -1468,41 +1538,69 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // Limit the number of call log to CALLLOG_NUM_LIMIT if ((appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.FAVORITES) - && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK)) { + && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK)) { if (requestSize > CALLLOG_NUM_LIMIT) { requestSize = CALLLOG_NUM_LIMIT; } } - Log.d(TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + startPoint - + " endPoint=" + endPoint); + Log.d( + TAG, + "pullPhonebook(): requestSize=" + + requestSize + + " startPoint=" + + startPoint + + " endPoint=" + + endPoint); boolean vcard21 = appParamValue.vcard21; boolean favorites = (appParamValue.needTag == BluetoothPbapObexServer.ContentType.FAVORITES); - if ((appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) - || favorites) { + if ((appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) || favorites) { if (startPoint == 0) { - String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, - appParamValue.ignorefilter ? null : appParamValue.propertySelector); + String ownerVcard = + mVcardManager.getOwnerPhoneNumberVcard( + vcard21, + appParamValue.ignorefilter ? null : appParamValue.propertySelector); if (endPoint == 0) { return pushBytes(op, ownerVcard); } else { - return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, - ownerVcard, needSendBody, pbSize, appParamValue.ignorefilter, - appParamValue.propertySelector, appParamValue.vCardSelector, - appParamValue.vCardSelectorOperator, mVcardSelector, favorites); + return mVcardManager.composeAndSendPhonebookVcards( + op, + 1, + endPoint, + vcard21, + ownerVcard, + needSendBody, + pbSize, + appParamValue.ignorefilter, + appParamValue.propertySelector, + appParamValue.vCardSelector, + appParamValue.vCardSelectorOperator, + mVcardSelector, + favorites); } } else { - return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, - vcard21, null, needSendBody, pbSize, appParamValue.ignorefilter, - appParamValue.propertySelector, appParamValue.vCardSelector, - appParamValue.vCardSelectorOperator, mVcardSelector, favorites); + return mVcardManager.composeAndSendPhonebookVcards( + op, + startPoint, + endPoint, + vcard21, + null, + needSendBody, + pbSize, + appParamValue.ignorefilter, + appParamValue.propertySelector, + appParamValue.vCardSelector, + appParamValue.vCardSelectorOperator, + mVcardSelector, + favorites); } } else if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK) { if (startPoint == 0) { - String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, - appParamValue.propertySelector); + String ownerVcard = + mVcardManager.getOwnerPhoneNumberVcard( + vcard21, appParamValue.propertySelector); if (endPoint == 0) { return pushBytes(op, ownerVcard); } else { @@ -1514,10 +1612,18 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { mContext, op, startPoint, endPoint, vcard21, null); } } else { - return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op, - startPoint, endPoint, vcard21, needSendBody, pbSize, - appParamValue.ignorefilter, appParamValue.propertySelector, - appParamValue.vCardSelector, appParamValue.vCardSelectorOperator, + return mVcardManager.composeAndSendSelectedCallLogVcards( + appParamValue.needTag, + op, + startPoint, + endPoint, + vcard21, + needSendBody, + pbSize, + appParamValue.ignorefilter, + appParamValue.propertySelector, + appParamValue.vCardSelector, + appParamValue.vCardSelectorOperator, mVcardSelector); } } @@ -1556,16 +1662,22 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // Reserved for future use. In case PSE challenge PCE and PCE input wrong // session key. @Override - public final void onAuthenticationFailure(final byte[] userName) { - } + public final void onAuthenticationFailure(final byte[] userName) {} public static final String createSelectionPara(final int type) { String selection = null; switch (type) { case ContentType.INCOMING_CALL_HISTORY: selection = - "(" + Calls.TYPE + "=" + CallLog.Calls.INCOMING_TYPE + " OR " + Calls.TYPE - + "=" + CallLog.Calls.REJECTED_TYPE + ")"; + "(" + + Calls.TYPE + + "=" + + CallLog.Calls.INCOMING_TYPE + + " OR " + + Calls.TYPE + + "=" + + CallLog.Calls.REJECTED_TYPE + + ")"; break; case ContentType.OUTGOING_CALL_HISTORY: selection = Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE; @@ -1580,9 +1692,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return selection; } - /** - * XML encode special characters in the name field - */ + /** XML encode special characters in the name field */ private static void xmlEncode(String name, StringBuilder result) { if (name == null) { return; @@ -1652,28 +1762,33 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { @VisibleForTesting void setDbCounters(ApplicationParameter ap) { - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.DATABASEIDENTIFIER_TAGID, + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.DATABASEIDENTIFIER_TAGID, ApplicationParameter.TRIPLET_LENGTH.DATABASEIDENTIFIER_LENGTH, getDatabaseIdentifier()); } @VisibleForTesting static void setFolderVersionCounters(ApplicationParameter ap) { - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.PRIMARYVERSIONCOUNTER_TAGID, + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.PRIMARYVERSIONCOUNTER_TAGID, ApplicationParameter.TRIPLET_LENGTH.PRIMARYVERSIONCOUNTER_LENGTH, getPBPrimaryFolderVersion()); - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.SECONDARYVERSIONCOUNTER_TAGID, + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.SECONDARYVERSIONCOUNTER_TAGID, ApplicationParameter.TRIPLET_LENGTH.SECONDARYVERSIONCOUNTER_LENGTH, getPBSecondaryFolderVersion()); } @VisibleForTesting static void setCallversionCounters(ApplicationParameter ap, AppParamValue appParamValue) { - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.PRIMARYVERSIONCOUNTER_TAGID, + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.PRIMARYVERSIONCOUNTER_TAGID, ApplicationParameter.TRIPLET_LENGTH.PRIMARYVERSIONCOUNTER_LENGTH, appParamValue.callHistoryVersionCounter); - ap.addTriplet(ApplicationParameter.TRIPLET_TAGID.SECONDARYVERSIONCOUNTER_TAGID, + ap.addTriplet( + ApplicationParameter.TRIPLET_TAGID.SECONDARYVERSIONCOUNTER_TAGID, ApplicationParameter.TRIPLET_LENGTH.SECONDARYVERSIONCOUNTER_LENGTH, appParamValue.callHistoryVersionCounter); } @@ -1730,5 +1845,4 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { public void setConnAppParamValue(AppParamValue connAppParamValue) { mConnAppParamValue = connAppParamValue; } - } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java index b17706e0784..06afb2c4636 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java @@ -75,49 +75,36 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect private static final String TAG = "BluetoothPbapService"; /** - * To enable PBAP DEBUG/VERBOSE logging - run below cmd in adb shell, and - * restart com.android.bluetooth process. only enable DEBUG log: - * "setprop log.tag.BluetoothPbapService DEBUG"; enable both VERBOSE and - * DEBUG log: "setprop log.tag.BluetoothPbapService VERBOSE" + * To enable PBAP DEBUG/VERBOSE logging - run below cmd in adb shell, and restart + * com.android.bluetooth process. only enable DEBUG log: "setprop log.tag.BluetoothPbapService + * DEBUG"; enable both VERBOSE and DEBUG log: "setprop log.tag.BluetoothPbapService VERBOSE" */ - - - /** - * The component name of the owned BluetoothPbapActivity - */ + /** The component name of the owned BluetoothPbapActivity */ private static final String PBAP_ACTIVITY = BluetoothPbapActivity.class.getCanonicalName(); - /** - * Intent indicating incoming obex authentication request which is from - * PCE(Carkit) - */ + /** Intent indicating incoming obex authentication request which is from PCE(Carkit) */ static final String AUTH_CHALL_ACTION = "com.android.bluetooth.pbap.authchall"; /** - * Intent indicating obex session key input complete by user which is sent - * from BluetoothPbapActivity + * Intent indicating obex session key input complete by user which is sent from + * BluetoothPbapActivity */ static final String AUTH_RESPONSE_ACTION = "com.android.bluetooth.pbap.authresponse"; /** - * Intent indicating user canceled obex authentication session key input - * which is sent from BluetoothPbapActivity + * Intent indicating user canceled obex authentication session key input which is sent from + * BluetoothPbapActivity */ static final String AUTH_CANCELLED_ACTION = "com.android.bluetooth.pbap.authcancelled"; - /** - * Intent indicating timeout for user confirmation, which is sent to - * BluetoothPbapActivity - */ + /** Intent indicating timeout for user confirmation, which is sent to BluetoothPbapActivity */ static final String USER_CONFIRM_TIMEOUT_ACTION = "com.android.bluetooth.pbap.userconfirmtimeout"; - /** - * Intent Extra name indicating session key which is sent from - * BluetoothPbapActivity - */ + /** Intent Extra name indicating session key which is sent from BluetoothPbapActivity */ static final String EXTRA_SESSION_KEY = "com.android.bluetooth.pbap.sessionkey"; + static final String EXTRA_DEVICE = "com.android.bluetooth.pbap.device"; static final int MSG_ACQUIRE_WAKE_LOCK = 5004; @@ -152,17 +139,19 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect private static final int SDP_PBAP_SUPPORTED_FEATURES = 0x021F; /* PBAP will use Bluetooth notification ID from 1000000 (included) to 2000000 (excluded). - The notification ID should be unique in Bluetooth package. */ + The notification ID should be unique in Bluetooth package. */ private static final int PBAP_NOTIFICATION_ID_START = 1000000; private static final int PBAP_NOTIFICATION_ID_END = 2000000; - static final int VERSION_UPDATE_NOTIFICATION_DELAY = 500; //in ms + static final int VERSION_UPDATE_NOTIFICATION_DELAY = 500; // in ms private int mSdpHandle = -1; private PbapHandler mSessionStatusHandler; private HandlerThread mHandlerThread; + @VisibleForTesting final HashMap mPbapStateMachineMap = new HashMap<>(); + private volatile int mNextNotificationId = PBAP_NOTIFICATION_ID_START; // package and class name to which we send intent to check phone book access permission @@ -223,8 +212,10 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect String action = intent.getAction(); Log.d(TAG, "action: " + action); if (BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY.equals(action)) { - int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, - BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); + int requestType = + intent.getIntExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); if (requestType != BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) { return; } @@ -243,10 +234,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect return; } mSessionStatusHandler.removeMessages(USER_TIMEOUT, sm); - int access = intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, - BluetoothDevice.CONNECTION_ACCESS_NO); - boolean savePreference = intent.getBooleanExtra( - BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false); + int access = + intent.getIntExtra( + BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, + BluetoothDevice.CONNECTION_ACCESS_NO); + boolean savePreference = + intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false); if (access == BluetoothDevice.CONNECTION_ACCESS_YES) { if (savePreference) { @@ -331,12 +324,13 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect }; @VisibleForTesting - BroadcastReceiver mPbapReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - parseIntent(intent); - } - }; + BroadcastReceiver mPbapReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + parseIntent(intent); + } + }; private void closeService() { Log.v(TAG, "Pbap Service closeService"); @@ -382,8 +376,10 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect return; } - int pbapSupportedRepositories = isSimEnabled() ? SDP_PBAP_SUPPORTED_REPOSITORIES_WITH_SIM - : SDP_PBAP_SUPPORTED_REPOSITORIES_WITHOUT_SIM; + int pbapSupportedRepositories = + isSimEnabled() + ? SDP_PBAP_SUPPORTED_REPOSITORIES_WITH_SIM + : SDP_PBAP_SUPPORTED_REPOSITORIES_WITHOUT_SIM; mSdpHandle = SdpManagerNativeInterface.getInstance() @@ -430,19 +426,23 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect // create Notification channel. sNotificationManager = context.getSystemService(NotificationManager.class); if (sNotificationManager != null) { - NotificationChannel mChannel = new NotificationChannel(PBAP_NOTIFICATION_ID, - PBAP_NOTIFICATION_NAME, NotificationManager.IMPORTANCE_DEFAULT); + NotificationChannel mChannel = + new NotificationChannel( + PBAP_NOTIFICATION_ID, + PBAP_NOTIFICATION_NAME, + NotificationManager.IMPORTANCE_DEFAULT); sNotificationManager.createNotificationChannel(mChannel); // create notification String title = context.getString(R.string.phonebook_advance_feature_support); String contentText = context.getString(R.string.repair_for_adv_phonebook_feature); int notificationId = android.R.drawable.stat_sys_data_bluetooth; - Notification notification = new Notification.Builder(context, PBAP_NOTIFICATION_ID) - .setContentTitle(title) - .setContentText(contentText) - .setSmallIcon(notificationId) - .setAutoCancel(true) - .build(); + Notification notification = + new Notification.Builder(context, PBAP_NOTIFICATION_ID) + .setContentTitle(title) + .setContentText(contentText) + .setSmallIcon(notificationId) + .setAutoCancel(true) + .build(); sNotificationManager.notify(notificationId, notification); } else { Log.e(TAG, "sNotificationManager is null"); @@ -452,12 +452,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, 6); } - } /* Checks if notification for Version Upgrade is required */ - protected static void handleNotificationTask(BluetoothPbapService service, - BluetoothDevice remoteDevice) { + protected static void handleNotificationTask( + BluetoothPbapService service, BluetoothDevice remoteDevice) { int pce_version = 0; AdapterService adapterService = AdapterService.getAdapterService(); @@ -466,8 +465,10 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect Log.d(TAG, "pce_version: " + pce_version); } - boolean matched = InteropUtil.interopMatchAddrOrName( - InteropUtil.InteropFeature.INTEROP_ADV_PBAP_VER_1_2, remoteDevice.getAddress()); + boolean matched = + InteropUtil.interopMatchAddrOrName( + InteropUtil.InteropFeature.INTEROP_ADV_PBAP_VER_1_2, + remoteDevice.getAddress()); Log.d(TAG, "INTEROP_ADV_PBAP_VER_1_2: matched=" + matched); if (pce_version == PBAP_ADV_VERSION && !matched) { @@ -480,6 +481,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } } } + private class PbapHandler extends Handler { private PbapHandler(Looper looper) { super(looper); @@ -508,12 +510,14 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect break; case USER_TIMEOUT: Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); - intent.setPackage(SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - getString(R.string.pairing_ui_package))); + intent.setPackage( + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, + getString(R.string.pairing_ui_package))); PbapStateMachine stateMachine = (PbapStateMachine) msg.obj; intent.putExtra(BluetoothDevice.EXTRA_DEVICE, stateMachine.getRemoteDevice()); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); BluetoothPbapService.this.sendBroadcast( intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); @@ -522,8 +526,10 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect case MSG_ACQUIRE_WAKE_LOCK: if (mWakeLock == null) { PowerManager pm = getSystemService(PowerManager.class); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "StartingObexPbapTransaction"); + mWakeLock = + pm.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, + "StartingObexPbapTransaction"); mWakeLock.setReferenceCounted(false); mWakeLock.acquire(); Log.w(TAG, "Acquire Wake Lock"); @@ -586,9 +592,9 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect * Get the current connection state of PBAP with the passed in device * * @param device is the device whose connection state to PBAP we are trying to get - * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, - * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or - * {@link BluetoothProfile#STATE_DISCONNECTING} + * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, {@link + * BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or {@link + * BluetoothProfile#STATE_DISCONNECTING} */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(BluetoothDevice device) { @@ -627,14 +633,13 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } /** - * Set connection policy of the profile and tries to disconnect it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and tries to disconnect it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -646,8 +651,8 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.PBAP, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.PBAP, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { @@ -659,10 +664,9 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device @@ -671,12 +675,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect if (device == null) { throw new IllegalArgumentException("Null device"); } - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.PBAP); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.PBAP); } /** * Disconnects pbap server profile with device + * * @param device is the remote bluetooth device */ public void disconnect(BluetoothDevice device) { @@ -709,8 +713,10 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect @Override public void start() { Log.v(TAG, "start()"); - mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), - "DatabaseManager cannot be null when PbapService starts"); + mDatabaseManager = + Objects.requireNonNull( + AdapterService.getAdapterService().getDatabase(), + "DatabaseManager cannot be null when PbapService starts"); IntentFilter userFilter = new IntentFilter(); userFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -736,9 +742,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect registerReceiver(mPbapReceiver, filter); try { mContactChangeObserver = new BluetoothPbapContentObserver(); - getContentResolver().registerContentObserver( - DevicePolicyUtils.getEnterprisePhoneUri(this), false, - mContactChangeObserver); + getContentResolver() + .registerContentObserver( + DevicePolicyUtils.getEnterprisePhoneUri(this), + false, + mContactChangeObserver); } catch (SQLiteException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, @@ -856,8 +864,8 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } @Override - public List getDevicesMatchingConnectionStates(int[] states, - AttributionSource source) { + public List getDevicesMatchingConnectionStates( + int[] states, AttributionSource source) { Log.d(TAG, "getDevicesMatchingConnectionStates"); BluetoothPbapService service = getService(source); if (service == null) { @@ -877,10 +885,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } @Override - public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy, - AttributionSource source) { - Log.d(TAG, "setConnectionPolicy for device: " + device + ", policy:" - + connectionPolicy); + public boolean setConnectionPolicy( + BluetoothDevice device, int connectionPolicy, AttributionSource source) { + Log.d( + TAG, + "setConnectionPolicy for device: " + device + ", policy:" + connectionPolicy); BluetoothPbapService service = getService(source); if (service == null) { return false; @@ -902,8 +911,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect @Override public boolean onConnect(BluetoothDevice remoteDevice, BluetoothSocket socket) { if (remoteDevice == null || socket == null) { - Log.e(TAG, "onConnect(): Unexpected null. remoteDevice=" + remoteDevice - + " socket=" + socket); + Log.e( + TAG, + "onConnect(): Unexpected null. remoteDevice=" + + remoteDevice + + " socket=" + + socket); return false; } @@ -927,8 +940,9 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } /** - * Get the phonebook access permission for the device; if unknown, ask the user. - * Send the result to the state machine. + * Get the phonebook access permission for the device; if unknown, ask the user. Send the result + * to the state machine. + * * @param stateMachine PbapStateMachine which sends the request */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -945,9 +959,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect stateMachine.sendMessage(PbapStateMachine.REJECTED); } else { // permission == BluetoothDevice.ACCESS_UNKNOWN Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); - intent.setClassName(BluetoothPbapService.ACCESS_AUTHORITY_PACKAGE, + intent.setClassName( + BluetoothPbapService.ACCESS_AUTHORITY_PACKAGE, BluetoothPbapService.ACCESS_AUTHORITY_CLASS); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, this.getPackageName()); @@ -963,8 +979,9 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect Log.v(TAG, "waiting for authorization for connection from: " + device); /* In case car kit time out and try to use HFP for phonebook * access, while UI still there waiting for user to confirm */ - Message msg = mSessionStatusHandler.obtainMessage(BluetoothPbapService.USER_TIMEOUT, - stateMachine); + Message msg = + mSessionStatusHandler.obtainMessage( + BluetoothPbapService.USER_TIMEOUT, stateMachine); mSessionStatusHandler.sendMessageDelayed(msg, USER_CONFIRM_TIMEOUT_VALUE); /* We will continue the process when we receive * BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY from Settings app. */ @@ -972,8 +989,8 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } /** - * Called when an unrecoverable error occurred in an accept thread. - * Close down the server socket, and restart. + * Called when an unrecoverable error occurred in an accept thread. Close down the server + * socket, and restart. */ @Override public synchronized void onAcceptFailed() { @@ -1040,7 +1057,6 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect sLocalPhoneNum = tm.getLine1Number(); sLocalPhoneName = this.getString(R.string.localPhoneName); } - Log.v(TAG, "Local Phone Details- Number:" + sLocalPhoneNum - + ", Name:" + sLocalPhoneName); + Log.v(TAG, "Local Phone Details- Number:" + sLocalPhoneNum + ", Name:" + sLocalPhoneName); } } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java index 2bb017ccaf9..bd3a5b58d49 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java @@ -52,48 +52,41 @@ import java.util.List; public class BluetoothPbapSimVcardManager { private static final String TAG = "PbapSIMvCardComposer"; - @VisibleForTesting public static final String FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO = - "Failed to get database information"; + "Failed to get database information"; @VisibleForTesting - public static final String FAILURE_REASON_NO_ENTRY = - "There's no exportable in the database"; + public static final String FAILURE_REASON_NO_ENTRY = "There's no exportable in the database"; @VisibleForTesting public static final String FAILURE_REASON_NOT_INITIALIZED = - "The vCard composer object is not correctly initialized"; + "The vCard composer object is not correctly initialized"; /** Should be visible only from developers... (no need to translate, hopefully) */ @VisibleForTesting public static final String FAILURE_REASON_UNSUPPORTED_URI = - "The Uri vCard composer received is not supported by the composer."; + "The Uri vCard composer received is not supported by the composer."; - @VisibleForTesting - public static final String NO_ERROR = "No error"; + @VisibleForTesting public static final String NO_ERROR = "No error"; - @VisibleForTesting - public static final Uri SIM_URI = Uri.parse("content://icc/adn"); + @VisibleForTesting public static final Uri SIM_URI = Uri.parse("content://icc/adn"); - @VisibleForTesting - public static final String SIM_PATH = "/SIM1/telecom"; + @VisibleForTesting public static final String SIM_PATH = "/SIM1/telecom"; - private static final String[] SIM_PROJECTION = new String[] { - Contacts.DISPLAY_NAME, - CommonDataKinds.Phone.NUMBER, - CommonDataKinds.Phone.TYPE, - CommonDataKinds.Phone.LABEL - }; + private static final String[] SIM_PROJECTION = + new String[] { + Contacts.DISPLAY_NAME, + CommonDataKinds.Phone.NUMBER, + CommonDataKinds.Phone.TYPE, + CommonDataKinds.Phone.LABEL + }; - @VisibleForTesting - public static final int NAME_COLUMN_INDEX = 0; - @VisibleForTesting - public static final int NUMBER_COLUMN_INDEX = 1; + @VisibleForTesting public static final int NAME_COLUMN_INDEX = 0; + @VisibleForTesting public static final int NUMBER_COLUMN_INDEX = 1; private static final int NUMBERTYPE_COLUMN_INDEX = 2; private static final int NUMBERLABEL_COLUMN_INDEX = 3; - private final Context mContext; private ContentResolver mContentResolver; private Cursor mCursor; @@ -105,16 +98,26 @@ public class BluetoothPbapSimVcardManager { mContentResolver = context.getContentResolver(); } - public boolean init(final Uri contentUri, final String selection, - final String[] selectionArgs, final String sortOrder) { + public boolean init( + final Uri contentUri, + final String selection, + final String[] selectionArgs, + final String sortOrder) { if (!SIM_URI.equals(contentUri)) { mErrorReason = FAILURE_REASON_UNSUPPORTED_URI; return false; } - //checkpoint Figure out if we can apply selection, projection and sort order. - mCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mContentResolver, - contentUri, SIM_PROJECTION, null, null, sortOrder); + // checkpoint Figure out if we can apply selection, projection and sort order. + mCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, + contentUri, + SIM_PROJECTION, + null, + null, + sortOrder); if (mCursor == null) { mErrorReason = FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO; @@ -152,9 +155,11 @@ public class BluetoothPbapSimVcardManager { } private String createOnevCardEntryInternal(boolean vcardVer21) { - final int vcardType = (vcardVer21 ? VCardConfig.VCARD_TYPE_V21_GENERIC : - VCardConfig.VCARD_TYPE_V30_GENERIC) | - VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; + final int vcardType = + (vcardVer21 + ? VCardConfig.VCARD_TYPE_V21_GENERIC + : VCardConfig.VCARD_TYPE_V30_GENERIC) + | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; final VCardBuilder builder = new VCardBuilder(vcardType); String name = mCursor.getString(NAME_COLUMN_INDEX); if (TextUtils.isEmpty(name)) { @@ -229,10 +234,10 @@ public class BluetoothPbapSimVcardManager { } public void moveToPosition(final int position, boolean sortalpha) { - if(mCursor == null) { + if (mCursor == null) { return; } - if(sortalpha) { + if (sortalpha) { setPositionByAlpha(position); return; } @@ -244,12 +249,11 @@ public class BluetoothPbapSimVcardManager { } private void setPositionByAlpha(int position) { - if(mCursor == null) { + if (mCursor == null) { return; } ArrayList nameList = new ArrayList(); - for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor - .moveToNext()) { + for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) { String name = mCursor.getString(NAME_COLUMN_INDEX); if (TextUtils.isEmpty(name)) { name = mContext.getString(android.R.string.unknownName); @@ -257,18 +261,19 @@ public class BluetoothPbapSimVcardManager { nameList.add(name); } - Collections.sort(nameList, new Comparator () { - @Override - public int compare(String str1, String str2){ - return str1.compareToIgnoreCase(str2); - } - }); + Collections.sort( + nameList, + new Comparator() { + @Override + public int compare(String str1, String str2) { + return str1.compareToIgnoreCase(str2); + } + }); for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) { - if(mCursor.getString(NAME_COLUMN_INDEX).equals(nameList.get(position))) { - break; + if (mCursor.getString(NAME_COLUMN_INDEX).equals(nameList.get(position))) { + break; } - } } @@ -276,8 +281,10 @@ public class BluetoothPbapSimVcardManager { int size = 0; Cursor contactCursor = null; try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - mContentResolver, SIM_URI, SIM_PROJECTION, null,null, null); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, SIM_URI, SIM_PROJECTION, null, null, null); if (contactCursor != null) { size = contactCursor.getCount(); } @@ -292,15 +299,18 @@ public class BluetoothPbapSimVcardManager { public final ArrayList getSIMPhonebookNameList(final int orderByWhat) { ArrayList nameList = new ArrayList(); nameList.add(BluetoothPbapService.getLocalPhoneName()); - //Since owner card should always be 0.vcf, maintain a separate list to avoid sorting + // Since owner card should always be 0.vcf, maintain a separate list to avoid sorting ArrayList allnames = new ArrayList(); Cursor contactCursor = null; try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - mContentResolver, SIM_URI, SIM_PROJECTION, null,null,null); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, SIM_URI, SIM_PROJECTION, null, null, null); if (contactCursor != null) { - for (contactCursor.moveToFirst(); !contactCursor.isAfterLast(); contactCursor - .moveToNext()) { + for (contactCursor.moveToFirst(); + !contactCursor.isAfterLast(); + contactCursor.moveToNext()) { String name = contactCursor.getString(NAME_COLUMN_INDEX); if (TextUtils.isEmpty(name)) { name = mContext.getString(android.R.string.unknownName); @@ -317,32 +327,35 @@ public class BluetoothPbapSimVcardManager { Log.v(TAG, "getPhonebookNameList, order by index"); } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { Log.v(TAG, "getPhonebookNameList, order by alpha"); - Collections.sort(allnames, new Comparator () { - @Override - public int compare(String str1, String str2) { - return str1.compareToIgnoreCase(str2); - } - }); + Collections.sort( + allnames, + new Comparator() { + @Override + public int compare(String str1, String str2) { + return str1.compareToIgnoreCase(str2); + } + }); } nameList.addAll(allnames); return nameList; - } - public final ArrayList getSIMContactNamesByNumber( - final String phoneNumber) { + public final ArrayList getSIMContactNamesByNumber(final String phoneNumber) { ArrayList nameList = new ArrayList(); ArrayList startNameList = new ArrayList(); Cursor contactCursor = null; try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( - mContentResolver, SIM_URI, SIM_PROJECTION, null, null, null); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContentResolver, SIM_URI, SIM_PROJECTION, null, null, null); if (contactCursor != null) { - for (contactCursor.moveToFirst(); !contactCursor.isAfterLast(); contactCursor - .moveToNext()) { + for (contactCursor.moveToFirst(); + !contactCursor.isAfterLast(); + contactCursor.moveToNext()) { String number = contactCursor.getString(NUMBER_COLUMN_INDEX); if (number == null) { Log.v(TAG, "number is null"); @@ -375,15 +388,18 @@ public class BluetoothPbapSimVcardManager { int startListSize = startNameList.size(); for (int index = 0; index < startListSize; index++) { String object = startNameList.get(index); - if (!nameList.contains(object)) - nameList.add(object); + if (!nameList.contains(object)) nameList.add(object); } return nameList; } - public static final int composeAndSendSIMPhonebookVcards(Context context, Operation op, - final int startPoint, final int endPoint, final boolean vcardType21, + public static final int composeAndSendSIMPhonebookVcards( + Context context, + Operation op, + final int startPoint, + final int endPoint, + final boolean vcardType21, String ownerVCard) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); @@ -404,16 +420,20 @@ public class BluetoothPbapSimVcardManager { return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } composer.moveToPosition(startPoint - 1, false); - for (int count =startPoint -1; count < endPoint; count++) { + for (int count = startPoint - 1; count < endPoint; count++) { if (BluetoothPbapObexServer.sIsAborted) { - ((ServerOperation)op).setAborted(true); + ((ServerOperation) op).setAborted(true); BluetoothPbapObexServer.sIsAborted = false; break; } String vcard = composer.createOneEntry(vcardType21); if (vcard == null) { - Log.e(TAG, "Failed to read a contact. Error reason: " - + composer.getErrorReason() + ", count:" + count); + Log.e( + TAG, + "Failed to read a contact. Error reason: " + + composer.getErrorReason() + + ", count:" + + count); ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, @@ -435,8 +455,12 @@ public class BluetoothPbapSimVcardManager { return ResponseCodes.OBEX_HTTP_OK; } - public static final int composeAndSendSIMPhonebookOneVcard(Context context, Operation op, - final int offset, final boolean vcardType21, String ownerVCard, + public static final int composeAndSendSIMPhonebookOneVcard( + Context context, + Operation op, + final int offset, + final boolean vcardType21, + String ownerVCard, int orderByWhat) { if (offset < 1) { Log.e(TAG, "Internal error: offset is not correct."); @@ -457,18 +481,17 @@ public class BluetoothPbapSimVcardManager { return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) { - composer.moveToPosition(offset -1, false); + composer.moveToPosition(offset - 1, false); } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { - composer.moveToPosition(offset -1, true); + composer.moveToPosition(offset - 1, true); } if (BluetoothPbapObexServer.sIsAborted) { - ((ServerOperation)op).setAborted(true); - BluetoothPbapObexServer.sIsAborted = false; + ((ServerOperation) op).setAborted(true); + BluetoothPbapObexServer.sIsAborted = false; } String vcard = composer.createOneEntry(vcardType21); if (vcard == null) { - Log.e(TAG, "Failed to read a contact. Error reason: " - + composer.getErrorReason()); + Log.e(TAG, "Failed to read a contact. Error reason: " + composer.getErrorReason()); ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, @@ -489,16 +512,20 @@ public class BluetoothPbapSimVcardManager { return ResponseCodes.OBEX_HTTP_OK; } - protected boolean isSimPhoneBook(String name, String type, String PB, - String SIM1, String TYPE_PB, String TYPE_LISTING, String mCurrentPath) { + protected boolean isSimPhoneBook( + String name, + String type, + String PB, + String SIM1, + String TYPE_PB, + String TYPE_LISTING, + String mCurrentPath) { return ((name.contains(PB.subSequence(0, PB.length())) - && name.contains(SIM1.subSequence(0, - SIM1.length()))) - && (type.equals(TYPE_PB))) - || (((name.contains( - PB.subSequence(0, PB.length()))) - && (mCurrentPath.equals(SIM_PATH))) + && name.contains(SIM1.subSequence(0, SIM1.length()))) + && (type.equals(TYPE_PB))) + || (((name.contains(PB.subSequence(0, PB.length()))) + && (mCurrentPath.equals(SIM_PATH))) && (type.equals(TYPE_LISTING))); } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java index 035ba321b92..c91219abf5e 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java @@ -73,17 +73,13 @@ class BluetoothPbapUtils { static long sPrimaryVersionCounter = 0; static long sSecondaryVersionCounter = 0; - @VisibleForTesting - static long sTotalContacts = 0; + @VisibleForTesting static long sTotalContacts = 0; /* totalFields and totalSvcFields used to update primary/secondary version * counter between pbap sessions*/ - @VisibleForTesting - static long sTotalFields = 0; - @VisibleForTesting - static long sTotalSvcFields = 0; - @VisibleForTesting - static long sContactsLastUpdated = 0; + @VisibleForTesting static long sTotalFields = 0; + @VisibleForTesting static long sTotalSvcFields = 0; + @VisibleForTesting static long sContactsLastUpdated = 0; private static class ContactData { private String mName; @@ -97,7 +93,10 @@ class BluetoothPbapUtils { mAddress = new ArrayList<>(); } - ContactData(String name, ArrayList phone, ArrayList email, + ContactData( + String name, + ArrayList phone, + ArrayList email, ArrayList address) { this.mName = name; this.mPhone = phone; @@ -106,20 +105,14 @@ class BluetoothPbapUtils { } } - @VisibleForTesting - static HashMap sContactDataset = new HashMap<>(); + @VisibleForTesting static HashMap sContactDataset = new HashMap<>(); - @VisibleForTesting - static HashSet sContactSet = new HashSet<>(); + @VisibleForTesting static HashSet sContactSet = new HashSet<>(); - @VisibleForTesting - static final String TYPE_NAME = "name"; - @VisibleForTesting - static final String TYPE_PHONE = "phone"; - @VisibleForTesting - static final String TYPE_EMAIL = "email"; - @VisibleForTesting - static final String TYPE_ADDRESS = "address"; + @VisibleForTesting static final String TYPE_NAME = "name"; + @VisibleForTesting static final String TYPE_PHONE = "phone"; + @VisibleForTesting static final String TYPE_EMAIL = "email"; + @VisibleForTesting static final String TYPE_ADDRESS = "address"; private static boolean hasFilter(byte[] filter) { return filter != null && filter.length > 0; @@ -136,12 +129,12 @@ class BluetoothPbapUtils { return false; } - static VCardComposer createFilteredVCardComposer(final Context ctx, final int vcardType, - final byte[] filter) { + static VCardComposer createFilteredVCardComposer( + final Context ctx, final int vcardType, final byte[] filter) { int vType = vcardType; boolean includePhoto = - BluetoothPbapConfig.includePhotosInVcard() && (!hasFilter(filter) || isFilterBitSet( - filter, FILTER_PHOTO)); + BluetoothPbapConfig.includePhotosInVcard() + && (!hasFilter(filter) || isFilterBitSet(filter, FILTER_PHOTO)); if (!includePhoto) { Log.v(TAG, "Excluding images from VCardComposer..."); vType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; @@ -206,8 +199,14 @@ class BluetoothPbapUtils { String vcard = null; try { composer = createFilteredVCardComposer(ctx, vcardType, filter); - if (composer.init(Profile.CONTENT_URI, null, null, null, null, - Uri.withAppendedPath(Profile.CONTENT_URI, + if (composer.init( + Profile.CONTENT_URI, + null, + null, + null, + null, + Uri.withAppendedPath( + Profile.CONTENT_URI, RawContactsEntity.CONTENT_URI.getLastPathSegment()))) { vcard = composer.createOneEntry(); } else { @@ -248,8 +247,14 @@ class BluetoothPbapUtils { edit.putLong("totalSvcFields", sTotalSvcFields); edit.apply(); - Log.v(TAG, "Saved Primary:" + sPrimaryVersionCounter + ", Secondary:" - + sSecondaryVersionCounter + ", Database Identifier: " + dbIdentifier); + Log.v( + TAG, + "Saved Primary:" + + sPrimaryVersionCounter + + ", Secondary:" + + sSecondaryVersionCounter + + ", Database Identifier: " + + dbIdentifier); } /* fetchPbapParams() loads preserved value of Database Identifiers and folder @@ -283,10 +288,10 @@ class BluetoothPbapUtils { } static synchronized void updateSecondaryVersionCounter(Context context, Handler handler) { - /* updatedList stores list of contacts which are added/updated after - * the time when contacts were last updated. (contactsLastUpdated - * indicates the time when contact/contacts were last updated and - * corresponding changes were reflected in Folder Version Counters).*/ + /* updatedList stores list of contacts which are added/updated after + * the time when contacts were last updated. (contactsLastUpdated + * indicates the time when contact/contacts were last updated and + * corresponding changes were reflected in Folder Version Counters).*/ ArrayList updatedList = new ArrayList<>(); HashSet currentContactSet = new HashSet<>(); @@ -322,22 +327,26 @@ class BluetoothPbapUtils { String whereClause = Data.CONTACT_ID + "=?"; - /* code to check if new contact/contacts are added */ + /* code to check if new contact/contacts are added */ if (currentContactCount > sTotalContacts) { for (String contact : updatedList) { String[] selectionArgs = {contact}; - fetchAndSetContacts(context, handler, dataProjection, whereClause, selectionArgs, - false); + fetchAndSetContacts( + context, handler, dataProjection, whereClause, selectionArgs, false); sSecondaryVersionCounter++; sPrimaryVersionCounter++; sTotalContacts = currentContactCount; } - /* When contact/contacts are deleted */ + /* When contact/contacts are deleted */ } else if (currentContactCount < sTotalContacts) { sTotalContacts = currentContactCount; - ArrayList svcFields = new ArrayList<>( - Arrays.asList(StructuredName.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE, - Email.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE)); + ArrayList svcFields = + new ArrayList<>( + Arrays.asList( + StructuredName.CONTENT_ITEM_TYPE, + Phone.CONTENT_ITEM_TYPE, + Email.CONTENT_ITEM_TYPE, + StructuredPostal.CONTENT_ITEM_TYPE)); HashSet deletedContacts = new HashSet<>(sContactSet); deletedContacts.removeAll(currentContactSet); sPrimaryVersionCounter += deletedContacts.size(); @@ -373,8 +382,8 @@ class BluetoothPbapUtils { } } - /* When contacts are updated. i.e. Fields of existing contacts are - * added/updated/deleted */ + /* When contacts are updated. i.e. Fields of existing contacts are + * added/updated/deleted */ } else { for (String contact : updatedList) { sPrimaryVersionCounter++; @@ -454,8 +463,11 @@ class BluetoothPbapUtils { } } - Log.d(TAG, - "primaryVersionCounter = " + sPrimaryVersionCounter + ", secondaryVersionCounter=" + Log.d( + TAG, + "primaryVersionCounter = " + + sPrimaryVersionCounter + + ", secondaryVersionCounter=" + sSecondaryVersionCounter); // check if Primary/Secondary version Counter has rolled over @@ -468,8 +480,7 @@ class BluetoothPbapUtils { * Field update can be a field updated/added/deleted in an existing contact. * Returns true if any contact field is updated else return false. */ @VisibleForTesting - static boolean checkFieldUpdates(ArrayList oldFields, - ArrayList newFields) { + static boolean checkFieldUpdates(ArrayList oldFields, ArrayList newFields) { if (newFields != null && oldFields != null) { if (newFields.size() != oldFields.size()) { sTotalSvcFields += Math.abs(newFields.size() - oldFields.size()); @@ -594,9 +605,13 @@ class BluetoothPbapUtils { sTotalFields = currentTotalFields; sTotalSvcFields = currentSvcFieldCount; sContactsLastUpdated = System.currentTimeMillis(); - Log.d(TAG, "Contacts updated between last BT OFF and current" - + "Pbap Connect, primaryVersionCounter=" + sPrimaryVersionCounter - + ", secondaryVersionCounter=" + sSecondaryVersionCounter); + Log.d( + TAG, + "Contacts updated between last BT OFF and current" + + "Pbap Connect, primaryVersionCounter=" + + sPrimaryVersionCounter + + ", secondaryVersionCounter=" + + sSecondaryVersionCounter); } else if (!isLoad) { sTotalFields++; sTotalSvcFields++; diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java index a357597c4a3..6382193068c 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java @@ -57,21 +57,20 @@ import java.util.Collections; public class BluetoothPbapVcardManager { private static final String TAG = "BluetoothPbapVcardManager"; - private ContentResolver mResolver; private Context mContext; static final String SORT_ORDER_PHONE_NUMBER = CommonDataKinds.Phone.NUMBER + " ASC"; - static final String[] PHONES_CONTACTS_PROJECTION = new String[]{ - Phone.CONTACT_ID, // 0 - Phone.DISPLAY_NAME, // 1 - }; + static final String[] PHONES_CONTACTS_PROJECTION = + new String[] { + Phone.CONTACT_ID, // 0 + Phone.DISPLAY_NAME, // 1 + }; - static final String[] PHONE_LOOKUP_PROJECTION = new String[]{ - PhoneLookup._ID, PhoneLookup.DISPLAY_NAME - }; + static final String[] PHONE_LOOKUP_PROJECTION = + new String[] {PhoneLookup._ID, PhoneLookup.DISPLAY_NAME}; static final int CONTACTS_ID_COLUMN_INDEX = 0; @@ -95,11 +94,12 @@ public class BluetoothPbapVcardManager { /** * Create an owner vcard from the configured profile + * * @param vcardType21 * @return */ - private String getOwnerPhoneNumberVcardFromProfile(final boolean vcardType21, - final byte[] filter) { + private String getOwnerPhoneNumberVcardFromProfile( + final boolean vcardType21, final byte[] filter) { // Currently only support Generic Vcard 2.1 and 3.0 int vcardType; if (vcardType21) { @@ -116,24 +116,25 @@ public class BluetoothPbapVcardManager { } public final String getOwnerPhoneNumberVcard(final boolean vcardType21, final byte[] filter) { - //Owner vCard enhancement: Use "ME" profile if configured + // Owner vCard enhancement: Use "ME" profile if configured if (BluetoothPbapConfig.useProfileForOwnerVcard()) { String vcard = getOwnerPhoneNumberVcardFromProfile(vcardType21, filter); if (vcard != null && vcard.length() != 0) { return vcard; } } - //End enhancement + // End enhancement String name = BluetoothPbapService.getLocalPhoneName(); String number = BluetoothPbapService.getLocalPhoneNum(); - String vcard = BluetoothPbapCallLogComposer.composeVCardForPhoneOwnNumber( - Phone.TYPE_MOBILE, name, number, vcardType21); + String vcard = + BluetoothPbapCallLogComposer.composeVCardForPhoneOwnNumber( + Phone.TYPE_MOBILE, name, number, vcardType21); return vcard; } - public final int getPhonebookSize(final int type, - BluetoothPbapSimVcardManager vCardSimManager) { + public final int getPhonebookSize( + final int type, BluetoothPbapSimVcardManager vCardSimManager) { int size; switch (type) { case BluetoothPbapObexServer.ContentType.PHONEBOOK: @@ -153,6 +154,7 @@ public class BluetoothPbapVcardManager { /** * Returns the number of contacts (i.e., vcf) in a phonebook object. + * * @param type specifies which phonebook object, e.g., pb, fav * @return */ @@ -164,9 +166,15 @@ public class BluetoothPbapVcardManager { selectionClause = Phone.STARRED + " = 1"; } try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, new String[]{Phone.CONTACT_ID}, selectionClause, - null, Phone.CONTACT_ID); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + new String[] {Phone.CONTACT_ID}, + selectionClause, + null, + Phone.CONTACT_ID); if (contactCursor == null) { return 0; } @@ -224,26 +232,28 @@ public class BluetoothPbapVcardManager { return size; } - @VisibleForTesting - static final int CALLS_NUMBER_COLUMN_INDEX = 0; - @VisibleForTesting - static final int CALLS_NAME_COLUMN_INDEX = 1; - @VisibleForTesting - static final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2; + @VisibleForTesting static final int CALLS_NUMBER_COLUMN_INDEX = 0; + @VisibleForTesting static final int CALLS_NAME_COLUMN_INDEX = 1; + @VisibleForTesting static final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2; public final ArrayList loadCallHistoryList(final int type) { final Uri myUri = CallLog.Calls.CONTENT_URI; String selection = BluetoothPbapObexServer.createSelectionPara(type); - String[] projection = new String[]{ - Calls.NUMBER, Calls.CACHED_NAME, Calls.NUMBER_PRESENTATION - }; - + String[] projection = + new String[] {Calls.NUMBER, Calls.CACHED_NAME, Calls.NUMBER_PRESENTATION}; Cursor callCursor = null; ArrayList list = new ArrayList(); try { - callCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, projection, selection, null, CALLLOG_SORT_ORDER); + callCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + projection, + selection, + null, + CALLLOG_SORT_ORDER); if (callCursor != null) { for (callCursor.moveToFirst(); !callCursor.isAfterLast(); callCursor.moveToNext()) { String name = callCursor.getString(CALLS_NAME_COLUMN_INDEX); @@ -278,7 +288,7 @@ public class BluetoothPbapVcardManager { public final ArrayList getPhonebookNameList(final int orderByWhat) { ArrayList nameList = new ArrayList(); - //Owner vCard enhancement. Use "ME" profile if configured + // Owner vCard enhancement. Use "ME" profile if configured String ownerName = null; if (BluetoothPbapConfig.useProfileForOwnerVcard()) { ownerName = BluetoothPbapUtils.getProfileName(mContext); @@ -289,7 +299,7 @@ public class BluetoothPbapVcardManager { if (ownerName != null) { nameList.add(ownerName); } - //End enhancement + // End enhancement final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); Cursor contactCursor = null; @@ -309,8 +319,8 @@ public class BluetoothPbapVcardManager { null, orderBy); if (contactCursor != null) { - appendDistinctNameIdList(nameList, mContext.getString(android.R.string.unknownName), - contactCursor); + appendDistinctNameIdList( + nameList, mContext.getString(android.R.string.unknownName), contactCursor); } } catch (CursorWindowAllocationException e) { ContentProfileErrorReportUtils.report( @@ -335,8 +345,12 @@ public class BluetoothPbapVcardManager { return nameList; } - final ArrayList getSelectedPhonebookNameList(final int orderByWhat, - final boolean vcardType21, int needSendBody, int pbSize, byte[] selector, + final ArrayList getSelectedPhonebookNameList( + final int orderByWhat, + final boolean vcardType21, + int needSendBody, + int pbSize, + byte[] selector, String vCardSelectorOperator) { ArrayList nameList = new ArrayList(); PropertySelector vcardselector = new PropertySelector(selector); @@ -350,16 +364,18 @@ public class BluetoothPbapVcardManager { VCardComposer composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType, null); - composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { - - @Override - public String onValueReceived(String rawValue, int type, String label, - boolean isPrimary) { - String numberWithControlSequence = rawValue.replace(PhoneNumberUtils.PAUSE, 'p') - .replace(PhoneNumberUtils.WAIT, 'w'); - return numberWithControlSequence; - } - }); + composer.setPhoneNumberTranslationCallback( + new VCardPhoneNumberTranslationCallback() { + + @Override + public String onValueReceived( + String rawValue, int type, String label, boolean isPrimary) { + String numberWithControlSequence = + rawValue.replace(PhoneNumberUtils.PAUSE, 'p') + .replace(PhoneNumberUtils.WAIT, 'w'); + return numberWithControlSequence; + } + }); // Owner vCard enhancement. Use "ME" profile if configured String ownerName = null; @@ -375,13 +391,21 @@ public class BluetoothPbapVcardManager { final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); Cursor contactCursor = null; try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, PHONES_CONTACTS_PROJECTION, null, null, - Phone.CONTACT_ID); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + PHONES_CONTACTS_PROJECTION, + null, + null, + Phone.CONTACT_ID); ArrayList contactNameIdList = new ArrayList(); - appendDistinctNameIdList(contactNameIdList, - mContext.getString(android.R.string.unknownName), contactCursor); + appendDistinctNameIdList( + contactNameIdList, + mContext.getString(android.R.string.unknownName), + contactCursor); if (contactCursor != null) { if (!composer.init(contactCursor)) { @@ -395,8 +419,10 @@ public class BluetoothPbapVcardManager { int i = 0; contactCursor.moveToFirst(); while (!contactCursor.isAfterLast()) { - String vcard = composer.buildVCard(RawContactsEntity.queryRawContactEntity( - mResolver, contactCursor.getLong(idColumn))); + String vcard = + composer.buildVCard( + RawContactsEntity.queryRawContactEntity( + mResolver, contactCursor.getLong(idColumn))); if (!contactCursor.moveToNext()) { Log.i(TAG, "Cursor#moveToNext() returned false"); } @@ -475,12 +501,14 @@ public class BluetoothPbapVcardManager { } try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - uri, projection, null, null, Phone.CONTACT_ID); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, uri, projection, null, null, Phone.CONTACT_ID); if (contactCursor != null) { - appendDistinctNameIdList(nameList, mContext.getString(android.R.string.unknownName), - contactCursor); + appendDistinctNameIdList( + nameList, mContext.getString(android.R.string.unknownName), contactCursor); for (String nameIdStr : nameList) { Log.v(TAG, "got name " + nameIdStr + " by number " + phoneNumber); } @@ -512,8 +540,9 @@ public class BluetoothPbapVcardManager { long count = 0; long primaryVcMsb = 0; try { - callCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, null, selection, null, null); + callCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(mResolver, myUri, null, selection, null, null); while (callCursor != null && callCursor.moveToNext()) { count = count + 1; } @@ -540,9 +569,10 @@ public class BluetoothPbapVcardManager { return pvc.array(); } - private static final String[] CALLLOG_PROJECTION = new String[]{ - CallLog.Calls._ID, // 0 - }; + private static final String[] CALLLOG_PROJECTION = + new String[] { + CallLog.Calls._ID, // 0 + }; private static final int ID_COLUMN_INDEX = 0; final int composeAndSendSelectedCallLogVcards( @@ -575,9 +605,15 @@ public class BluetoothPbapVcardManager { long endPointId = 0; try { // Need test to see if order by _ID is ok here, or by date? - callsCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, CALLLOG_PROJECTION, typeSelection, null, - CALLLOG_SORT_ORDER); + callsCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + CALLLOG_PROJECTION, + typeSelection, + null, + CALLLOG_SORT_ORDER); if (callsCursor != null) { callsCursor.moveToPosition(startPoint - 1); startPointId = callsCursor.getLong(ID_COLUMN_INDEX); @@ -623,14 +659,34 @@ public class BluetoothPbapVcardManager { Log.v(TAG, "Call log query selection is: " + selection); - return composeCallLogsAndSendSelectedVCards(op, selection, vcardType21, needSendBody, - pbSize, null, ignorefilter, filter, vcardselector, vcardselectorop, vcardselect); + return composeCallLogsAndSendSelectedVCards( + op, + selection, + vcardType21, + needSendBody, + pbSize, + null, + ignorefilter, + filter, + vcardselector, + vcardselectorop, + vcardselect); } - final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, - final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, - boolean ignorefilter, byte[] filter, byte[] vcardselector, String vcardselectorop, - boolean vcardselect, boolean favorites) { + final int composeAndSendPhonebookVcards( + Operation op, + final int startPoint, + final int endPoint, + final boolean vcardType21, + String ownerVCard, + int needSendBody, + int pbSize, + boolean ignorefilter, + byte[] filter, + byte[] vcardselector, + String vcardselectorop, + boolean vcardselect, + boolean favorites) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); ContentProfileErrorReportUtils.report( @@ -643,9 +699,7 @@ public class BluetoothPbapVcardManager { final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); Cursor contactCursor = null; - Cursor contactIdCursor = new MatrixCursor(new String[]{ - Phone.CONTACT_ID - }); + Cursor contactIdCursor = new MatrixCursor(new String[] {Phone.CONTACT_ID}); String selectionClause = null; if (favorites) { @@ -653,9 +707,15 @@ public class BluetoothPbapVcardManager { } try { - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, PHONES_CONTACTS_PROJECTION, selectionClause, - null, Phone.CONTACT_ID); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + PHONES_CONTACTS_PROJECTION, + selectionClause, + null, + Phone.CONTACT_ID); if (contactCursor != null) { contactIdCursor = ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint); @@ -674,17 +734,30 @@ public class BluetoothPbapVcardManager { } if (vcardselect) { - return composeContactsAndSendSelectedVCards(op, contactIdCursor, vcardType21, - ownerVCard, needSendBody, pbSize, ignorefilter, filter, vcardselector, + return composeContactsAndSendSelectedVCards( + op, + contactIdCursor, + vcardType21, + ownerVCard, + needSendBody, + pbSize, + ignorefilter, + filter, + vcardselector, vcardselectorop); } else { - return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard, - ignorefilter, filter); + return composeContactsAndSendVCards( + op, contactIdCursor, vcardType21, ownerVCard, ignorefilter, filter); } } - final int composeAndSendPhonebookOneVcard(Operation op, final int offset, - final boolean vcardType21, String ownerVCard, int orderByWhat, boolean ignorefilter, + final int composeAndSendPhonebookOneVcard( + Operation op, + final int offset, + final boolean vcardType21, + String ownerVCard, + int orderByWhat, + boolean ignorefilter, byte[] filter) { if (offset < 1) { Log.e(TAG, "Internal error: offset is not correct."); @@ -698,17 +771,22 @@ public class BluetoothPbapVcardManager { final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); Cursor contactCursor = null; - Cursor contactIdCursor = new MatrixCursor(new String[]{ - Phone.CONTACT_ID - }); + Cursor contactIdCursor = new MatrixCursor(new String[] {Phone.CONTACT_ID}); // By default order is indexed String orderBy = Phone.CONTACT_ID; try { if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { orderBy = Phone.DISPLAY_NAME; } - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, PHONES_CONTACTS_PROJECTION, null, null, orderBy); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + PHONES_CONTACTS_PROJECTION, + null, + null, + orderBy); } catch (CursorWindowAllocationException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, @@ -723,16 +801,13 @@ public class BluetoothPbapVcardManager { contactCursor = null; } } - return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard, - ignorefilter, filter); + return composeContactsAndSendVCards( + op, contactIdCursor, vcardType21, ownerVCard, ignorefilter, filter); } - /** - * Filter contact cursor by certain condition. - */ + /** Filter contact cursor by certain condition. */ static final class ContactCursorFilter { /** - * * @param contactCursor * @param offset * @return a cursor containing contact id of {@code offset} contact. @@ -742,12 +817,11 @@ public class BluetoothPbapVcardManager { } /** - * * @param contactCursor * @param startPoint * @param endPoint * @return a cursor containing contact ids of {@code startPoint}th to {@code endPoint}th - * contact. (i.e. [startPoint, endPoint], both points should be greater than 0) + * contact. (i.e. [startPoint, endPoint], both points should be greater than 0) */ static Cursor filterByRange(Cursor contactCursor, int startPoint, int endPoint) { final int contactIdColumn = contactCursor.getColumnIndex(Data.CONTACT_ID); @@ -755,15 +829,13 @@ public class BluetoothPbapVcardManager { // As startPoint, endOffset index starts from 1 to n, we set // currentPoint base as 1 not 0 int currentOffset = 1; - final MatrixCursor contactIdsCursor = new MatrixCursor(new String[]{ - Phone.CONTACT_ID - }); + final MatrixCursor contactIdsCursor = new MatrixCursor(new String[] {Phone.CONTACT_ID}); while (contactCursor.moveToNext() && currentOffset <= endPoint) { long currentContactId = contactCursor.getLong(contactIdColumn); if (previousContactId != currentContactId) { previousContactId = currentContactId; if (currentOffset >= startPoint) { - contactIdsCursor.addRow(new Long[]{currentContactId}); + contactIdsCursor.addRow(new Long[] {currentContactId}); Log.v(TAG, "contactIdsCursor.addRow: " + currentContactId); } currentOffset++; @@ -773,8 +845,13 @@ public class BluetoothPbapVcardManager { } } - private int composeContactsAndSendVCards(Operation op, final Cursor contactIdCursor, - final boolean vcardType21, String ownerVCard, boolean ignorefilter, byte[] filter) { + private int composeContactsAndSendVCards( + Operation op, + final Cursor contactIdCursor, + final boolean vcardType21, + String ownerVCard, + boolean ignorefilter, + byte[] filter) { long timestamp = System.currentTimeMillis(); VCardComposer composer = null; @@ -803,19 +880,21 @@ public class BluetoothPbapVcardManager { // BT does want PAUSE/WAIT conversion while it doesn't want the // other formatting // done by vCard library by default. - composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { - @Override - public String onValueReceived(String rawValue, int type, String label, - boolean isPrimary) { - // 'p' and 'w' are the standard characters for pause and - // wait - // (see RFC 3601) - // so use those when exporting phone numbers via vCard. - String numberWithControlSequence = rawValue.replace(PhoneNumberUtils.PAUSE, 'p') - .replace(PhoneNumberUtils.WAIT, 'w'); - return numberWithControlSequence; - } - }); + composer.setPhoneNumberTranslationCallback( + new VCardPhoneNumberTranslationCallback() { + @Override + public String onValueReceived( + String rawValue, int type, String label, boolean isPrimary) { + // 'p' and 'w' are the standard characters for pause and + // wait + // (see RFC 3601) + // so use those when exporting phone numbers via vCard. + String numberWithControlSequence = + rawValue.replace(PhoneNumberUtils.PAUSE, 'p') + .replace(PhoneNumberUtils.WAIT, 'w'); + return numberWithControlSequence; + } + }); buffer = new HandlerForStringBuffer(op, ownerVCard); Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount()); if (!composer.init(contactIdCursor) || !buffer.init()) { @@ -832,8 +911,10 @@ public class BluetoothPbapVcardManager { BluetoothPbapObexServer.sIsAborted = false; break; } - String vcard = composer.buildVCard(RawContactsEntity.queryRawContactEntity( - mResolver, contactIdCursor.getLong(idColumn))); + String vcard = + composer.buildVCard( + RawContactsEntity.queryRawContactEntity( + mResolver, contactIdCursor.getLong(idColumn))); if (!contactIdCursor.moveToNext()) { Log.i(TAG, "Cursor#moveToNext() returned false"); } @@ -871,15 +952,26 @@ public class BluetoothPbapVcardManager { } } - Log.v(TAG, "Total vcard composing and sending out takes " + (System.currentTimeMillis() - - timestamp) + " ms"); + Log.v( + TAG, + "Total vcard composing and sending out takes " + + (System.currentTimeMillis() - timestamp) + + " ms"); return ResponseCodes.OBEX_HTTP_OK; } - private int composeContactsAndSendSelectedVCards(Operation op, final Cursor contactIdCursor, - final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, - boolean ignorefilter, byte[] filter, byte[] selector, String vcardselectorop) { + private int composeContactsAndSendSelectedVCards( + Operation op, + final Cursor contactIdCursor, + final boolean vcardType21, + String ownerVCard, + int needSendBody, + int pbSize, + boolean ignorefilter, + byte[] filter, + byte[] selector, + String vcardselectorop) { long timestamp = System.currentTimeMillis(); VCardComposer composer = null; @@ -907,17 +999,19 @@ public class BluetoothPbapVcardManager { /* BT does want PAUSE/WAIT conversion while it doesn't want the * other formatting done by vCard library by default. */ - composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { - @Override - public String onValueReceived(String rawValue, int type, String label, - boolean isPrimary) { - /* 'p' and 'w' are the standard characters for pause and wait - * (see RFC 3601) so use those when exporting phone numbers via vCard.*/ - String numberWithControlSequence = rawValue.replace(PhoneNumberUtils.PAUSE, 'p') - .replace(PhoneNumberUtils.WAIT, 'w'); - return numberWithControlSequence; - } - }); + composer.setPhoneNumberTranslationCallback( + new VCardPhoneNumberTranslationCallback() { + @Override + public String onValueReceived( + String rawValue, int type, String label, boolean isPrimary) { + /* 'p' and 'w' are the standard characters for pause and wait + * (see RFC 3601) so use those when exporting phone numbers via vCard.*/ + String numberWithControlSequence = + rawValue.replace(PhoneNumberUtils.PAUSE, 'p') + .replace(PhoneNumberUtils.WAIT, 'w'); + return numberWithControlSequence; + } + }); buffer = new HandlerForStringBuffer(op, ownerVCard); Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount()); if (!composer.init(contactIdCursor) || !buffer.init()) { @@ -934,8 +1028,10 @@ public class BluetoothPbapVcardManager { BluetoothPbapObexServer.sIsAborted = false; break; } - String vcard = composer.buildVCard(RawContactsEntity.queryRawContactEntity( - mResolver, contactIdCursor.getLong(idColumn))); + String vcard = + composer.buildVCard( + RawContactsEntity.queryRawContactEntity( + mResolver, contactIdCursor.getLong(idColumn))); if (!contactIdCursor.moveToNext()) { Log.i(TAG, "Cursor#moveToNext() returned false"); } @@ -994,15 +1090,26 @@ public class BluetoothPbapVcardManager { } } - Log.v(TAG, "Total vcard composing and sending out takes " + (System.currentTimeMillis() - - timestamp) + " ms"); + Log.v( + TAG, + "Total vcard composing and sending out takes " + + (System.currentTimeMillis() - timestamp) + + " ms"); return ResponseCodes.OBEX_HTTP_OK; } - private int composeCallLogsAndSendSelectedVCards(Operation op, final String selection, - final boolean vcardType21, int needSendBody, int pbSize, String ownerVCard, - boolean ignorefilter, byte[] filter, byte[] selector, String vcardselectorop, + private int composeCallLogsAndSendSelectedVCards( + Operation op, + final String selection, + final boolean vcardType21, + int needSendBody, + int pbSize, + String ownerVCard, + boolean ignorefilter, + byte[] filter, + byte[] selector, + String vcardselectorop, boolean vCardSelct) { long timestamp = System.currentTimeMillis(); @@ -1041,8 +1148,10 @@ public class BluetoothPbapVcardManager { } if (needSendBody == NEED_SEND_BODY) { if (vcard == null) { - Log.e(TAG, "Failed to read a contact. Error reason: " - + composer.getErrorReason()); + Log.e( + TAG, + "Failed to read a contact. Error reason: " + + composer.getErrorReason()); ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, @@ -1062,8 +1171,10 @@ public class BluetoothPbapVcardManager { } } else { if (vcard == null) { - Log.e(TAG, "Failed to read a contact. Error reason: " - + composer.getErrorReason()); + Log.e( + TAG, + "Failed to read a contact. Error reason: " + + composer.getErrorReason()); ContentProfileErrorReportUtils.report( BluetoothProfile.PBAP, BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, @@ -1089,8 +1200,11 @@ public class BluetoothPbapVcardManager { } } - Log.v(TAG, "Total vcard composing and sending out takes " + (System.currentTimeMillis() - - timestamp) + " ms"); + Log.v( + TAG, + "Total vcard composing and sending out takes " + + (System.currentTimeMillis() - timestamp) + + " ms"); return ResponseCodes.OBEX_HTTP_OK; } @@ -1103,14 +1217,20 @@ public class BluetoothPbapVcardManager { String[] vTagAndTel = attr[i].split(":", 2); int telLenBefore = vTagAndTel[1].length(); // Remove '-', '(', ')' or ' ' from TEL number - vTagAndTel[1] = vTagAndTel[1].replace("-", "") - .replace("(", "") - .replace(")", "") - .replace(" ", ""); + vTagAndTel[1] = + vTagAndTel[1] + .replace("-", "") + .replace("(", "") + .replace(")", "") + .replace(" ", ""); if (vTagAndTel[1].length() < telLenBefore) { Log.v(TAG, "Fixing vCard TEL to " + vTagAndTel[1]); - attr[i] = new StringBuilder().append(vTagAndTel[0]).append(":") - .append(vTagAndTel[1]).toString(); + attr[i] = + new StringBuilder() + .append(vTagAndTel[0]) + .append(":") + .append(vTagAndTel[1]) + .toString(); } } } @@ -1156,7 +1276,7 @@ public class BluetoothPbapVcardManager { private static final String SEPARATOR = System.getProperty("line.separator"); private final byte[] mFilter; - //This function returns true if the attributes needs to be included in the filtered vcard. + // This function returns true if the attributes needs to be included in the filtered vcard. private boolean isFilteredIn(FilterBit bit, boolean vCardType21) { final int offset = (bit.pos / 8) + 1; final int bitPos = bit.pos % 8; @@ -1312,8 +1432,8 @@ public class BluetoothPbapVcardManager { } /** - * Get size of the cursor without duplicated contact id. This assumes the - * given cursor is sorted by CONTACT_ID. + * Get size of the cursor without duplicated contact id. This assumes the given cursor is sorted + * by CONTACT_ID. */ private static int getDistinctContactIdSize(Cursor cursor) { final int contactIdColumn = cursor.getColumnIndex(Data.CONTACT_ID); @@ -1334,11 +1454,11 @@ public class BluetoothPbapVcardManager { } /** - * Append "display_name,contact_id" string array from cursor to ArrayList. - * This assumes the given cursor is sorted by CONTACT_ID. + * Append "display_name,contact_id" string array from cursor to ArrayList. This assumes the + * given cursor is sorted by CONTACT_ID. */ - private static void appendDistinctNameIdList(ArrayList resultList, String defaultName, - Cursor cursor) { + private static void appendDistinctNameIdList( + ArrayList resultList, String defaultName, Cursor cursor) { final int contactIdColumn = cursor.getColumnIndex(Data.CONTACT_ID); final int idColumn = cursor.getColumnIndex(Data._ID); final int nameColumn = cursor.getColumnIndex(Data.DISPLAY_NAME); diff --git a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java index 133f7e3c711..5263837bf42 100644 --- a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java +++ b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java @@ -54,17 +54,8 @@ import com.android.obex.ServerSession; import java.io.IOException; /** - * Bluetooth PBAP StateMachine - * (New connection socket) - * WAITING FOR AUTH - * | - * | (request permission from Settings UI) - * | - * (Accept) / \ (Reject) - * / \ - * v v - * CONNECTED -----> FINISHED - * (OBEX Server done) + * Bluetooth PBAP StateMachine (New connection socket) WAITING FOR AUTH | | (request permission from + * Settings UI) | (Accept) / \ (Reject) / \ v v CONNECTED -----> FINISHED (OBEX Server done) */ // Next tag value for ContentProfileErrorReportUtils.report(): 3 @VisibleForTesting(visibility = Visibility.PACKAGE) @@ -81,10 +72,7 @@ public class PbapStateMachine extends StateMachine { static final int AUTH_KEY_INPUT = 7; static final int AUTH_CANCELLED = 8; - /** - * Used to limit PBAP OBEX maximum packet size in order to reduce - * transaction time. - */ + /** Used to limit PBAP OBEX maximum packet size in order to reduce transaction time. */ private static final int PBAP_OBEX_MAXIMUM_PACKET_SIZE = 8192; private BluetoothPbapService mService; @@ -149,9 +137,9 @@ public class PbapStateMachine extends StateMachine { * Get a state value from {@link BluetoothProfile} that represents the connection state of * this headset state * - * @return a value in {@link BluetoothProfile#STATE_DISCONNECTED}, - * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or - * {@link BluetoothProfile#STATE_DISCONNECTING} + * @return a value in {@link BluetoothProfile#STATE_DISCONNECTED}, {@link + * BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or + * {@link BluetoothProfile#STATE_DISCONNECTING} */ abstract int getConnectionStateInt(); @@ -190,17 +178,20 @@ public class PbapStateMachine extends StateMachine { Utils.getTempBroadcastOptions().toBundle()); } - /** - * Broadcast connection state change for this state machine - */ + /** Broadcast connection state change for this state machine */ void broadcastStateTransitions() { int prevStateInt = BluetoothProfile.STATE_DISCONNECTED; if (mPrevState != null) { prevStateInt = mPrevState.getConnectionStateInt(); } if (getConnectionStateInt() != prevStateInt) { - stateLogD("connection state changed: " + mRemoteDevice + ": " + mPrevState + " -> " - + this); + stateLogD( + "connection state changed: " + + mRemoteDevice + + ": " + + mPrevState + + " -> " + + this); broadcastConnectionState(mRemoteDevice, prevStateInt, getConnectionStateInt()); } } @@ -209,9 +200,8 @@ public class PbapStateMachine extends StateMachine { * Verify if the current state transition is legal by design. This is called from enter() * method and crash if the state transition is not expected by the state machine design. * - * Note: - * This method uses state objects to verify transition because these objects should be final - * and any other instances are invalid + *

Note: This method uses state objects to verify transition because these objects should + * be final and any other instances are invalid */ private void enforceValidConnectionStateTransition() { boolean isValidTransition = false; @@ -224,8 +214,12 @@ public class PbapStateMachine extends StateMachine { } if (!isValidTransition) { throw new IllegalStateException( - "Invalid state transition from " + mPrevState + " to " + this - + " for device " + mRemoteDevice); + "Invalid state transition from " + + mPrevState + + " to " + + this + + " for device " + + mRemoteDevice); } } @@ -260,10 +254,11 @@ public class PbapStateMachine extends StateMachine { transitionTo(mFinished); break; case DISCONNECT: - mServiceHandler.removeMessages(BluetoothPbapService.USER_TIMEOUT, - PbapStateMachine.this); - mServiceHandler.obtainMessage(BluetoothPbapService.USER_TIMEOUT, - PbapStateMachine.this).sendToTarget(); + mServiceHandler.removeMessages( + BluetoothPbapService.USER_TIMEOUT, PbapStateMachine.this); + mServiceHandler + .obtainMessage(BluetoothPbapService.USER_TIMEOUT, PbapStateMachine.this) + .sendToTarget(); transitionTo(mFinished); break; } @@ -273,8 +268,11 @@ public class PbapStateMachine extends StateMachine { private void rejectConnection() { mPbapServer = new BluetoothPbapObexServer(mServiceHandler, mService, PbapStateMachine.this); - BluetoothObexTransport transport = new BluetoothObexTransport(mConnSocket, - PBAP_OBEX_MAXIMUM_PACKET_SIZE, BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED); + BluetoothObexTransport transport = + new BluetoothObexTransport( + mConnSocket, + PBAP_OBEX_MAXIMUM_PACKET_SIZE, + BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED); ObexRejectServer server = new ObexRejectServer(ResponseCodes.OBEX_HTTP_UNAVAILABLE, mConnSocket); try { @@ -318,8 +316,10 @@ public class PbapStateMachine extends StateMachine { Log.e(TAG, "Close Connection Socket error: " + e.toString()); } - mServiceHandler.obtainMessage(BluetoothPbapService.MSG_STATE_MACHINE_DONE, - PbapStateMachine.this).sendToTarget(); + mServiceHandler + .obtainMessage( + BluetoothPbapService.MSG_STATE_MACHINE_DONE, PbapStateMachine.this) + .sendToTarget(); broadcastStateTransitions(); } } @@ -344,8 +344,7 @@ public class PbapStateMachine extends StateMachine { } broadcastStateTransitions(); MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PBAP); - mService.setConnectionPolicy( - mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + mService.setConnectionPolicy(mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); } @Override @@ -388,8 +387,11 @@ public class PbapStateMachine extends StateMachine { mObexAuth.setChallenged(false); mObexAuth.setCancelled(false); } - BluetoothObexTransport transport = new BluetoothObexTransport(mConnSocket, - PBAP_OBEX_MAXIMUM_PACKET_SIZE, BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED); + BluetoothObexTransport transport = + new BluetoothObexTransport( + mConnSocket, + PBAP_OBEX_MAXIMUM_PACKET_SIZE, + BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED); mServerSession = new ServerSession(transport, mPbapServer, mObexAuth); // It's ok to just use one wake lock // Message MSG_ACQUIRE_WAKE_LOCK is always surrounded by RELEASE. safe. @@ -403,7 +405,8 @@ public class PbapStateMachine extends StateMachine { private void createPbapNotification() { NotificationManager nm = mService.getSystemService(NotificationManager.class); NotificationChannel notificationChannel = - new NotificationChannel(PBAP_OBEX_NOTIFICATION_CHANNEL, + new NotificationChannel( + PBAP_OBEX_NOTIFICATION_CHANNEL, mService.getString(R.string.pbap_notification_group), NotificationManager.IMPORTANCE_HIGH); nm.createNotificationChannel(notificationChannel); @@ -424,25 +427,29 @@ public class PbapStateMachine extends StateMachine { String name = Utils.getName(mRemoteDevice); Notification notification = - new Notification.Builder(mService, PBAP_OBEX_NOTIFICATION_CHANNEL).setWhen( - System.currentTimeMillis()) + new Notification.Builder(mService, PBAP_OBEX_NOTIFICATION_CHANNEL) + .setWhen(System.currentTimeMillis()) .setContentTitle(mService.getString(R.string.auth_notif_title)) .setContentText(mService.getString(R.string.auth_notif_message, name)) .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth) .setTicker(mService.getString(R.string.auth_notif_ticker)) - .setColor(mService.getResources() - .getColor( - android.R.color - .system_notification_accent_color, - mService.getTheme())) + .setColor( + mService.getResources() + .getColor( + android.R.color + .system_notification_accent_color, + mService.getTheme())) .setFlag(Notification.FLAG_AUTO_CANCEL, true) .setFlag(Notification.FLAG_ONLY_ALERT_ONCE, true) .setContentIntent( - PendingIntent.getActivity(mService, 0, clickIntent, - PendingIntent.FLAG_IMMUTABLE)) + PendingIntent.getActivity( + mService, 0, clickIntent, PendingIntent.FLAG_IMMUTABLE)) .setDeleteIntent( - PendingIntent.getBroadcast(mService, 0, deleteIntent, - PendingIntent.FLAG_IMMUTABLE)) + PendingIntent.getBroadcast( + mService, + 0, + deleteIntent, + PendingIntent.FLAG_IMMUTABLE)) .setLocalOnly(true) .build(); nm.notify(mNotificationId, notification); @@ -468,9 +475,9 @@ public class PbapStateMachine extends StateMachine { /** * Get the current connection state of this state machine * - * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, - * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or - * {@link BluetoothProfile#STATE_DISCONNECTING} + * @return current connection state, one of {@link BluetoothProfile#STATE_DISCONNECTED}, {@link + * BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, or {@link + * BluetoothProfile#STATE_DISCONNECTING} */ synchronized int getConnectionState() { PbapStateBase state = (PbapStateBase) getCurrentState(); diff --git a/android/app/src/com/android/bluetooth/pbapclient/Authenticator.java b/android/app/src/com/android/bluetooth/pbapclient/Authenticator.java index ee06984bfde..899e2e633fc 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/Authenticator.java +++ b/android/app/src/com/android/bluetooth/pbapclient/Authenticator.java @@ -40,8 +40,9 @@ public class Authenticator extends AbstractAccountAuthenticator { // Don't add additional accounts @Override - public Bundle addAccount(AccountAuthenticatorResponse r, String s, String s2, String[] strings, - Bundle bundle) throws NetworkErrorException { + public Bundle addAccount( + AccountAuthenticatorResponse r, String s, String s2, String[] strings, Bundle bundle) + throws NetworkErrorException { Log.d(TAG, "got call", new Exception()); // Don't allow accounts to be added. throw new UnsupportedOperationException(); @@ -57,8 +58,9 @@ public class Authenticator extends AbstractAccountAuthenticator { // Getting an authentication token is not supported @Override - public Bundle getAuthToken(AccountAuthenticatorResponse r, Account account, String s, - Bundle bundle) throws NetworkErrorException { + public Bundle getAuthToken( + AccountAuthenticatorResponse r, Account account, String s, Bundle bundle) + throws NetworkErrorException { Log.d(TAG, "got call", new Exception()); throw new UnsupportedOperationException(); } @@ -72,8 +74,9 @@ public class Authenticator extends AbstractAccountAuthenticator { // Updating user credentials is not supported @Override - public Bundle updateCredentials(AccountAuthenticatorResponse r, Account account, String s, - Bundle bundle) throws NetworkErrorException { + public Bundle updateCredentials( + AccountAuthenticatorResponse r, Account account, String s, Bundle bundle) + throws NetworkErrorException { Log.d(TAG, "got call", new Exception()); return null; } diff --git a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java index 920a724354b..a062efb6041 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java +++ b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java @@ -31,13 +31,12 @@ import java.util.Arrays; class BluetoothPbapObexAuthenticator implements Authenticator { private static final String TAG = "PbapClientObexAuth"; - //Default session key for legacy devices is 0000 - @VisibleForTesting - String mSessionKey = "0000"; + // Default session key for legacy devices is 0000 + @VisibleForTesting String mSessionKey = "0000"; @Override - public PasswordAuthentication onAuthenticationChallenge(String description, - boolean isUserIdRequired, boolean isFullAccess) { + public PasswordAuthentication onAuthenticationChallenge( + String description, boolean isUserIdRequired, boolean isFullAccess) { PasswordAuthentication pa = null; Log.d(TAG, "onAuthenticationChallenge: starting"); @@ -45,8 +44,7 @@ class BluetoothPbapObexAuthenticator implements Authenticator { Log.d(TAG, "onAuthenticationChallenge: mSessionKey=" + mSessionKey); pa = new PasswordAuthentication(null, mSessionKey.getBytes()); } else { - Log.d(TAG, - "onAuthenticationChallenge: mSessionKey is empty, timeout/cancel occurred"); + Log.d(TAG, "onAuthenticationChallenge: mSessionKey is empty, timeout/cancel occurred"); } return pa; diff --git a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java index 5b46c30da9c..998309dfc1d 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java +++ b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java @@ -40,8 +40,13 @@ final class BluetoothPbapRequestPullPhoneBook extends BluetoothPbapRequest { private final byte mFormat; - BluetoothPbapRequestPullPhoneBook(String pbName, Account account, long filter, byte format, - int maxListCount, int listStartOffset) { + BluetoothPbapRequestPullPhoneBook( + String pbName, + Account account, + long filter, + byte format, + int maxListCount, + int listStartOffset) { mAccount = account; if (maxListCount < 0 || maxListCount > 65535) { throw new IllegalArgumentException("maxListCount should be [0..65535]"); diff --git a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java index 4b2a5d99c1a..96f960ad71d 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java +++ b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java @@ -44,8 +44,7 @@ class BluetoothPbapVcardList { class CardEntryHandler implements VCardEntryHandler { @Override - public void onStart() { - } + public void onStart() {} @Override public void onEntryCreated(VCardEntry entry) { @@ -53,8 +52,7 @@ class BluetoothPbapVcardList { } @Override - public void onEnd() { - } + public void onEnd() {} } BluetoothPbapVcardList(Account account, InputStream in, byte format) throws IOException { @@ -116,8 +114,8 @@ class BluetoothPbapVcardList { * * @param parser -- the {@link VCardParser} to use. * @param in -- the {@link InputStream} to parse. - * @return {@code true} if there was a {@link VCardVersionException}; {@code false} if there - * is any other {@link VCardException} or succeeds (i.e., no {@link VCardException}). + * @return {@code true} if there was a {@link VCardVersionException}; {@code false} if there is + * any other {@link VCardException} or succeeds (i.e., no {@link VCardException}). * @throws IOException if there's an issue reading the {@link InputStream}. */ private boolean parsedWithVcardVersionException(VCardParser parser, InputStream in) diff --git a/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java b/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java index d2a3202d39e..16256710d2b 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java +++ b/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java @@ -43,16 +43,15 @@ import java.util.List; public class CallLogPullRequest extends PullRequest { private static final String TAG = "CallLogPullRequest"; - @VisibleForTesting - static final String TIMESTAMP_PROPERTY = "X-IRMC-CALL-DATETIME"; + @VisibleForTesting static final String TIMESTAMP_PROPERTY = "X-IRMC-CALL-DATETIME"; private static final String TIMESTAMP_FORMAT = "yyyyMMdd'T'HHmmss"; private final Account mAccount; private Context mContext; private HashMap mCallCounter; - public CallLogPullRequest(Context context, String path, HashMap map, - Account account) { + public CallLogPullRequest( + Context context, String path, HashMap map, Account account) { mContext = context; this.path = path; mCallCounter = map; @@ -87,7 +86,8 @@ public class CallLogPullRequest extends PullRequest { values.put(CallLog.Calls.TYPE, type); values.put(Calls.PHONE_ACCOUNT_ID, mAccount.name); List phones = vcard.getPhoneList(); - if (phones == null || phones.get(0).getNumber().equals(";") + if (phones == null + || phones.get(0).getNumber().equals(";") || phones.get(0).getNumber().length() == 0) { values.put(CallLog.Calls.NUMBER, ""); } else { @@ -113,14 +113,15 @@ public class CallLogPullRequest extends PullRequest { } } } - ops.add(ContentProviderOperation.newInsert(CallLog.Calls.CONTENT_URI) - .withValues(values) - .withYieldAllowed(true) - .build()); + ops.add( + ContentProviderOperation.newInsert(CallLog.Calls.CONTENT_URI) + .withValues(values) + .withYieldAllowed(true) + .build()); } mContext.getContentResolver().applyBatch(CallLog.AUTHORITY, ops); Log.d(TAG, "Updated call logs."); - //OUTGOING_TYPE is the last callLog we fetched. + // OUTGOING_TYPE is the last callLog we fetched. if (type == CallLog.Calls.OUTGOING_TYPE) { updateTimesContacted(); } @@ -138,22 +139,24 @@ public class CallLogPullRequest extends PullRequest { for (String key : mCallCounter.keySet()) { ContentValues values = new ContentValues(); values.put(ContactsContract.RawContacts.TIMES_CONTACTED, mCallCounter.get(key)); - Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, - Uri.encode(key)); - try (Cursor c = BluetoothMethodProxy.getInstance().contentResolverQuery( - mContext.getContentResolver(), uri, null, null, null)) { + Uri uri = + Uri.withAppendedPath( + ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(key)); + try (Cursor c = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mContext.getContentResolver(), uri, null, null, null)) { if (c != null && c.getCount() > 0) { c.moveToNext(); - String contactId = c.getString(c.getColumnIndex( - ContactsContract.PhoneLookup.CONTACT_ID)); + String contactId = + c.getString(c.getColumnIndex(ContactsContract.PhoneLookup.CONTACT_ID)); Log.d(TAG, "onPullComplete: ID " + contactId + " key : " + key); String where = ContactsContract.RawContacts.CONTACT_ID + "=" + contactId; - mContext.getContentResolver().update( - ContactsContract.RawContacts.CONTENT_URI, values, where, null); + mContext.getContentResolver() + .update(ContactsContract.RawContacts.CONTENT_URI, values, where, null); } } } Log.d(TAG, "Updated TIMES_CONTACTED"); } - } diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java index e259e2d3e4a..519b03c2d79 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java @@ -65,24 +65,25 @@ class PbapClientConnectionHandler extends Handler { // The following constants are pulled from the Bluetooth Phone Book Access Profile specification // 1.1 - private static final byte[] PBAP_TARGET = new byte[]{ - 0x79, - 0x61, - 0x35, - (byte) 0xf0, - (byte) 0xf0, - (byte) 0xc5, - 0x11, - (byte) 0xd8, - 0x09, - 0x66, - 0x08, - 0x00, - 0x20, - 0x0c, - (byte) 0x9a, - 0x66 - }; + private static final byte[] PBAP_TARGET = + new byte[] { + 0x79, + 0x61, + 0x35, + (byte) 0xf0, + (byte) 0xf0, + (byte) 0xc5, + 0x11, + (byte) 0xd8, + 0x09, + 0x66, + 0x08, + 0x00, + 0x20, + 0x0c, + (byte) 0x9a, + 0x66 + }; private static final int PBAP_FEATURE_DEFAULT_IMAGE_FORMAT = 0x00000200; private static final int PBAP_FEATURE_DOWNLOADING = 0x00000001; @@ -99,11 +100,16 @@ class PbapClientConnectionHandler extends Handler { private static final int PBAP_SUPPORTED_FEATURE = PBAP_FEATURE_DEFAULT_IMAGE_FORMAT | PBAP_FEATURE_DOWNLOADING; private static final long PBAP_REQUESTED_FIELDS = - PBAP_FILTER_VERSION | PBAP_FILTER_FN | PBAP_FILTER_N | PBAP_FILTER_PHOTO - | PBAP_FILTER_ADR | PBAP_FILTER_EMAIL | PBAP_FILTER_TEL | PBAP_FILTER_NICKNAME; + PBAP_FILTER_VERSION + | PBAP_FILTER_FN + | PBAP_FILTER_N + | PBAP_FILTER_PHOTO + | PBAP_FILTER_ADR + | PBAP_FILTER_EMAIL + | PBAP_FILTER_TEL + | PBAP_FILTER_NICKNAME; - @VisibleForTesting - static final int L2CAP_INVALID_PSM = -1; + @VisibleForTesting static final int L2CAP_INVALID_PSM = -1; public static final String PB_PATH = "telecom/pb.vcf"; public static final String FAV_PATH = "telecom/fav.vcf"; @@ -139,7 +145,7 @@ class PbapClientConnectionHandler extends Handler { /** * Constructs PCEConnectionHandler object * - * @param Builder To build BluetoothPbapClientHandler Instance. + * @param Builder To build BluetoothPbapClientHandler Instance. */ PbapClientConnectionHandler(Builder pceHandlerbuild) { super(pceHandlerbuild.mLooper); @@ -183,7 +189,6 @@ class PbapClientConnectionHandler extends Handler { PbapClientConnectionHandler pbapClientHandler = new PbapClientConnectionHandler(this); return pbapClientHandler; } - } @Override @@ -324,7 +329,8 @@ class PbapClientConnectionHandler extends Handler { ObexAppParameters oap = new ObexAppParameters(); if (mPseRec.getProfileVersion() >= PBAP_V1_2) { - oap.add(BluetoothPbapRequest.OAP_TAGID_PBAP_SUPPORTED_FEATURES, + oap.add( + BluetoothPbapRequest.OAP_TAGID_PBAP_SUPPORTED_FEATURES, PBAP_SUPPORTED_FEATURE); } @@ -373,8 +379,7 @@ class PbapClientConnectionHandler extends Handler { // Download contacts in batches of size DEFAULT_BATCH_SIZE BluetoothPbapRequestPullPhoneBookSize requestPbSize = - new BluetoothPbapRequestPullPhoneBookSize(path, - PBAP_REQUESTED_FIELDS); + new BluetoothPbapRequestPullPhoneBookSize(path, PBAP_REQUESTED_FIELDS); requestPbSize.execute(mObexSession); int numberOfContactsRemaining = requestPbSize.getSize(); @@ -390,12 +395,17 @@ class PbapClientConnectionHandler extends Handler { while ((numberOfContactsRemaining > 0) && (startOffset <= UPPER_LIMIT)) { int numberOfContactsToDownload = - Math.min(Math.min(DEFAULT_BATCH_SIZE, numberOfContactsRemaining), - UPPER_LIMIT - startOffset + 1); + Math.min( + Math.min(DEFAULT_BATCH_SIZE, numberOfContactsRemaining), + UPPER_LIMIT - startOffset + 1); BluetoothPbapRequestPullPhoneBook request = - new BluetoothPbapRequestPullPhoneBook(path, mAccount, - PBAP_REQUESTED_FIELDS, VCARD_TYPE_30, - numberOfContactsToDownload, startOffset); + new BluetoothPbapRequestPullPhoneBook( + path, + mAccount, + PBAP_REQUESTED_FIELDS, + VCARD_TYPE_30, + numberOfContactsToDownload, + startOffset); request.execute(mObexSession); ArrayList vcards = request.getList(); if (path == FAV_PATH) { @@ -427,8 +437,8 @@ class PbapClientConnectionHandler extends Handler { new BluetoothPbapRequestPullPhoneBook(path, mAccount, 0, VCARD_TYPE_30, 0, 0); request.execute(mObexSession); CallLogPullRequest processor = - new CallLogPullRequest(mPbapClientStateMachine.getContext(), path, - callCounter, mAccount); + new CallLogPullRequest( + mPbapClientStateMachine.getContext(), path, callCounter, mAccount); processor.setResults(request.getList()); processor.onPullComplete(); } catch (IOException e) { @@ -464,8 +474,11 @@ class PbapClientConnectionHandler extends Handler { Log.d(TAG, "CallLog ContentResolver is not found"); return; } - mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, - Calls.PHONE_ACCOUNT_ID + "=?", new String[]{mAccount.name}); + mContext.getContentResolver() + .delete( + CallLog.Calls.CONTENT_URI, + Calls.PHONE_ACCOUNT_ID + "=?", + new String[] {mAccount.name}); } catch (IllegalArgumentException e) { Log.d(TAG, "Call Logs could not be deleted, they may not exist yet."); } diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java index 74174159278..d3a8665495c 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java @@ -60,20 +60,19 @@ public class PbapClientService extends ProfileService { private static final String SERVICE_NAME = "Phonebook Access PCE"; - /** - * The component names for the owned authenticator service - */ + /** The component names for the owned authenticator service */ private static final String AUTHENTICATOR_SERVICE = AuthenticationService.class.getCanonicalName(); // MAXIMUM_DEVICES set to 10 to prevent an excessive number of simultaneous devices. private static final int MAXIMUM_DEVICES = 10; + @VisibleForTesting Map mPbapClientStateMachineMap = new ConcurrentHashMap<>(); + private static PbapClientService sPbapClientService; - @VisibleForTesting - PbapBroadcastReceiver mPbapBroadcastReceiver = new PbapBroadcastReceiver(); + @VisibleForTesting PbapBroadcastReceiver mPbapBroadcastReceiver = new PbapBroadcastReceiver(); private int mSdpHandle = -1; private DatabaseManager mDatabaseManager; @@ -219,8 +218,8 @@ public class PbapClientService extends ProfileService { * Determine if our account type is visible to us yet. If it is, then our service is ready and * our account type is ready to use. * - * Make a placeholder device account and determine our visibility relative to it. Note that this - * function uses the same restrictions as the other add and remove functions, but is *also* + *

Make a placeholder device account and determine our visibility relative to it. Note that + * this function uses the same restrictions as the other add and remove functions, but is *also* * available to all system apps instead of throwing a runtime SecurityException. */ protected boolean isAuthenticationServiceReady() { @@ -246,8 +245,11 @@ public class PbapClientService extends ProfileService { for (Account acc : accounts) { Log.w(TAG, "Deleting " + acc); try { - getContentResolver().delete(CallLog.Calls.CONTENT_URI, - CallLog.Calls.PHONE_ACCOUNT_ID + "=?", new String[]{acc.name}); + getContentResolver() + .delete( + CallLog.Calls.CONTENT_URI, + CallLog.Calls.PHONE_ACCOUNT_ID + "=?", + new String[] {acc.name}); } catch (IllegalArgumentException e) { Log.w(TAG, "Call Logs could not be deleted, they may not exist yet."); } @@ -261,12 +263,19 @@ public class PbapClientService extends ProfileService { // Delete call logs belonging to accountName==BD_ADDR that also match // component name "hfpclient". ComponentName componentName = new ComponentName(context, HfpClientConnectionService.class); - String selectionFilter = CallLog.Calls.PHONE_ACCOUNT_ID + "=? AND " - + CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME + "=?"; - String[] selectionArgs = new String[]{accountName, componentName.flattenToString()}; + String selectionFilter = + CallLog.Calls.PHONE_ACCOUNT_ID + + "=? AND " + + CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME + + "=?"; + String[] selectionArgs = new String[] {accountName, componentName.flattenToString()}; try { - BluetoothMethodProxy.getInstance().contentResolverDelete(getContentResolver(), - CallLog.Calls.CONTENT_URI, selectionFilter, selectionArgs); + BluetoothMethodProxy.getInstance() + .contentResolverDelete( + getContentResolver(), + CallLog.Calls.CONTENT_URI, + selectionFilter, + selectionArgs); } catch (IllegalArgumentException e) { Log.w(TAG, "Call Logs could not be deleted, they may not exist yet."); } @@ -355,9 +364,7 @@ public class PbapClientService extends ProfileService { } } - /** - * Handler for incoming service calls - */ + /** Handler for incoming service calls */ @VisibleForTesting static class BluetoothPbapClientBinder extends IBluetoothPbapClient.Stub implements IProfileServiceBinder { @@ -459,8 +466,6 @@ public class PbapClientService extends ProfileService { return service.getConnectionPolicy(device); } - - } // API methods @@ -487,8 +492,8 @@ public class PbapClientService extends ProfileService { if (device == null) { throw new IllegalArgumentException("Null device"); } - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Received request to ConnectPBAPPhonebook " + device.getAddress()); if (getConnectionPolicy(device) <= BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { return false; @@ -519,8 +524,8 @@ public class PbapClientService extends ProfileService { if (device == null) { throw new IllegalArgumentException("Null device"); } - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); PbapClientStateMachine pbapClientStateMachine = mPbapClientStateMachineMap.get(device); if (pbapClientStateMachine != null) { pbapClientStateMachine.disconnect(device); @@ -540,8 +545,7 @@ public class PbapClientService extends ProfileService { List getDevicesMatchingConnectionStates(int[] states) { List deviceList = new ArrayList(0); for (Map.Entry stateMachineEntry : - mPbapClientStateMachineMap - .entrySet()) { + mPbapClientStateMachineMap.entrySet()) { int currentDeviceState = stateMachineEntry.getValue().getConnectionState(); for (int state : states) { if (currentDeviceState == state) { @@ -560,8 +564,13 @@ public class PbapClientService extends ProfileService { Log.e(TAG, "No Statemachine found for the device=" + device.toString()); return; } - Log.v(TAG, "Received SDP record for UUID=" + uuid.toString() + " (expected UUID=" - + BluetoothUuid.PBAP_PSE.toString() + ")"); + Log.v( + TAG, + "Received SDP record for UUID=" + + uuid.toString() + + " (expected UUID=" + + BluetoothUuid.PBAP_PSE.toString() + + ")"); if (uuid.equals(BluetoothUuid.PBAP_PSE)) { stateMachine .obtainMessage(PbapClientStateMachine.MSG_SDP_COMPLETE, record) @@ -573,10 +582,10 @@ public class PbapClientService extends ProfileService { * Get the current connection state of the profile * * @param device is the remote bluetooth device - * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, - * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected, - * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or - * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected + * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link + * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link + * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link + * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { if (device == null) { @@ -591,15 +600,14 @@ public class PbapClientService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -610,12 +618,12 @@ public class PbapClientService extends ProfileService { if (device == null) { throw new IllegalArgumentException("Null device"); } - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.PBAP_CLIENT, - connectionPolicy)) { + if (!mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.PBAP_CLIENT, connectionPolicy)) { return false; } if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { @@ -629,10 +637,9 @@ public class PbapClientService extends ProfileService { /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device @@ -642,10 +649,9 @@ public class PbapClientService extends ProfileService { if (device == null) { throw new IllegalArgumentException("Null device"); } - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - return mDatabaseManager - .getProfileConnectionPolicy(device, BluetoothProfile.PBAP_CLIENT); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.PBAP_CLIENT); } @Override diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java index f4a1ef6bf4d..2c8a441056e 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java @@ -111,7 +111,9 @@ class PbapClientStateMachine extends StateMachine { } @VisibleForTesting - PbapClientStateMachine(PbapClientService svc, BluetoothDevice device, + PbapClientStateMachine( + PbapClientService svc, + BluetoothDevice device, PbapClientConnectionHandler connectionHandler) { super(TAG); @@ -137,8 +139,8 @@ class PbapClientStateMachine extends StateMachine { @Override public void enter() { Log.d(TAG, "Enter Disconnected: " + getCurrentMessage().what); - onConnectionStateChanged(mCurrentDevice, mMostRecentState, - BluetoothProfile.STATE_DISCONNECTED); + onConnectionStateChanged( + mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_DISCONNECTED); mMostRecentState = BluetoothProfile.STATE_DISCONNECTED; quit(); } @@ -149,8 +151,8 @@ class PbapClientStateMachine extends StateMachine { @Override public void enter() { Log.d(TAG, "Enter Connecting: " + getCurrentMessage().what); - onConnectionStateChanged(mCurrentDevice, mMostRecentState, - BluetoothProfile.STATE_CONNECTING); + onConnectionStateChanged( + mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTING); mCurrentDevice.sdpSearch(BluetoothUuid.PBAP_PSE); mMostRecentState = BluetoothProfile.STATE_CONNECTING; @@ -180,8 +182,8 @@ class PbapClientStateMachine extends StateMachine { Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName()); switch (message.what) { case MSG_DISCONNECT: - if (message.obj instanceof BluetoothDevice && message.obj.equals( - mCurrentDevice)) { + if (message.obj instanceof BluetoothDevice + && message.obj.equals(mCurrentDevice)) { removeMessages(MSG_CONNECT_TIMEOUT); transitionTo(mDisconnecting); } @@ -219,8 +221,8 @@ class PbapClientStateMachine extends StateMachine { @Override public void enter() { Log.d(TAG, "Enter Disconnecting: " + getCurrentMessage().what); - onConnectionStateChanged(mCurrentDevice, mMostRecentState, - BluetoothProfile.STATE_DISCONNECTING); + onConnectionStateChanged( + mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_DISCONNECTING); mMostRecentState = BluetoothProfile.STATE_DISCONNECTING; PbapClientConnectionHandler connectionHandler = mConnectionHandler; if (connectionHandler != null) { @@ -277,8 +279,8 @@ class PbapClientStateMachine extends StateMachine { @Override public void enter() { Log.d(TAG, "Enter Connected: " + getCurrentMessage().what); - onConnectionStateChanged(mCurrentDevice, mMostRecentState, - BluetoothProfile.STATE_CONNECTED); + onConnectionStateChanged( + mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTED); mMostRecentState = BluetoothProfile.STATE_CONNECTED; downloadIfReady(); } @@ -306,15 +308,17 @@ class PbapClientStateMachine extends StateMachine { } } - /** - * Trigger a contacts download if the user is unlocked and our accounts are available to us - */ + /** Trigger a contacts download if the user is unlocked and our accounts are available to us */ private void downloadIfReady() { boolean userReady = mUserManager.isUserUnlocked(); boolean accountServiceReady = mService.isAuthenticationServiceReady(); if (!userReady || !accountServiceReady) { - Log.w(TAG, "Cannot download contacts yet, userReady=" + userReady - + ", accountServiceReady=" + accountServiceReady); + Log.w( + TAG, + "Cannot download contacts yet, userReady=" + + userReady + + ", accountServiceReady=" + + accountServiceReady); return; } PbapClientConnectionHandler connectionHandler = mConnectionHandler; @@ -344,7 +348,8 @@ class PbapClientStateMachine extends StateMachine { intent.putExtra(BluetoothProfile.EXTRA_STATE, state); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - mService.sendBroadcastMultiplePermissions(intent, + mService.sendBroadcastMultiplePermissions( + intent, new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}, Utils.getTempBroadcastOptions()); } @@ -423,7 +428,6 @@ class PbapClientStateMachine extends StateMachine { return BluetoothProfile.STATE_DISCONNECTED; } - public BluetoothDevice getDevice() { /* * Disconnected is the only state where device can change, and to prevent the race @@ -442,7 +446,13 @@ class PbapClientStateMachine extends StateMachine { } public void dump(StringBuilder sb) { - ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice.getAddress() + "(" - + Utils.getName(mCurrentDevice) + ") " + this.toString()); + ProfileService.println( + sb, + "mCurrentDevice: " + + mCurrentDevice.getAddress() + + "(" + + Utils.getName(mCurrentDevice) + + ") " + + this.toString()); } } diff --git a/android/app/src/com/android/bluetooth/pbapclient/PhonebookPullRequest.java b/android/app/src/com/android/bluetooth/pbapclient/PhonebookPullRequest.java index 5496f7ac936..a0780af69d1 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PhonebookPullRequest.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PhonebookPullRequest.java @@ -31,8 +31,7 @@ import java.util.ArrayList; public class PhonebookPullRequest extends PullRequest { private static final String TAG = "PhonebookPullRequest"; - @VisibleForTesting - static final int MAX_OPS = 250; + @VisibleForTesting static final int MAX_OPS = 250; private final Context mContext; public boolean complete = false; @@ -42,7 +41,6 @@ public class PhonebookPullRequest extends PullRequest { path = PbapClientConnectionHandler.PB_PATH; } - @Override public void onPullComplete() { if (mEntries == null) { diff --git a/android/app/src/com/android/bluetooth/pbapclient/PullRequest.java b/android/app/src/com/android/bluetooth/pbapclient/PullRequest.java index ce5a7a0a5dc..f9381078031 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PullRequest.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PullRequest.java @@ -34,4 +34,3 @@ public abstract class PullRequest { mEntries = results; } } - diff --git a/android/app/src/com/android/bluetooth/sap/ISapRilReceiver.java b/android/app/src/com/android/bluetooth/sap/ISapRilReceiver.java index 01d4c299d18..1acbfdf4746 100644 --- a/android/app/src/com/android/bluetooth/sap/ISapRilReceiver.java +++ b/android/app/src/com/android/bluetooth/sap/ISapRilReceiver.java @@ -18,32 +18,20 @@ package com.android.bluetooth.sap; import android.hardware.radio.sap.ISap; -/** - * ISapRilReceiver is used to send messages - */ +/** ISapRilReceiver is used to send messages */ public interface ISapRilReceiver extends ISap { - /** - * Set mSapProxy to null - */ + /** Set mSapProxy to null */ void resetSapProxy(); - /** - * Notify SapServer that this class is ready for shutdown. - */ + /** Notify SapServer that this class is ready for shutdown. */ void notifyShutdown(); - /** - * Notify SapServer that the RIL socket is connected - */ + /** Notify SapServer that the RIL socket is connected */ void sendRilConnectMessage(); - /** - * Get mSapProxyLock - */ + /** Get mSapProxyLock */ Object getSapProxyLock(); - /** - * Verifies mSapProxy is not null - */ + /** Verifies mSapProxy is not null */ boolean isProxyValid(); } diff --git a/android/app/src/com/android/bluetooth/sap/SapMessage.java b/android/app/src/com/android/bluetooth/sap/SapMessage.java index ea1d600ff5c..9eb35e53c48 100644 --- a/android/app/src/com/android/bluetooth/sap/SapMessage.java +++ b/android/app/src/com/android/bluetooth/sap/SapMessage.java @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger; /** * SapMessage is used for incoming and outgoing messages. * - * For incoming messages + *

For incoming messages */ public class SapMessage { @@ -371,7 +371,7 @@ public class SapMessage { * Construct a SapMessage based on the incoming rfcomm request. * * @param requestType The type of the request - * @param is the input stream to read the data from + * @param is the input stream to read the data from * @return the resulting message, or null if an error occurs */ @SuppressWarnings("unused") @@ -417,14 +417,14 @@ public class SapMessage { } newMessage.setSendToRil(true); break; - case ID_TRANSFER_ATR_REQ: /* No params */ + case ID_TRANSFER_ATR_REQ: /* No params */ case ID_POWER_SIM_OFF_REQ: /* No params */ - case ID_POWER_SIM_ON_REQ: /* No params */ - case ID_RESET_SIM_REQ: /* No params */ + case ID_POWER_SIM_ON_REQ: /* No params */ + case ID_RESET_SIM_REQ: /* No params */ case ID_TRANSFER_CARD_READER_STATUS_REQ: /* No params */ newMessage.setSendToRil(true); break; - case ID_DISCONNECT_REQ: /* No params */ + case ID_DISCONNECT_REQ: /* No params */ break; default: Log.e(TAG, "Unknown request type"); @@ -436,9 +436,9 @@ public class SapMessage { /** * Blocking read of an entire array of data. * - * @param is the input stream to read from - * @param buffer the buffer to read into - the length of the buffer will - * determine how many bytes will be read. + * @param is the input stream to read from + * @param buffer the buffer to read into - the length of the buffer will determine how many + * bytes will be read. */ private static void read(InputStream is, byte[] buffer) throws IOException { int bytesToRead = buffer.length; @@ -457,7 +457,7 @@ public class SapMessage { /** * Skip a number of bytes in an InputStream. * - * @param is the input stream + * @param is the input stream * @param count the number of bytes to skip * @throws IOException In case of reaching EOF or a stream error */ @@ -468,12 +468,11 @@ public class SapMessage { } /** - * Read the parameters from the stream and update the relevant members. - * This function will ensure that all parameters are read from the stream, even - * if an error is detected. + * Read the parameters from the stream and update the relevant members. This function will + * ensure that all parameters are read from the stream, even if an error is detected. * * @param count the number of parameters to read - * @param is the input stream + * @param is the input stream * @return True if all parameters were successfully parsed, False if an error were detected. */ private boolean parseParameters(int count, InputStream is) throws IOException { @@ -497,8 +496,11 @@ public class SapMessage { switch (paramId) { case PARAM_MAX_MSG_SIZE_ID: if (paramLength != PARAM_MAX_MSG_SIZE_LENGTH) { - Log.e(TAG, "Received PARAM_MAX_MSG_SIZE with wrong length: " + paramLength - + " skipping this parameter."); + Log.e( + TAG, + "Received PARAM_MAX_MSG_SIZE with wrong length: " + + paramLength + + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; } else { @@ -519,8 +521,11 @@ public class SapMessage { break; case PARAM_TRANSPORT_PROTOCOL_ID: if (paramLength != PARAM_TRANSPORT_PROTOCOL_LENGTH) { - Log.e(TAG, "Received PARAM_TRANSPORT_PROTOCOL with wrong length: " - + paramLength + " skipping this parameter."); + Log.e( + TAG, + "Received PARAM_TRANSPORT_PROTOCOL with wrong length: " + + paramLength + + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; } else { @@ -531,8 +536,10 @@ public class SapMessage { case PARAM_CONNECTION_STATUS_ID: // not needed for server role, but used for module test if (paramLength != PARAM_CONNECTION_STATUS_LENGTH) { - Log.e(TAG, - "Received PARAM_CONNECTION_STATUS with wrong length: " + paramLength + Log.e( + TAG, + "Received PARAM_CONNECTION_STATUS with wrong length: " + + paramLength + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; @@ -544,8 +551,11 @@ public class SapMessage { case PARAM_CARD_READER_STATUS_ID: // not needed for server role, but used for module test if (paramLength != PARAM_CARD_READER_STATUS_LENGTH) { - Log.e(TAG, "Received PARAM_CARD_READER_STATUS with wrong length: " - + paramLength + " skipping this parameter."); + Log.e( + TAG, + "Received PARAM_CARD_READER_STATUS with wrong length: " + + paramLength + + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; } else { @@ -556,8 +566,11 @@ public class SapMessage { case PARAM_STATUS_CHANGE_ID: // not needed for server role, but used for module test if (paramLength != PARAM_STATUS_CHANGE_LENGTH) { - Log.e(TAG, "Received PARAM_STATUS_CHANGE with wrong length: " + paramLength - + " skipping this parameter."); + Log.e( + TAG, + "Received PARAM_STATUS_CHANGE with wrong length: " + + paramLength + + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; } else { @@ -568,8 +581,11 @@ public class SapMessage { case PARAM_RESULT_CODE_ID: // not needed for server role, but used for module test if (paramLength != PARAM_RESULT_CODE_LENGTH) { - Log.e(TAG, "Received PARAM_RESULT_CODE with wrong length: " + paramLength - + " skipping this parameter."); + Log.e( + TAG, + "Received PARAM_RESULT_CODE with wrong length: " + + paramLength + + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; } else { @@ -580,8 +596,11 @@ public class SapMessage { case PARAM_DISCONNECT_TYPE_ID: // not needed for server role, but used for module test if (paramLength != PARAM_DISCONNECT_TYPE_LENGTH) { - Log.e(TAG, "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " - + paramLength + " skipping this parameter."); + Log.e( + TAG, + "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " + + paramLength + + " skipping this parameter."); skip(is, paramLength + skipLen); success = false; } else { @@ -602,8 +621,12 @@ public class SapMessage { skip(is, skipLen); break; default: - Log.e(TAG, - "Received unknown parameter ID: " + paramId + " length: " + paramLength + Log.e( + TAG, + "Received unknown parameter ID: " + + paramId + + " length: " + + paramLength + " skipping this parameter."); skip(is, paramLength + skipLen); } @@ -614,9 +637,9 @@ public class SapMessage { /** * Writes a single value parameter of 1 or 2 bytes in length. * - * @param os The BufferedOutputStream to write to. - * @param id The Parameter ID - * @param value The parameter value + * @param os The BufferedOutputStream to write to. + * @param id The Parameter ID + * @param value The parameter value * @param length The length of the parameter value * @throws IOException if the write to os fails */ @@ -650,8 +673,8 @@ public class SapMessage { /** * Writes a byte[] parameter of any length. * - * @param os The BufferedOutputStream to write to. - * @param id The Parameter ID + * @param os The BufferedOutputStream to write to. + * @param id The Parameter ID * @param value The byte array to write, the length will be extracted from the array. * @throws IOException if the write to os fails */ @@ -681,7 +704,10 @@ public class SapMessage { /* write the parameters */ if (mConnectionStatus != INVALID_VALUE) { - writeParameter(os, PARAM_CONNECTION_STATUS_ID, mConnectionStatus, + writeParameter( + os, + PARAM_CONNECTION_STATUS_ID, + mConnectionStatus, PARAM_CONNECTION_STATUS_LENGTH); } if (mMaxMsgSize != INVALID_VALUE) { @@ -691,18 +717,24 @@ public class SapMessage { writeParameter(os, PARAM_RESULT_CODE_ID, mResultCode, PARAM_RESULT_CODE_LENGTH); } if (mDisconnectionType != INVALID_VALUE) { - writeParameter(os, PARAM_DISCONNECT_TYPE_ID, mDisconnectionType, - PARAM_DISCONNECT_TYPE_LENGTH); + writeParameter( + os, PARAM_DISCONNECT_TYPE_ID, mDisconnectionType, PARAM_DISCONNECT_TYPE_LENGTH); } if (mCardReaderStatus != INVALID_VALUE) { - writeParameter(os, PARAM_CARD_READER_STATUS_ID, mCardReaderStatus, + writeParameter( + os, + PARAM_CARD_READER_STATUS_ID, + mCardReaderStatus, PARAM_CARD_READER_STATUS_LENGTH); } if (mStatusChange != INVALID_VALUE) { writeParameter(os, PARAM_STATUS_CHANGE_ID, mStatusChange, PARAM_STATUS_CHANGE_LENGTH); } if (mTransportProtocol != INVALID_VALUE) { - writeParameter(os, PARAM_TRANSPORT_PROTOCOL_ID, mTransportProtocol, + writeParameter( + os, + PARAM_TRANSPORT_PROTOCOL_ID, + mTransportProtocol, PARAM_TRANSPORT_PROTOCOL_LENGTH); } if (mApdu != null) { @@ -723,10 +755,7 @@ public class SapMessage { * RILD Interface message conversion functions. ***************************************************************************/ - - /** - * Send the message by calling corresponding ISap api. - */ + /** Send the message by calling corresponding ISap api. */ public void send(ISapRilReceiver sapProxy) throws RemoteException, RuntimeException { int rilSerial = sNextSerial.getAndIncrement(); @@ -740,64 +769,76 @@ public class SapMessage { sOngoingRequests.put(rilSerial, mMsgType); switch (mMsgType) { - case ID_CONNECT_REQ: { - sapProxy.connectReq(rilSerial, mMaxMsgSize); - break; - } - case ID_DISCONNECT_REQ: { - sapProxy.disconnectReq(rilSerial); - break; - } - case ID_TRANSFER_APDU_REQ: { - int type; - byte[] command; - if (mApdu != null) { - type = SapApduType.APDU; - command = mApdu; - } else if (mApdu7816 != null) { - type = SapApduType.APDU7816; - command = mApdu7816; - } else { - Log.e(TAG, "Missing Apdu parameter in TRANSFER_APDU_REQ"); - throw new IllegalArgumentException(); + case ID_CONNECT_REQ: + { + sapProxy.connectReq(rilSerial, mMaxMsgSize); + break; } - sapProxy.apduReq(rilSerial, type, command); - break; - } - case ID_SET_TRANSPORT_PROTOCOL_REQ: { - int transportProtocol; - if (mTransportProtocol == TRANS_PROTO_T0) { - transportProtocol = SapTransferProtocol.T0; - } else if (mTransportProtocol == TRANS_PROTO_T1) { - transportProtocol = SapTransferProtocol.T1; - } else { - Log.e(TAG, "Missing or invalid TransportProtocol parameter in" - + " SET_TRANSPORT_PROTOCOL_REQ: " + mTransportProtocol); - throw new IllegalArgumentException(); + case ID_DISCONNECT_REQ: + { + sapProxy.disconnectReq(rilSerial); + break; + } + case ID_TRANSFER_APDU_REQ: + { + int type; + byte[] command; + if (mApdu != null) { + type = SapApduType.APDU; + command = mApdu; + } else if (mApdu7816 != null) { + type = SapApduType.APDU7816; + command = mApdu7816; + } else { + Log.e(TAG, "Missing Apdu parameter in TRANSFER_APDU_REQ"); + throw new IllegalArgumentException(); + } + sapProxy.apduReq(rilSerial, type, command); + break; + } + case ID_SET_TRANSPORT_PROTOCOL_REQ: + { + int transportProtocol; + if (mTransportProtocol == TRANS_PROTO_T0) { + transportProtocol = SapTransferProtocol.T0; + } else if (mTransportProtocol == TRANS_PROTO_T1) { + transportProtocol = SapTransferProtocol.T1; + } else { + Log.e( + TAG, + "Missing or invalid TransportProtocol parameter in" + + " SET_TRANSPORT_PROTOCOL_REQ: " + + mTransportProtocol); + throw new IllegalArgumentException(); + } + sapProxy.setTransferProtocolReq(rilSerial, transportProtocol); + break; + } + case ID_TRANSFER_ATR_REQ: + { + sapProxy.transferAtrReq(rilSerial); + break; + } + case ID_POWER_SIM_OFF_REQ: + { + sapProxy.powerReq(rilSerial, false); + break; + } + case ID_POWER_SIM_ON_REQ: + { + sapProxy.powerReq(rilSerial, true); + break; + } + case ID_RESET_SIM_REQ: + { + sapProxy.resetSimReq(rilSerial); + break; + } + case ID_TRANSFER_CARD_READER_STATUS_REQ: + { + sapProxy.transferCardReaderStatusReq(rilSerial); + break; } - sapProxy.setTransferProtocolReq(rilSerial, transportProtocol); - break; - } - case ID_TRANSFER_ATR_REQ: { - sapProxy.transferAtrReq(rilSerial); - break; - } - case ID_POWER_SIM_OFF_REQ: { - sapProxy.powerReq(rilSerial, false); - break; - } - case ID_POWER_SIM_ON_REQ: { - sapProxy.powerReq(rilSerial, true); - break; - } - case ID_RESET_SIM_REQ: { - sapProxy.resetSimReq(rilSerial); - break; - } - case ID_TRANSFER_CARD_READER_STATUS_REQ: { - sapProxy.transferCardReaderStatusReq(rilSerial); - break; - } default: Log.e(TAG, "Unknown request type"); throw new IllegalArgumentException(); @@ -831,42 +872,47 @@ public class SapMessage { private void createUnsolicited(MsgHeader msg) throws IOException, InvalidProtocolBufferMicroException { switch (msg.getId()) { -// TODO: -// Not sure when we use these? case RIL_UNSOL_RIL_CONNECTED: -// if(VERBOSE) Log.i(TAG, "RIL_UNSOL_RIL_CONNECTED received, ignoring"); -// msgType = ID_RIL_UNSOL_CONNECTED; -// break; - case SapApi.RIL_SIM_SAP_STATUS: { - Log.v(TAG, "RIL_SIM_SAP_STATUS_IND received"); - RIL_SIM_SAP_STATUS_IND indMsg = - RIL_SIM_SAP_STATUS_IND.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_STATUS_IND; - if (indMsg.hasStatusChange()) { - setStatusChange(indMsg.getStatusChange()); - Log.v(TAG, - "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " + mStatusChange); - } else { - Log.v(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); - mMsgType = ID_RIL_UNKNOWN; + // TODO: + // Not sure when we use these? case RIL_UNSOL_RIL_CONNECTED: + // if(VERBOSE) Log.i(TAG, "RIL_UNSOL_RIL_CONNECTED received, ignoring"); + // msgType = ID_RIL_UNSOL_CONNECTED; + // break; + case SapApi.RIL_SIM_SAP_STATUS: + { + Log.v(TAG, "RIL_SIM_SAP_STATUS_IND received"); + RIL_SIM_SAP_STATUS_IND indMsg = + RIL_SIM_SAP_STATUS_IND.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_STATUS_IND; + if (indMsg.hasStatusChange()) { + setStatusChange(indMsg.getStatusChange()); + Log.v( + TAG, + "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " + mStatusChange); + } else { + Log.v(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); + mMsgType = ID_RIL_UNKNOWN; + } + break; } - break; - } - case SapApi.RIL_SIM_SAP_DISCONNECT: { - Log.v(TAG, "RIL_SIM_SAP_DISCONNECT_IND received"); - - RIL_SIM_SAP_DISCONNECT_IND indMsg = - RIL_SIM_SAP_DISCONNECT_IND.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_RIL_UNSOL_DISCONNECT_IND; // don't use ID_DISCONNECT_IND; - if (indMsg.hasDisconnectType()) { - setDisconnectionType(indMsg.getDisconnectType()); - Log.v(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " - + mDisconnectionType); - } else { - Log.v(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); - mMsgType = ID_RIL_UNKNOWN; + case SapApi.RIL_SIM_SAP_DISCONNECT: + { + Log.v(TAG, "RIL_SIM_SAP_DISCONNECT_IND received"); + + RIL_SIM_SAP_DISCONNECT_IND indMsg = + RIL_SIM_SAP_DISCONNECT_IND.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_RIL_UNSOL_DISCONNECT_IND; // don't use ID_DISCONNECT_IND; + if (indMsg.hasDisconnectType()) { + setDisconnectionType(indMsg.getDisconnectType()); + Log.v( + TAG, + "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " + + mDisconnectionType); + } else { + Log.v(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); + mMsgType = ID_RIL_UNKNOWN; + } + break; } - break; - } default: Log.v(TAG, "Unused unsolicited message received, ignoring: " + msg.getId()); mMsgType = ID_RIL_UNKNOWN; @@ -885,8 +931,14 @@ public class SapMessage { int serial = msg.getToken(); int error = msg.getError(); Integer reqType = sOngoingRequests.remove(serial); - Log.v(TAG, "RIL SOLICITED serial: " + serial + ", error: " + error + " SapReqType: " + ( - (reqType == null) ? "null" : getMsgTypeName(reqType))); + Log.v( + TAG, + "RIL SOLICITED serial: " + + serial + + ", error: " + + error + + " SapReqType: " + + ((reqType == null) ? "null" : getMsgTypeName(reqType))); if (reqType == null) { /* This can happen if we get a resp. for a canceled request caused by a power off, @@ -898,244 +950,254 @@ public class SapMessage { mResultCode = mapRilErrorCode(error); switch (reqType) { - case ID_CONNECT_REQ: { - RIL_SIM_SAP_CONNECT_RSP resMsg = - RIL_SIM_SAP_CONNECT_RSP.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_CONNECT_RESP; - if (resMsg.hasMaxMessageSize()) { - mMaxMsgSize = resMsg.getMaxMessageSize(); - - } - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SUCCESS: - mConnectionStatus = CON_STATUS_OK; - break; - case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_OK_CALL_ONGOING: - mConnectionStatus = CON_STATUS_OK_ONGOING_CALL; - break; - case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_FAILURE: - mConnectionStatus = CON_STATUS_ERROR_CONNECTION; - break; - case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_LARGE: - mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED; - break; - case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_SMALL: - mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_TOO_SMALL; - break; - default: - mConnectionStatus = CON_STATUS_ERROR_CONNECTION; // Cannot happen! - break; + case ID_CONNECT_REQ: + { + RIL_SIM_SAP_CONNECT_RSP resMsg = + RIL_SIM_SAP_CONNECT_RSP.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_CONNECT_RESP; + if (resMsg.hasMaxMessageSize()) { + mMaxMsgSize = resMsg.getMaxMessageSize(); + } + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SUCCESS: + mConnectionStatus = CON_STATUS_OK; + break; + case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_OK_CALL_ONGOING: + mConnectionStatus = CON_STATUS_OK_ONGOING_CALL; + break; + case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_FAILURE: + mConnectionStatus = CON_STATUS_ERROR_CONNECTION; + break; + case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_LARGE: + mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED; + break; + case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_SMALL: + mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_TOO_SMALL; + break; + default: + mConnectionStatus = CON_STATUS_ERROR_CONNECTION; // Cannot happen! + break; + } + mResultCode = INVALID_VALUE; + Log.v( + TAG, + " ID_CONNECT_REQ: mMaxMsgSize: " + + mMaxMsgSize + + " mConnectionStatus: " + + mConnectionStatus); + break; } - mResultCode = INVALID_VALUE; - Log.v(TAG, " ID_CONNECT_REQ: mMaxMsgSize: " + mMaxMsgSize - + " mConnectionStatus: " + mConnectionStatus); - break; - } case ID_DISCONNECT_REQ: mMsgType = ID_DISCONNECT_RESP; mResultCode = INVALID_VALUE; break; - case ID_TRANSFER_APDU_REQ: { - RIL_SIM_SAP_APDU_RSP resMsg = - RIL_SIM_SAP_APDU_RSP.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_TRANSFER_APDU_RESP; - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_APDU_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - /* resMsg.getType is unused as the client knows the type of request used. */ - if (resMsg.hasApduResponse()) { - mApduResp = resMsg.getApduResponse().toByteArray(); - } - break; - case RIL_SIM_SAP_APDU_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NO_REASON; - break; - case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ABSENT: - mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; - break; - case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: - mResultCode = RESULT_ERROR_CARD_POWERED_OFF; - break; - case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_NOT_READY: - mResultCode = RESULT_ERROR_CARD_REMOVED; - break; - default: - mResultCode = RESULT_ERROR_NO_REASON; - break; - } - break; - } - case ID_SET_TRANSPORT_PROTOCOL_REQ: { - RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP resMsg = - RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.parseFrom( - msg.getPayload().toByteArray()); - mMsgType = ID_SET_TRANSPORT_PROTOCOL_RESP; - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - break; - case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NOT_SUPPORTED; - break; - case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ABSENT: - mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; - break; - case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: - mResultCode = RESULT_ERROR_CARD_POWERED_OFF; - break; - case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_NOT_READY: - mResultCode = RESULT_ERROR_CARD_REMOVED; - break; - default: - mResultCode = RESULT_ERROR_NOT_SUPPORTED; - break; + case ID_TRANSFER_APDU_REQ: + { + RIL_SIM_SAP_APDU_RSP resMsg = + RIL_SIM_SAP_APDU_RSP.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_TRANSFER_APDU_RESP; + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_APDU_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + /* resMsg.getType is unused as the client knows the type of request used. */ + if (resMsg.hasApduResponse()) { + mApduResp = resMsg.getApduResponse().toByteArray(); + } + break; + case RIL_SIM_SAP_APDU_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NO_REASON; + break; + case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ABSENT: + mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; + break; + case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: + mResultCode = RESULT_ERROR_CARD_POWERED_OFF; + break; + case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_NOT_READY: + mResultCode = RESULT_ERROR_CARD_REMOVED; + break; + default: + mResultCode = RESULT_ERROR_NO_REASON; + break; + } + break; } - break; - } - case ID_TRANSFER_ATR_REQ: { - RIL_SIM_SAP_TRANSFER_ATR_RSP resMsg = - RIL_SIM_SAP_TRANSFER_ATR_RSP.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_TRANSFER_ATR_RESP; - if (resMsg.hasAtr()) { - mAtr = resMsg.getAtr().toByteArray(); + case ID_SET_TRANSPORT_PROTOCOL_REQ: + { + RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP resMsg = + RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.parseFrom( + msg.getPayload().toByteArray()); + mMsgType = ID_SET_TRANSPORT_PROTOCOL_RESP; + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + break; + case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NOT_SUPPORTED; + break; + case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ABSENT: + mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; + break; + case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: + mResultCode = RESULT_ERROR_CARD_POWERED_OFF; + break; + case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_NOT_READY: + mResultCode = RESULT_ERROR_CARD_REMOVED; + break; + default: + mResultCode = RESULT_ERROR_NOT_SUPPORTED; + break; + } + break; } - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - break; - case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NO_REASON; - break; - case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ABSENT: - mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; - break; - case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: - mResultCode = RESULT_ERROR_CARD_POWERED_OFF; - break; - case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_ON: - mResultCode = RESULT_ERROR_CARD_POWERED_ON; - break; - case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: - mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; - break; - default: - mResultCode = RESULT_ERROR_NO_REASON; - break; + case ID_TRANSFER_ATR_REQ: + { + RIL_SIM_SAP_TRANSFER_ATR_RSP resMsg = + RIL_SIM_SAP_TRANSFER_ATR_RSP.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_TRANSFER_ATR_RESP; + if (resMsg.hasAtr()) { + mAtr = resMsg.getAtr().toByteArray(); + } + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + break; + case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NO_REASON; + break; + case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ABSENT: + mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; + break; + case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: + mResultCode = RESULT_ERROR_CARD_POWERED_OFF; + break; + case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_ON: + mResultCode = RESULT_ERROR_CARD_POWERED_ON; + break; + case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: + mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; + break; + default: + mResultCode = RESULT_ERROR_NO_REASON; + break; + } + break; } - break; - } - case ID_POWER_SIM_OFF_REQ: { - RIL_SIM_SAP_POWER_RSP resMsg = - RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_POWER_SIM_OFF_RESP; - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NO_REASON; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: - mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: - mResultCode = RESULT_ERROR_CARD_POWERED_OFF; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: - mResultCode = RESULT_ERROR_CARD_POWERED_ON; - break; - default: - mResultCode = RESULT_ERROR_NO_REASON; - break; + case ID_POWER_SIM_OFF_REQ: + { + RIL_SIM_SAP_POWER_RSP resMsg = + RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_POWER_SIM_OFF_RESP; + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NO_REASON; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: + mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: + mResultCode = RESULT_ERROR_CARD_POWERED_OFF; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: + mResultCode = RESULT_ERROR_CARD_POWERED_ON; + break; + default: + mResultCode = RESULT_ERROR_NO_REASON; + break; + } + break; } - break; - } - case ID_POWER_SIM_ON_REQ: { - RIL_SIM_SAP_POWER_RSP resMsg = - RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_POWER_SIM_ON_RESP; - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NO_REASON; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: - mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: - mResultCode = RESULT_ERROR_CARD_POWERED_OFF; - break; - case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: - mResultCode = RESULT_ERROR_CARD_POWERED_ON; - break; - default: - mResultCode = RESULT_ERROR_NO_REASON; - break; + case ID_POWER_SIM_ON_REQ: + { + RIL_SIM_SAP_POWER_RSP resMsg = + RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_POWER_SIM_ON_RESP; + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NO_REASON; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: + mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: + mResultCode = RESULT_ERROR_CARD_POWERED_OFF; + break; + case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: + mResultCode = RESULT_ERROR_CARD_POWERED_ON; + break; + default: + mResultCode = RESULT_ERROR_NO_REASON; + break; + } + break; } - break; - } - case ID_RESET_SIM_REQ: { - RIL_SIM_SAP_RESET_SIM_RSP resMsg = - RIL_SIM_SAP_RESET_SIM_RSP.parseFrom(msg.getPayload().toByteArray()); - mMsgType = ID_RESET_SIM_RESP; - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - break; - case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NO_REASON; - break; - case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ABSENT: - mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; - break; - case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: - mResultCode = RESULT_ERROR_CARD_POWERED_OFF; - break; - default: - mResultCode = RESULT_ERROR_NO_REASON; - break; + case ID_RESET_SIM_REQ: + { + RIL_SIM_SAP_RESET_SIM_RSP resMsg = + RIL_SIM_SAP_RESET_SIM_RSP.parseFrom(msg.getPayload().toByteArray()); + mMsgType = ID_RESET_SIM_RESP; + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + break; + case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NO_REASON; + break; + case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ABSENT: + mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; + break; + case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: + mResultCode = RESULT_ERROR_CARD_POWERED_OFF; + break; + default: + mResultCode = RESULT_ERROR_NO_REASON; + break; + } + break; } - break; - } - case ID_TRANSFER_CARD_READER_STATUS_REQ: { - RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP resMsg = - RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.parseFrom( - msg.getPayload().toByteArray()); - mMsgType = ID_TRANSFER_CARD_READER_STATUS_RESP; - switch (resMsg.getResponse()) { - case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SUCCESS: - mResultCode = RESULT_OK; - if (resMsg.hasCardReaderStatus()) { - mCardReaderStatus = resMsg.getCardReaderStatus(); - } else { + case ID_TRANSFER_CARD_READER_STATUS_REQ: + { + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP resMsg = + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.parseFrom( + msg.getPayload().toByteArray()); + mMsgType = ID_TRANSFER_CARD_READER_STATUS_RESP; + switch (resMsg.getResponse()) { + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SUCCESS: + mResultCode = RESULT_OK; + if (resMsg.hasCardReaderStatus()) { + mCardReaderStatus = resMsg.getCardReaderStatus(); + } else { + mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; + } + break; + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_GENERIC_FAILURE: + mResultCode = RESULT_ERROR_NO_REASON; + break; + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP + .RIL_E_SIM_DATA_NOT_AVAILABLE: mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; - } - break; - case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_GENERIC_FAILURE: - mResultCode = RESULT_ERROR_NO_REASON; - break; - case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: - mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; - break; - default: - mResultCode = RESULT_ERROR_NO_REASON; - break; + break; + default: + mResultCode = RESULT_ERROR_NO_REASON; + break; + } + break; } - break; - } case ID_RIL_SIM_ACCESS_TEST_REQ: // TODO: implement in RILD mMsgType = ID_RIL_SIM_ACCESS_TEST_RESP; break; default: Log.e(TAG, "Unknown request type: " + reqType); - } } - /* Map from RIL header error codes to SAP error codes */ private static int mapRilErrorCode(int rilErrorCode) { switch (rilErrorCode) { @@ -1156,7 +1218,6 @@ public class SapMessage { } } - public static String getMsgTypeName(int msgType) { switch (msgType) { case ID_CONNECT_REQ: diff --git a/android/app/src/com/android/bluetooth/sap/SapRilReceiver.java b/android/app/src/com/android/bluetooth/sap/SapRilReceiver.java index aa6051610c7..6a7290165d3 100644 --- a/android/app/src/com/android/bluetooth/sap/SapRilReceiver.java +++ b/android/app/src/com/android/bluetooth/sap/SapRilReceiver.java @@ -29,9 +29,7 @@ import com.android.modules.utils.build.SdkLevel; import java.util.concurrent.atomic.AtomicLong; -/** - * SapRiilReceiver is the AIDL implementation of ISapRilReceiver - */ +/** SapRiilReceiver is the AIDL implementation of ISapRilReceiver */ public class SapRilReceiver implements ISapRilReceiver { private static final String TAG = "SapRilReceiver"; @@ -53,8 +51,8 @@ public class SapRilReceiver implements ISapRilReceiver { /** * TRANSFER_APDU_REQ from SAP 1.1 spec 5.1.6 * - * @param serial Id to match req-resp. Resp must include same serial. - * @param type APDU command type + * @param serial Id to match req-resp. Resp must include same serial. + * @param type APDU command type * @param command CommandAPDU/CommandAPDU7816 parameter depending on type */ @Override @@ -65,7 +63,7 @@ public class SapRilReceiver implements ISapRilReceiver { /** * CONNECT_REQ from SAP 1.1 spec 5.1.1 * - * @param serial Id to match req-resp. Resp must include same serial. + * @param serial Id to match req-resp. Resp must include same serial. * @param maxMsgSizeBytes MaxMsgSize to be used for SIM Access Profile connection */ @Override @@ -86,7 +84,7 @@ public class SapRilReceiver implements ISapRilReceiver { /** * POWER_SIM_OFF_REQ and POWER_SIM_ON_REQ from SAP 1.1 spec 5.1.10 + 5.1.12 * - * @param serial Id to match req-resp. Resp must include same serial. + * @param serial Id to match req-resp. Resp must include same serial. * @param powerOn true for on, false for off */ @Override @@ -118,7 +116,7 @@ public class SapRilReceiver implements ISapRilReceiver { /** * SET_TRANSPORT_PROTOCOL_REQ from SAP 1.1 spec 5.1.20 * - * @param serial Id to match req-resp. Resp must include same serial. + * @param serial Id to match req-resp. Resp must include same serial. * @param transferProtocol Transport Protocol */ @Override @@ -187,16 +185,26 @@ public class SapRilReceiver implements ISapRilReceiver { private void removeOngoingReqAndSendMessage(int token, SapMessage sapMessage) { Integer reqType = SapMessage.sOngoingRequests.remove(token); - Log.v(TAG, "removeOngoingReqAndSendMessage: token " + token + " reqType " + ( - reqType == null ? "null" : SapMessage.getMsgTypeName(reqType))); + Log.v( + TAG, + "removeOngoingReqAndSendMessage: token " + + token + + " reqType " + + (reqType == null ? "null" : SapMessage.getMsgTypeName(reqType))); sendSapMessage(sapMessage); } class SapCallback extends ISapCallback.Stub { @Override public void connectResponse(int token, int sapConnectRsp, int maxMsgSize) { - Log.d(TAG, "connectResponse: token " + token + " sapConnectRsp " + sapConnectRsp - + " maxMsgSize " + maxMsgSize); + Log.d( + TAG, + "connectResponse: token " + + token + + " sapConnectRsp " + + sapConnectRsp + + " maxMsgSize " + + maxMsgSize); SapService.notifyUpdateWakeLock(mSapServiceHandler); SapMessage sapMessage = new SapMessage(SapMessage.ID_CONNECT_RESP); sapMessage.setConnectionStatus(sapConnectRsp); @@ -218,7 +226,8 @@ public class SapRilReceiver implements ISapRilReceiver { @Override public void disconnectIndication(int token, int disconnectType) { - Log.d(TAG, + Log.d( + TAG, "disconnectIndication: token " + token + " disconnectType " + disconnectType); SapService.notifyUpdateWakeLock(mSapServiceHandler); SapMessage sapMessage = new SapMessage(SapMessage.ID_RIL_UNSOL_DISCONNECT_IND); @@ -255,8 +264,10 @@ public class SapRilReceiver implements ISapRilReceiver { Log.d(TAG, "powerResponse: token " + token + " resultCode " + resultCode); SapService.notifyUpdateWakeLock(mSapServiceHandler); Integer reqType = SapMessage.sOngoingRequests.remove(token); - Log.v(TAG, "powerResponse: reqType " + (reqType == null ? "null" - : SapMessage.getMsgTypeName(reqType))); + Log.v( + TAG, + "powerResponse: reqType " + + (reqType == null ? "null" : SapMessage.getMsgTypeName(reqType))); SapMessage sapMessage; if (reqType == SapMessage.ID_POWER_SIM_OFF_REQ) { sapMessage = new SapMessage(SapMessage.ID_POWER_SIM_OFF_RESP); @@ -288,11 +299,16 @@ public class SapRilReceiver implements ISapRilReceiver { } @Override - public void transferCardReaderStatusResponse(int token, int resultCode, - int cardReaderStatus) { - Log.d(TAG, - "transferCardReaderStatusResponse: token " + token + " resultCode " + resultCode - + " cardReaderStatus " + cardReaderStatus); + public void transferCardReaderStatusResponse( + int token, int resultCode, int cardReaderStatus) { + Log.d( + TAG, + "transferCardReaderStatusResponse: token " + + token + + " resultCode " + + resultCode + + " cardReaderStatus " + + cardReaderStatus); SapService.notifyUpdateWakeLock(mSapServiceHandler); SapMessage sapMessage = new SapMessage(SapMessage.ID_TRANSFER_CARD_READER_STATUS_RESP); sapMessage.setResultCode(resultCode); @@ -343,16 +359,12 @@ public class SapRilReceiver implements ISapRilReceiver { return mSapProxy != null; } - /** - * Check if AIDL is supported - */ + /** Check if AIDL is supported */ public static boolean isAidlSupported() { return SdkLevel.isAtLeastU() && ServiceManager.isDeclared(HAL_INSTANCE_NAME); } - /** - * Obtain a valid sapProxy - */ + /** Obtain a valid sapProxy */ public ISap getSapProxy() { synchronized (mSapProxyLock) { if (mSapProxy != null) { @@ -363,8 +375,7 @@ public class SapRilReceiver implements ISapRilReceiver { IBinder service = ServiceManager.waitForDeclaredService(HAL_INSTANCE_NAME); mSapProxy = ISap.Stub.asInterface(service); if (mSapProxy != null) { - service.linkToDeath(mSapProxyDeathRecipient, - /* flags= */ 0); + service.linkToDeath(mSapProxyDeathRecipient, /* flags= */ 0); mSapProxy.setCallback(mSapCallback); } else { Log.e(TAG, "getSapProxy: mSapProxy == null"); @@ -378,8 +389,9 @@ public class SapRilReceiver implements ISapRilReceiver { // if service is not up, treat it like death notification to try to get service // again mSapServerMsgHandler.sendMessageDelayed( - mSapServerMsgHandler.obtainMessage(SapServer.SAP_PROXY_DEAD, - mSapProxyCookie.get()), SapServer.ISAP_GET_SERVICE_DELAY_MILLIS); + mSapServerMsgHandler.obtainMessage( + SapServer.SAP_PROXY_DEAD, mSapProxyCookie.get()), + SapServer.ISAP_GET_SERVICE_DELAY_MILLIS); } return mSapProxy; } @@ -443,9 +455,7 @@ public class SapRilReceiver implements ISapRilReceiver { mSapServerMsgHandler.sendMessage(newMsg); } - /** - * Send a shutdown signal to SapServer to indicate the - */ + /** Send a shutdown signal to SapServer to indicate the */ private void sendShutdownMessage() { if (mSapServerMsgHandler != null) { mSapServerMsgHandler.sendEmptyMessage(SapServer.SAP_RIL_SOCK_CLOSED); diff --git a/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java b/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java index 7200901483e..4546aecca96 100644 --- a/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java +++ b/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java @@ -28,9 +28,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; -/** - * SapRiilReceiverHidl is the HIDL implementation of ISapRilReceiver - */ +/** SapRiilReceiverHidl is the HIDL implementation of ISapRilReceiver */ public class SapRilReceiverHidl implements ISapRilReceiver { private static final String TAG = "SapRilReceiver"; @@ -60,21 +58,20 @@ public class SapRilReceiverHidl implements ISapRilReceiver { /** * TRANSFER_APDU_REQ from SAP 1.1 spec 5.1.6 * - * @param serial Id to match req-resp. Resp must include same serial. - * @param type APDU command type + * @param serial Id to match req-resp. Resp must include same serial. + * @param type APDU command type * @param command CommandAPDU/CommandAPDU7816 parameter depending on type */ @Override public void apduReq(int serial, int type, byte[] command) throws RemoteException { ArrayList commandHidl = primitiveArrayToContainerArrayList(command); mSapProxy.apduReq(serial, type, commandHidl); - } /** * CONNECT_REQ from SAP 1.1 spec 5.1.1 * - * @param serial Id to match req-resp. Resp must include same serial. + * @param serial Id to match req-resp. Resp must include same serial. * @param maxMsgSizeBytes MaxMsgSize to be used for SIM Access Profile connection */ @Override @@ -95,7 +92,7 @@ public class SapRilReceiverHidl implements ISapRilReceiver { /** * POWER_SIM_OFF_REQ and POWER_SIM_ON_REQ from SAP 1.1 spec 5.1.10 + 5.1.12 * - * @param serial Id to match req-resp. Resp must include same serial. + * @param serial Id to match req-resp. Resp must include same serial. * @param powerOn true for on, false for off */ @Override @@ -127,7 +124,7 @@ public class SapRilReceiverHidl implements ISapRilReceiver { /** * SET_TRANSPORT_PROTOCOL_REQ from SAP 1.1 spec 5.1.20 * - * @param serial Id to match req-resp. Resp must include same serial. + * @param serial Id to match req-resp. Resp must include same serial. * @param transferProtocol Transport Protocol */ @Override @@ -197,8 +194,12 @@ public class SapRilReceiverHidl implements ISapRilReceiver { private void removeOngoingReqAndSendMessage(int token, SapMessage sapMessage) { Integer reqType = SapMessage.sOngoingRequests.remove(token); - Log.v(TAG, "removeOngoingReqAndSendMessage: token " + token + " reqType " + ( - reqType == null ? "null" : SapMessage.getMsgTypeName(reqType))); + Log.v( + TAG, + "removeOngoingReqAndSendMessage: token " + + token + + " reqType " + + (reqType == null ? "null" : SapMessage.getMsgTypeName(reqType))); sendSapMessage(sapMessage); } @@ -218,8 +219,14 @@ public class SapRilReceiverHidl implements ISapRilReceiver { class SapCallback extends ISapCallback.Stub { @Override public void connectResponse(int token, int sapConnectRsp, int maxMsgSize) { - Log.d(TAG, "connectResponse: token " + token + " sapConnectRsp " + sapConnectRsp - + " maxMsgSize " + maxMsgSize); + Log.d( + TAG, + "connectResponse: token " + + token + + " sapConnectRsp " + + sapConnectRsp + + " maxMsgSize " + + maxMsgSize); SapService.notifyUpdateWakeLock(mSapServiceHandler); SapMessage sapMessage = new SapMessage(SapMessage.ID_CONNECT_RESP); sapMessage.setConnectionStatus(sapConnectRsp); @@ -241,7 +248,8 @@ public class SapRilReceiverHidl implements ISapRilReceiver { @Override public void disconnectIndication(int token, int disconnectType) { - Log.d(TAG, + Log.d( + TAG, "disconnectIndication: token " + token + " disconnectType " + disconnectType); SapService.notifyUpdateWakeLock(mSapServiceHandler); SapMessage sapMessage = new SapMessage(SapMessage.ID_RIL_UNSOL_DISCONNECT_IND); @@ -278,8 +286,10 @@ public class SapRilReceiverHidl implements ISapRilReceiver { Log.d(TAG, "powerResponse: token " + token + " resultCode " + resultCode); SapService.notifyUpdateWakeLock(mSapServiceHandler); Integer reqType = SapMessage.sOngoingRequests.remove(token); - Log.v(TAG, "powerResponse: reqType " + (reqType == null ? "null" - : SapMessage.getMsgTypeName(reqType))); + Log.v( + TAG, + "powerResponse: reqType " + + (reqType == null ? "null" : SapMessage.getMsgTypeName(reqType))); SapMessage sapMessage; if (reqType == SapMessage.ID_POWER_SIM_OFF_REQ) { sapMessage = new SapMessage(SapMessage.ID_POWER_SIM_OFF_RESP); @@ -311,11 +321,16 @@ public class SapRilReceiverHidl implements ISapRilReceiver { } @Override - public void transferCardReaderStatusResponse(int token, int resultCode, - int cardReaderStatus) { - Log.d(TAG, - "transferCardReaderStatusResponse: token " + token + " resultCode " + resultCode - + " cardReaderStatus " + cardReaderStatus); + public void transferCardReaderStatusResponse( + int token, int resultCode, int cardReaderStatus) { + Log.d( + TAG, + "transferCardReaderStatusResponse: token " + + token + + " resultCode " + + resultCode + + " cardReaderStatus " + + cardReaderStatus); SapService.notifyUpdateWakeLock(mSapServiceHandler); SapMessage sapMessage = new SapMessage(SapMessage.ID_TRANSFER_CARD_READER_STATUS_RESP); sapMessage.setResultCode(resultCode); @@ -356,9 +371,7 @@ public class SapRilReceiverHidl implements ISapRilReceiver { return mSapProxy != null; } - /** - * Obtain a valid sapProxy - */ + /** Obtain a valid sapProxy */ public ISap getSapProxy() { synchronized (mSapProxyLock) { if (mSapProxy != null) { @@ -368,8 +381,8 @@ public class SapRilReceiverHidl implements ISapRilReceiver { try { mSapProxy = ISap.getService(SERVICE_NAME_RIL_BT); if (mSapProxy != null) { - mSapProxy.linkToDeath(mSapProxyDeathRecipient, - mSapProxyCookie.incrementAndGet()); + mSapProxy.linkToDeath( + mSapProxyDeathRecipient, mSapProxyCookie.incrementAndGet()); mSapProxy.setCallback(mSapCallback); } else { Log.e(TAG, "getSapProxy: mSapProxy == null"); @@ -383,8 +396,9 @@ public class SapRilReceiverHidl implements ISapRilReceiver { // if service is not up, treat it like death notification to try to get service // again mSapServerMsgHandler.sendMessageDelayed( - mSapServerMsgHandler.obtainMessage(SapServer.SAP_PROXY_DEAD, - mSapProxyCookie.get()), SapServer.ISAP_GET_SERVICE_DELAY_MILLIS); + mSapServerMsgHandler.obtainMessage( + SapServer.SAP_PROXY_DEAD, mSapProxyCookie.get()), + SapServer.ISAP_GET_SERVICE_DELAY_MILLIS); } return mSapProxy; } @@ -448,9 +462,7 @@ public class SapRilReceiverHidl implements ISapRilReceiver { mSapServerMsgHandler.sendMessage(newMsg); } - /** - * Send a shutdown signal to SapServer to indicate the - */ + /** Send a shutdown signal to SapServer to indicate the */ private void sendShutdownMessage() { if (mSapServerMsgHandler != null) { mSapServerMsgHandler.sendEmptyMessage(SapServer.SAP_RIL_SOCK_CLOSED); diff --git a/android/app/src/com/android/bluetooth/sap/SapServer.java b/android/app/src/com/android/bluetooth/sap/SapServer.java index de0138ca3f1..d5f19050a39 100644 --- a/android/app/src/com/android/bluetooth/sap/SapServer.java +++ b/android/app/src/com/android/bluetooth/sap/SapServer.java @@ -35,15 +35,14 @@ import java.io.OutputStream; import java.util.concurrent.CountDownLatch; /** - * The SapServer uses two threads, one for reading messages from the RFCOMM socket and - * one for writing the responses. - * Incoming requests are decoded in the "main" SapServer, by the decoder build into SapMEssage. - * The relevant RIL calls are made from the message handler thread through the rild-bt socket. - * The RIL replies are read in the SapRilReceiver, and passed to the SapServer message handler - * to be written to the RFCOMM socket. - * All writes to the RFCOMM and rild-bt socket must be synchronized, hence to write e.g. an error - * response, send a message to the Sap Handler thread. (There are helper functions to do this) - * Communication to the RIL is through an intent, and a BroadcastReceiver. + * The SapServer uses two threads, one for reading messages from the RFCOMM socket and one for + * writing the responses. Incoming requests are decoded in the "main" SapServer, by the decoder + * build into SapMEssage. The relevant RIL calls are made from the message handler thread through + * the rild-bt socket. The RIL replies are read in the SapRilReceiver, and passed to the SapServer + * message handler to be written to the RFCOMM socket. All writes to the RFCOMM and rild-bt socket + * must be synchronized, hence to write e.g. an error response, send a message to the Sap Handler + * thread. (There are helper functions to do this) Communication to the RIL is through an intent, + * and a BroadcastReceiver. */ public class SapServer extends Thread implements Callback { private static final String TAG = "SapServer"; @@ -51,29 +50,30 @@ public class SapServer extends Thread implements Callback { @VisibleForTesting enum SAP_STATE { - DISCONNECTED, CONNECTING, CONNECTING_CALL_ONGOING, CONNECTED, CONNECTED_BUSY, DISCONNECTING; + DISCONNECTED, + CONNECTING, + CONNECTING_CALL_ONGOING, + CONNECTED, + CONNECTED_BUSY, + DISCONNECTING; } - @VisibleForTesting - SAP_STATE mState = SAP_STATE.DISCONNECTED; + @VisibleForTesting SAP_STATE mState = SAP_STATE.DISCONNECTED; private Context mContext = null; /* RFCOMM socket I/O streams */ private BufferedOutputStream mRfcommOut = null; private BufferedInputStream mRfcommIn = null; /* References to the SapRilReceiver object */ - @VisibleForTesting - ISapRilReceiver mRilBtReceiver = null; + @VisibleForTesting ISapRilReceiver mRilBtReceiver = null; /* The message handler members */ - @VisibleForTesting - Handler mSapHandler = null; + @VisibleForTesting Handler mSapHandler = null; private HandlerThread mHandlerThread = null; /* Reference to the SAP service - which created this instance of the SAP server */ private Handler mSapServiceHandler = null; /* flag for when user forces disconnect of rfcomm */ - @VisibleForTesting - boolean mIsLocalInitDisconnect = false; + @VisibleForTesting boolean mIsLocalInitDisconnect = false; private CountDownLatch mDeinitSignal = new CountDownLatch(1); /* Message ID's handled by the message handler */ @@ -89,8 +89,7 @@ public class SapServer extends Thread implements Callback { public static final String SAP_DISCONNECT_TYPE_EXTRA = "com.android.bluetooth.sap.extra.DISCONNECT_TYPE"; public static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth; - @VisibleForTesting - static final String SAP_NOTIFICATION_CHANNEL = "sap_notification_channel"; + @VisibleForTesting static final String SAP_NOTIFICATION_CHANNEL = "sap_notification_channel"; public static final int ISAP_GET_SERVICE_DELAY_MILLIS = 3 * 1000; private static final int DISCONNECT_TIMEOUT_IMMEDIATE = 5000; /* ms */ private static final int DISCONNECT_TIMEOUT_RFCOMM = 2000; /* ms */ @@ -103,18 +102,17 @@ public class SapServer extends Thread implements Callback { /* We store the mMaxMessageSize, as we need a copy of it when the init. sequence completes */ private int mMaxMsgSize = 0; /* keep track of the current RIL test mode */ - @VisibleForTesting - int mTestMode = SapMessage.INVALID_VALUE; // used to set the RIL in test mode + @VisibleForTesting int mTestMode = SapMessage.INVALID_VALUE; // used to set the RIL in test mode /** * SapServer constructor * * @param serviceHandler The handler to send a SapService.MSG_SERVERSESSION_CLOSE when closing - * @param inStream The socket input stream - * @param outStream The socket output stream + * @param inStream The socket input stream + * @param outStream The socket output stream */ - public SapServer(Handler serviceHandler, Context context, InputStream inStream, - OutputStream outStream) { + public SapServer( + Handler serviceHandler, Context context, InputStream inStream, OutputStream outStream) { mContext = context; mSapServiceHandler = serviceHandler; @@ -131,21 +129,20 @@ public class SapServer extends Thread implements Callback { mContext.registerReceiver(mIntentReceiver, filter); } - /** - * This handles the response from RIL. - */ - @VisibleForTesting - BroadcastReceiver mIntentReceiver; + /** This handles the response from RIL. */ + @VisibleForTesting BroadcastReceiver mIntentReceiver; @VisibleForTesting class SapServerBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { - Log.v(TAG, - "ACTION_PHONE_STATE_CHANGED intent received in state " + mState.name() - + "PhoneState: " + intent.getStringExtra( - TelephonyManager.EXTRA_STATE)); + Log.v( + TAG, + "ACTION_PHONE_STATE_CHANGED intent received in state " + + mState.name() + + "PhoneState: " + + intent.getStringExtra(TelephonyManager.EXTRA_STATE)); if (mState == SAP_STATE.CONNECTING_CALL_ONGOING) { String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if (state != null) { @@ -158,8 +155,9 @@ public class SapServer extends Thread implements Callback { } } } else if (intent.getAction().equals(SAP_DISCONNECT_ACTION)) { - int disconnectType = intent.getIntExtra(SapServer.SAP_DISCONNECT_TYPE_EXTRA, - SapMessage.DISC_GRACEFULL); + int disconnectType = + intent.getIntExtra( + SapServer.SAP_DISCONNECT_TYPE_EXTRA, SapMessage.DISC_GRACEFULL); Log.v(TAG, " - Received SAP_DISCONNECT_ACTION type: " + disconnectType); if (disconnectType == SapMessage.DISC_RFCOMM) { @@ -176,9 +174,9 @@ public class SapServer extends Thread implements Callback { } /** - * Set RIL driver in test mode - only possible if SapMessage is build with TEST == true - * The value set by this function will take effect at the next connect request received - * in DISCONNECTED state. + * Set RIL driver in test mode - only possible if SapMessage is build with TEST == true The + * value set by this function will take effect at the next connect request received in + * DISCONNECTED state. * * @param testMode Use SapMessage.TEST_MODE_XXX */ @@ -202,7 +200,8 @@ public class SapServer extends Thread implements Callback { /* Handle local disconnect procedures */ if (discType == SapMessage.DISC_GRACEFULL) { /* Update the notification to allow the user to initiate a force disconnect */ - setNotification(SapMessage.DISC_IMMEDIATE, + setNotification( + SapMessage.DISC_IMMEDIATE, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); } else if (discType == SapMessage.DISC_IMMEDIATE) { @@ -217,7 +216,7 @@ public class SapServer extends Thread implements Callback { clearPendingRilResponses(msg); /* We simply need to forward to RIL, but not change state to busy - hence send and set - message to null. */ + message to null. */ changeState(SAP_STATE.DISCONNECTING); sendRilThreadMessage(msg); mIsLocalInitDisconnect = true; @@ -229,9 +228,11 @@ public class SapServer extends Thread implements Callback { Notification notification; NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class); - NotificationChannel notificationChannel = new NotificationChannel(SAP_NOTIFICATION_CHANNEL, - mContext.getString(R.string.bluetooth_sap_notif_title), - NotificationManager.IMPORTANCE_HIGH); + NotificationChannel notificationChannel = + new NotificationChannel( + SAP_NOTIFICATION_CHANNEL, + mContext.getString(R.string.bluetooth_sap_notif_title), + NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(notificationChannel); flags |= PendingIntent.FLAG_IMMUTABLE; Log.v(TAG, "setNotification type: " + type); @@ -260,11 +261,15 @@ public class SapServer extends Thread implements Callback { PendingIntent pIntentDisconnect = PendingIntent.getBroadcast(mContext, type, sapDisconnectIntent, flags); Notification.Action actionDisconnect = - new Notification.Action.Builder(Icon.createWithResource(mContext, - android.R.drawable.stat_sys_data_bluetooth), button, - pIntentDisconnect).build(); + new Notification.Action.Builder( + Icon.createWithResource( + mContext, android.R.drawable.stat_sys_data_bluetooth), + button, + pIntentDisconnect) + .build(); notification = - new Notification.Builder(mContext, SAP_NOTIFICATION_CHANNEL).setOngoing(true) + new Notification.Builder(mContext, SAP_NOTIFICATION_CHANNEL) + .setOngoing(true) .addAction(actionDisconnect) .setContentTitle(title) .setTicker(ticker) @@ -275,29 +280,36 @@ public class SapServer extends Thread implements Callback { .setLocalOnly(true) .build(); } else { - sapDisconnectIntent.putExtra(SapServer.SAP_DISCONNECT_TYPE_EXTRA, - SapMessage.DISC_GRACEFULL); + sapDisconnectIntent.putExtra( + SapServer.SAP_DISCONNECT_TYPE_EXTRA, SapMessage.DISC_GRACEFULL); Intent sapForceDisconnectIntent = new Intent(SapServer.SAP_DISCONNECT_ACTION); - sapForceDisconnectIntent.putExtra(SapServer.SAP_DISCONNECT_TYPE_EXTRA, - SapMessage.DISC_IMMEDIATE); + sapForceDisconnectIntent.putExtra( + SapServer.SAP_DISCONNECT_TYPE_EXTRA, SapMessage.DISC_IMMEDIATE); PendingIntent pIntentDisconnect = - PendingIntent.getBroadcast(mContext, SapMessage.DISC_GRACEFULL, - sapDisconnectIntent, flags); + PendingIntent.getBroadcast( + mContext, SapMessage.DISC_GRACEFULL, sapDisconnectIntent, flags); PendingIntent pIntentForceDisconnect = - PendingIntent.getBroadcast(mContext, SapMessage.DISC_IMMEDIATE, - sapForceDisconnectIntent, flags); - Notification.Action actionDisconnect = new Notification.Action.Builder( - Icon.createWithResource(mContext, android.R.drawable.stat_sys_data_bluetooth), - mContext.getString(R.string.bluetooth_sap_notif_disconnect_button), - pIntentDisconnect).build(); + PendingIntent.getBroadcast( + mContext, SapMessage.DISC_IMMEDIATE, sapForceDisconnectIntent, flags); + Notification.Action actionDisconnect = + new Notification.Action.Builder( + Icon.createWithResource( + mContext, android.R.drawable.stat_sys_data_bluetooth), + mContext.getString( + R.string.bluetooth_sap_notif_disconnect_button), + pIntentDisconnect) + .build(); Notification.Action actionForceDisconnect = - new Notification.Action.Builder(Icon.createWithResource(mContext, - android.R.drawable.stat_sys_data_bluetooth), - mContext.getString( - R.string.bluetooth_sap_notif_force_disconnect_button), - pIntentForceDisconnect).build(); + new Notification.Action.Builder( + Icon.createWithResource( + mContext, android.R.drawable.stat_sys_data_bluetooth), + mContext.getString( + R.string.bluetooth_sap_notif_force_disconnect_button), + pIntentForceDisconnect) + .build(); notification = - new Notification.Builder(mContext, SAP_NOTIFICATION_CHANNEL).setOngoing(true) + new Notification.Builder(mContext, SAP_NOTIFICATION_CHANNEL) + .setOngoing(true) .addAction(actionDisconnect) .addAction(actionForceDisconnect) .setContentTitle(title) @@ -323,8 +335,8 @@ public class SapServer extends Thread implements Callback { } /** - * The SapServer RFCOMM reader thread. Sets up the handler thread and handle - * all read from the RFCOMM in-socket. This thread also handle writes to the RIL socket. + * The SapServer RFCOMM reader thread. Sets up the handler thread and handle all read from the + * RFCOMM in-socket. This thread also handle writes to the RIL socket. */ @Override public void run() { @@ -334,8 +346,9 @@ public class SapServer extends Thread implements Callback { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); /* Start the SAP message handler thread */ - mHandlerThread = new HandlerThread("SapServerHandler", - android.os.Process.THREAD_PRIORITY_BACKGROUND); + mHandlerThread = + new HandlerThread( + "SapServerHandler", android.os.Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.start(); // This will return when the looper is ready @@ -384,8 +397,10 @@ public class SapServer extends Thread implements Callback { Log.v(TAG, "DISCONNECT_REQ"); if (mState == SAP_STATE.CONNECTING_CALL_ONGOING) { - Log.d(TAG, "disconnect received when call was ongoing, " - + "send disconnect response"); + Log.d( + TAG, + "disconnect received when call was ongoing, " + + "send disconnect response"); changeState(SAP_STATE.DISCONNECTING); SapMessage reply = new SapMessage(SapMessage.ID_DISCONNECT_RESP); @@ -408,10 +423,13 @@ public class SapServer extends Thread implements Callback { case SapMessage.ID_SET_TRANSPORT_PROTOCOL_REQ: /* The RIL might support more protocols that specified in the SAP, * allow only the valid values. */ - if (mState == SAP_STATE.CONNECTED && msg.getTransportProtocol() != 0 + if (mState == SAP_STATE.CONNECTED + && msg.getTransportProtocol() != 0 && msg.getTransportProtocol() != 1) { - Log.w(TAG, "Invalid TransportProtocol received:" - + msg.getTransportProtocol()); + Log.w( + TAG, + "Invalid TransportProtocol received:" + + msg.getTransportProtocol()); // We shall only handle one request at the time, hence return // error SapMessage errorReply = @@ -425,8 +443,10 @@ public class SapServer extends Thread implements Callback { we are * in busy state. */ if (mState != SAP_STATE.CONNECTED) { - Log.w(TAG, "Message received in STATE != CONNECTED - state = " - + mState.name()); + Log.w( + TAG, + "Message received in STATE != CONNECTED - state = " + + mState.name()); // We shall only handle one request at the time, hence return // error SapMessage errorReply = @@ -442,7 +462,7 @@ public class SapServer extends Thread implements Callback { } } else { - //An unknown message or in disconnecting state - send error indication + // An unknown message or in disconnecting state - send error indication Log.e(TAG, "Unable to parse message."); SapMessage atrReply = new SapMessage(SapMessage.ID_ERROR_RESP); sendClientMessage(atrReply); @@ -537,14 +557,11 @@ public class SapServer extends Thread implements Callback { } } - /** - * This function needs to determine: - * - if the maxMsgSize is acceptable - else reply CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED - * + new maxMsgSize if too big - * - connect to the RIL-BT socket - * - if a call is ongoing reply CON_STATUS_OK_ONGOING_CALL. - * - if all ok, just respond CON_STATUS_OK. + * This function needs to determine: - if the maxMsgSize is acceptable - else reply + * CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED + new maxMsgSize if too big - connect to the RIL-BT + * socket - if a call is ongoing reply CON_STATUS_OK_ONGOING_CALL. - if all ok, just respond + * CON_STATUS_OK. * * @param msg the incoming SapMessage */ @@ -612,9 +629,7 @@ public class SapServer extends Thread implements Callback { mSapHandler.sendMessage(newMsg); } - /** - * Send a RIL message to the SapServer message handler thread - */ + /** Send a RIL message to the SapServer message handler thread */ @VisibleForTesting void sendRilThreadMessage(SapMessage sapMsg) { Message newMsg = mSapHandler.obtainMessage(SAP_MSG_RIL_REQ, sapMsg); @@ -636,8 +651,8 @@ public class SapServer extends Thread implements Callback { } /** - * Change the SAP Server state. - * We add thread protection, as we access the state from two threads. + * Change the SAP Server state. We add thread protection, as we access the state from two + * threads. */ @VisibleForTesting void changeState(SAP_STATE newState) { @@ -652,16 +667,14 @@ public class SapServer extends Thread implements Callback { *************************************************************************/ /** - * The SapServer message handler thread implements the SAP state machine. - * - Handle all outgoing communication to the out-socket. Either replies from the RIL or direct - * messages send from the SapServe (e.g. connect_resp). - * - Handle all outgoing communication to the RIL-BT socket. - * - Handle all replies from the RIL + * The SapServer message handler thread implements the SAP state machine. - Handle all outgoing + * communication to the out-socket. Either replies from the RIL or direct messages send from the + * SapServe (e.g. connect_resp). - Handle all outgoing communication to the RIL-BT socket. - + * Handle all replies from the RIL */ @Override public boolean handleMessage(Message msg) { - Log.v(TAG_HANDLER, - "Handling message (ID: " + msg.what + "): " + getMessageName(msg.what)); + Log.v(TAG_HANDLER, "Handling message (ID: " + msg.what + "): " + getMessageName(msg.what)); SapMessage sapMsg = null; @@ -695,8 +708,8 @@ public class SapServer extends Thread implements Callback { handleRilInd(sapMsg); break; case SAP_RIL_SOCK_CLOSED: - /* The RIL socket was closed unexpectedly, send immediate disconnect indication - - close RFCOMM after timeout if no response. */ + /* The RIL socket was closed unexpectedly, send immediate disconnect indication + - close RFCOMM after timeout if no response. */ startDisconnectTimer(SapMessage.DISC_RFCOMM, DISCONNECT_TIMEOUT_RFCOMM); break; case SAP_PROXY_DEAD: @@ -710,8 +723,8 @@ public class SapServer extends Thread implements Callback { } /** - * Close the in/out rfcomm streams, to trigger a shutdown of the SapServer main thread. - * Use this after completing the deinit sequence. + * Close the in/out rfcomm streams, to trigger a shutdown of the SapServer main thread. Use this + * after completing the deinit sequence. */ @VisibleForTesting void shutdown() { @@ -743,14 +756,20 @@ public class SapServer extends Thread implements Callback { Intent sapDisconnectIntent = new Intent(SapServer.SAP_DISCONNECT_ACTION); sapDisconnectIntent.putExtra(SAP_DISCONNECT_TYPE_EXTRA, discType); AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class); - mPendingDiscIntent = PendingIntent.getBroadcast(mContext, discType, sapDisconnectIntent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + timeMs, mPendingDiscIntent); - - Log.v(TAG_HANDLER, - "Setting alarm for " + timeMs + " ms to activate disconnect type " - + discType); + mPendingDiscIntent = + PendingIntent.getBroadcast( + mContext, + discType, + sapDisconnectIntent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); + alarmManager.set( + AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + timeMs, + mPendingDiscIntent); + + Log.v( + TAG_HANDLER, + "Setting alarm for " + timeMs + " ms to activate disconnect type " + discType); } } @@ -768,9 +787,9 @@ public class SapServer extends Thread implements Callback { } /** - * Here we handle the replies to the SAP client, normally forwarded directly from the RIL. - * We do need to handle some of the messages in the SAP profile, hence we look at the messages - * here before they go to the client + * Here we handle the replies to the SAP client, normally forwarded directly from the RIL. We do + * need to handle some of the messages in the SAP profile, hence we look at the messages here + * before they go to the client * * @param sapMsg the message to send to the SAP client */ @@ -778,11 +797,12 @@ public class SapServer extends Thread implements Callback { void handleRfcommReply(SapMessage sapMsg) { if (sapMsg != null) { - Log.d(TAG_HANDLER, "handleRfcommReply() handling " + SapMessage.getMsgTypeName( - sapMsg.getMsgType())); + Log.d( + TAG_HANDLER, + "handleRfcommReply() handling " + + SapMessage.getMsgTypeName(sapMsg.getMsgType())); switch (sapMsg.getMsgType()) { - case SapMessage.ID_CONNECT_RESP: if (mState == SAP_STATE.CONNECTING_CALL_ONGOING) { /* Hold back the connect resp if a call was ongoing when the connect req @@ -794,8 +814,10 @@ public class SapServer extends Thread implements Callback { // This is successful connect response from RIL/modem. changeState(SAP_STATE.CONNECTED); } - Log.v(TAG, "Hold back the connect resp, as a call was ongoing" - + " when the initial response were sent."); + Log.v( + TAG, + "Hold back the connect resp, as a call was ongoing" + + " when the initial response were sent."); sapMsg = null; } else if (sapMsg.getConnectionStatus() == SapMessage.CON_STATUS_OK) { // This is successful connect response from RIL/modem. @@ -816,8 +838,7 @@ public class SapServer extends Thread implements Callback { if (mState == SAP_STATE.DISCONNECTING) { /* Close the RIL-BT output Stream and signal to SapRilReceiver to close * down the input stream. */ - Log.d(TAG, - "ID_DISCONNECT_RESP received in SAP_STATE." + "DISCONNECTING."); + Log.d(TAG, "ID_DISCONNECT_RESP received in SAP_STATE." + "DISCONNECTING."); /* Send the disconnect resp, and wait for the client to close the Rfcomm, * but start a timeout timer, just to be sure. Use alarm, to ensure we wake @@ -827,7 +848,8 @@ public class SapServer extends Thread implements Callback { sapMsg = disconnectResp; startDisconnectTimer(SapMessage.DISC_RFCOMM, DISCONNECT_TIMEOUT_RFCOMM); mDeinitSignal.countDown(); /* Signal deinit complete */ - } else { /* DISCONNECTED */ + } else { + /* DISCONNECTED */ mDeinitSignal.countDown(); /* Signal deinit complete */ if (mIsLocalInitDisconnect) { Log.v(TAG_HANDLER, "This is a FORCED disconnect."); @@ -848,7 +870,8 @@ public class SapServer extends Thread implements Callback { case SapMessage.ID_STATUS_IND: /* Some car-kits only "likes" status indication when connected, hence discard * any arriving outside this state */ - if (mState == SAP_STATE.DISCONNECTED || mState == SAP_STATE.CONNECTING + if (mState == SAP_STATE.DISCONNECTED + || mState == SAP_STATE.CONNECTING || mState == SAP_STATE.DISCONNECTING) { sapMsg = null; } @@ -889,36 +912,37 @@ public class SapServer extends Thread implements Callback { } switch (sapMsg.getMsgType()) { - case SapMessage.ID_RIL_UNSOL_DISCONNECT_IND: { - if (mState != SAP_STATE.DISCONNECTED && mState != SAP_STATE.DISCONNECTING) { - /* we only send disconnect indication to the client if we are actually - connected*/ - SapMessage reply = new SapMessage(SapMessage.ID_DISCONNECT_IND); - reply.setDisconnectionType(sapMsg.getDisconnectionType()); - sendClientMessage(reply); - } else { - /* TODO: This was introduced to handle disconnect indication from RIL */ - sendDisconnectInd(sapMsg.getDisconnectionType()); + case SapMessage.ID_RIL_UNSOL_DISCONNECT_IND: + { + if (mState != SAP_STATE.DISCONNECTED && mState != SAP_STATE.DISCONNECTING) { + /* we only send disconnect indication to the client if we are actually + connected*/ + SapMessage reply = new SapMessage(SapMessage.ID_DISCONNECT_IND); + reply.setDisconnectionType(sapMsg.getDisconnectionType()); + sendClientMessage(reply); + } else { + /* TODO: This was introduced to handle disconnect indication from RIL */ + sendDisconnectInd(sapMsg.getDisconnectionType()); + } + break; } - break; - } default: - Log.w(TAG_HANDLER, "Unhandled message - type: " + SapMessage.getMsgTypeName( - sapMsg.getMsgType())); + Log.w( + TAG_HANDLER, + "Unhandled message - type: " + + SapMessage.getMsgTypeName(sapMsg.getMsgType())); } } - /** - * This is only to be called from the handlerThread, else use sendRilThreadMessage(); - */ + /** This is only to be called from the handlerThread, else use sendRilThreadMessage(); */ @VisibleForTesting void sendRilMessage(SapMessage sapMsg) { - Log.v(TAG_HANDLER, - "sendRilMessage() - " + SapMessage.getMsgTypeName(sapMsg.getMsgType())); + Log.v(TAG_HANDLER, "sendRilMessage() - " + SapMessage.getMsgTypeName(sapMsg.getMsgType())); synchronized (mRilBtReceiver.getSapProxyLock()) { if (!mRilBtReceiver.isProxyValid()) { - Log.e(TAG_HANDLER, + Log.e( + TAG_HANDLER, "sendRiilMessage: Unable to send message to Ril; sapProxy is invalid"); sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP)); return; @@ -936,16 +960,12 @@ public class SapServer extends Thread implements Callback { mRilBtReceiver.resetSapProxy(); } } - } - /** - * Only call this from the sapHandler thread. - */ + /** Only call this from the sapHandler thread. */ @VisibleForTesting void sendReply(SapMessage msg) { - Log.v(TAG_HANDLER, - "sendReply() RFCOMM - " + SapMessage.getMsgTypeName(msg.getMsgType())); + Log.v(TAG_HANDLER, "sendReply() RFCOMM - " + SapMessage.getMsgTypeName(msg.getMsgType())); if (mRfcommOut != null) { // Needed to handle brutal shutdown from car-kit and out of range try { msg.write(mRfcommOut); @@ -953,7 +973,7 @@ public class SapServer extends Thread implements Callback { } catch (IOException e) { Log.w(TAG_HANDLER, e); /* As we cannot write to the rfcomm channel we are disconnected. - Shutdown and prepare for a new connect. */ + Shutdown and prepare for a new connect. */ } } } @@ -973,6 +993,4 @@ public class SapServer extends Thread implements Callback { return "Unknown message ID"; } } - } - diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java index e978be7d34a..24caab0c747 100644 --- a/android/app/src/com/android/bluetooth/sap/SapService.java +++ b/android/app/src/com/android/bluetooth/sap/SapService.java @@ -48,13 +48,13 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo private static final String TAG = "SapService"; /** - * To log debug/verbose in SAP, use the command "setprop log.tag.SapService DEBUG" or - * "setprop log.tag.SapService VERBOSE" and then "adb root" + "adb shell "stop; start"" - **/ - + * To log debug/verbose in SAP, use the command "setprop log.tag.SapService DEBUG" or "setprop + * log.tag.SapService VERBOSE" and then "adb root" + "adb shell "stop; start"" + */ /* Message ID's */ private static final int START_LISTENER = 1; + private static final int USER_TIMEOUT = 2; private static final int SHUTDOWN = 3; @@ -102,7 +102,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo private static SapService sSapService; private static final ParcelUuid[] SAP_UUIDS = { - BluetoothUuid.SAP, + BluetoothUuid.SAP, }; public SapService(Context ctx) { @@ -161,8 +161,12 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo // It is mandatory for MSE to support initiation of bonding and encryption. // TODO: Consider reusing the mServerSocket - it is indented to be reused // for multiple connections. - mServerSocket = BluetoothAdapter.getDefaultAdapter().listenUsingRfcommOn( - BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, true, true); + mServerSocket = + BluetoothAdapter.getDefaultAdapter() + .listenUsingRfcommOn( + BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, + true, + true); removeSdpRecord(); mSdpHandle = SdpManagerNativeInterface.getInstance() @@ -184,8 +188,8 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo break; } int state = mAdapterService.getState(); - if ((state != BluetoothAdapter.STATE_TURNING_ON) && (state - != BluetoothAdapter.STATE_ON)) { + if ((state != BluetoothAdapter.STATE_TURNING_ON) + && (state != BluetoothAdapter.STATE_ON)) { Log.w(TAG, "initServerSocket failed as BT is (being) turned off"); break; } @@ -274,8 +278,12 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } /* Start the SAP I/O thread and associate with message handler */ - mSapServer = new SapServer(mSessionStatusHandler, this, mConnSocket.getInputStream(), - mConnSocket.getOutputStream()); + mSapServer = + new SapServer( + mSessionStatusHandler, + this, + mConnSocket.getInputStream(), + mConnSocket.getOutputStream()); mSapServer.start(); /* Warning: at this point we most likely have already handled the initial connect * request from the SAP client, hence we need to be prepared to handle the @@ -314,10 +322,9 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } /** - * A thread that runs in the background waiting for remote rfcomm - * connect.Once a remote socket connected, this thread shall be - * shutdown.When the remote disconnect,this thread shall run again waiting - * for next request. + * A thread that runs in the background waiting for remote rfcomm connect.Once a remote socket + * connected, this thread shall be shutdown.When the remote disconnect,this thread shall run + * again waiting for next request. */ private class SocketAcceptThread extends Thread { @@ -366,8 +373,11 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo if (permission == BluetoothDevice.ACCESS_ALLOWED) { try { - Log.v(TAG, "incoming connection accepted from: " + sRemoteDeviceName - + " automatically as trusted device"); + Log.v( + TAG, + "incoming connection accepted from: " + + sRemoteDeviceName + + " automatically as trusted device"); startSapServerSession(); } catch (IOException ex) { Log.e(TAG, "catch exception starting obex server session", ex); @@ -375,10 +385,12 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } else if (permission != BluetoothDevice.ACCESS_REJECTED) { Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); - intent.setPackage(SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - getString(R.string.pairing_ui_package))); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + intent.setPackage( + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, + getString(R.string.pairing_ui_package))); + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_SIM_ACCESS); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); intent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, getPackageName()); @@ -390,14 +402,19 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); - Log.v(TAG, "waiting for authorization for connection from: " - + sRemoteDeviceName); + Log.v( + TAG, + "waiting for authorization for connection from: " + + sRemoteDeviceName); } else { // Close RFCOMM socket for current connection and start listening // again for new connections. - Log.w(TAG, "Can't connect with " + sRemoteDeviceName - + " as access is rejected"); + Log.w( + TAG, + "Can't connect with " + + sRemoteDeviceName + + " as access is rejected"); if (mSessionStatusHandler != null) { mSessionStatusHandler.sendEmptyMessage(MSG_SERVERSESSION_CLOSE); } @@ -416,71 +433,74 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } } - private final Handler mSessionStatusHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - Log.v(TAG, "Handler(): got msg=" + msg.what); - - switch (msg.what) { - case START_LISTENER: - if (mAdapterService.isEnabled()) { - startRfcommSocketListener(); - } - break; - case USER_TIMEOUT: - if (mIsWaitingAuthorization) { - sendCancelUserConfirmationIntent(mRemoteDevice); - cancelUserTimeoutAlarm(); - mIsWaitingAuthorization = false; - stopSapServerSession(); // And restart RfcommListener if needed - } - break; - case MSG_SERVERSESSION_CLOSE: - stopSapServerSession(); - break; - case MSG_SESSION_ESTABLISHED: - break; - case MSG_SESSION_DISCONNECTED: - // handled elsewhere - break; - case MSG_ACQUIRE_WAKE_LOCK: - Log.v(TAG, "Acquire Wake Lock request message"); - if (mWakeLock == null) { - PowerManager pm = getSystemService(PowerManager.class); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "StartingObexMapTransaction"); - mWakeLock.setReferenceCounted(false); - } - if (!mWakeLock.isHeld()) { - mWakeLock.acquire(); - Log.d(TAG, " Acquired Wake Lock by message"); - } - mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); - mSessionStatusHandler.sendMessageDelayed( - mSessionStatusHandler.obtainMessage(MSG_RELEASE_WAKE_LOCK), - RELEASE_WAKE_LOCK_DELAY); - break; - case MSG_RELEASE_WAKE_LOCK: - Log.v(TAG, "Release Wake Lock request message"); - if (mWakeLock != null) { - mWakeLock.release(); - Log.d(TAG, " Released Wake Lock by message"); + private final Handler mSessionStatusHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + Log.v(TAG, "Handler(): got msg=" + msg.what); + + switch (msg.what) { + case START_LISTENER: + if (mAdapterService.isEnabled()) { + startRfcommSocketListener(); + } + break; + case USER_TIMEOUT: + if (mIsWaitingAuthorization) { + sendCancelUserConfirmationIntent(mRemoteDevice); + cancelUserTimeoutAlarm(); + mIsWaitingAuthorization = false; + stopSapServerSession(); // And restart RfcommListener if needed + } + break; + case MSG_SERVERSESSION_CLOSE: + stopSapServerSession(); + break; + case MSG_SESSION_ESTABLISHED: + break; + case MSG_SESSION_DISCONNECTED: + // handled elsewhere + break; + case MSG_ACQUIRE_WAKE_LOCK: + Log.v(TAG, "Acquire Wake Lock request message"); + if (mWakeLock == null) { + PowerManager pm = getSystemService(PowerManager.class); + mWakeLock = + pm.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, + "StartingObexMapTransaction"); + mWakeLock.setReferenceCounted(false); + } + if (!mWakeLock.isHeld()) { + mWakeLock.acquire(); + Log.d(TAG, " Acquired Wake Lock by message"); + } + mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); + mSessionStatusHandler.sendMessageDelayed( + mSessionStatusHandler.obtainMessage(MSG_RELEASE_WAKE_LOCK), + RELEASE_WAKE_LOCK_DELAY); + break; + case MSG_RELEASE_WAKE_LOCK: + Log.v(TAG, "Release Wake Lock request message"); + if (mWakeLock != null) { + mWakeLock.release(); + Log.d(TAG, " Released Wake Lock by message"); + } + break; + case MSG_CHANGE_STATE: + Log.d(TAG, "change state message: newState = " + msg.arg1); + setState(msg.arg1); + break; + case SHUTDOWN: + /* Ensure to call close from this handler to avoid starting new stuff + because of pending messages */ + closeService(); + break; + default: + break; } - break; - case MSG_CHANGE_STATE: - Log.d(TAG, "change state message: newState = " + msg.arg1); - setState(msg.arg1); - break; - case SHUTDOWN: - /* Ensure to call close from this handler to avoid starting new stuff - because of pending messages */ - closeService(); - break; - default: - break; - } - } - }; + } + }; private void setState(int state) { setState(state, BluetoothSap.RESULT_SUCCESS); @@ -569,7 +589,8 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo public int getConnectionState(BluetoothDevice device) { synchronized (this) { - if (getState() == BluetoothSap.STATE_CONNECTED && getRemoteDevice() != null + if (getState() == BluetoothSap.STATE_CONNECTED + && getRemoteDevice() != null && getRemoteDevice().equals(device)) { return BluetoothProfile.STATE_CONNECTED; } else { @@ -579,14 +600,13 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } /** - * Set connection policy of the profile and disconnects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and disconnects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device * @param connectionPolicy is the connection policy to set to for this profile @@ -595,9 +615,10 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - AdapterService.getAdapterService().getDatabase() + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + AdapterService.getAdapterService() + .getDatabase() .setProfileConnectionPolicy(device, BluetoothProfile.SAP, connectionPolicy); if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { disconnect(device); @@ -608,19 +629,19 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo /** * Get the connection policy of the profile. * - *

The connection policy can be any of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device Bluetooth device * @return connection policy of the device */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - return AdapterService.getAdapterService().getDatabase() + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + return AdapterService.getAdapterService() + .getDatabase() .getProfileConnectionPolicy(device, BluetoothProfile.SAP); } @@ -719,10 +740,12 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo cancelUserTimeoutAlarm(); mRemoveTimeoutMsg = true; Intent timeoutIntent = new Intent(USER_CONFIRM_TIMEOUT_ACTION); - PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, timeoutIntent, - PendingIntent.FLAG_IMMUTABLE); - mAlarmManager.set(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + USER_CONFIRM_TIMEOUT_VALUE, pIntent); + PendingIntent pIntent = + PendingIntent.getBroadcast(this, 0, timeoutIntent, PendingIntent.FLAG_IMMUTABLE); + mAlarmManager.set( + AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + USER_CONFIRM_TIMEOUT_VALUE, + pIntent); } private void cancelUserTimeoutAlarm() { @@ -732,8 +755,9 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } if (mRemoveTimeoutMsg) { Intent timeoutIntent = new Intent(USER_CONFIRM_TIMEOUT_ACTION); - PendingIntent sender = PendingIntent.getBroadcast(this, 0, timeoutIntent, - PendingIntent.FLAG_IMMUTABLE); + PendingIntent sender = + PendingIntent.getBroadcast( + this, 0, timeoutIntent, PendingIntent.FLAG_IMMUTABLE); mAlarmManager.cancel(sender); mRemoveTimeoutMsg = false; } @@ -741,12 +765,12 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo private void sendCancelUserConfirmationIntent(BluetoothDevice device) { Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); - intent.setPackage(SystemProperties.get( - Utils.PAIRING_UI_PROPERTY, - getString(R.string.pairing_ui_package))); + intent.setPackage( + SystemProperties.get( + Utils.PAIRING_UI_PROPERTY, getString(R.string.pairing_ui_package))); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, - BluetoothDevice.REQUEST_TYPE_SIM_ACCESS); + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_SIM_ACCESS); sendBroadcast(intent, BLUETOOTH_CONNECT); } @@ -793,17 +817,20 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo mIsWaitingAuthorization = false; - if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, - BluetoothDevice.CONNECTION_ACCESS_NO) + if (intent.getIntExtra( + BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, + BluetoothDevice.CONNECTION_ACCESS_NO) == BluetoothDevice.CONNECTION_ACCESS_YES) { // bluetooth connection accepted by user if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { - boolean result = mRemoteDevice.setSimAccessPermission( - BluetoothDevice.ACCESS_ALLOWED); + boolean result = + mRemoteDevice.setSimAccessPermission( + BluetoothDevice.ACCESS_ALLOWED); Log.v(TAG, "setSimAccessPermission(ACCESS_ALLOWED) result=" + result); } - boolean result = setConnectionPolicy(mRemoteDevice, - BluetoothProfile.CONNECTION_POLICY_ALLOWED); + boolean result = + setConnectionPolicy( + mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_ALLOWED); Log.d(TAG, "setConnectionPolicy ALLOWED, result = " + result); try { @@ -818,12 +845,14 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } } else { if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { - boolean result = mRemoteDevice.setSimAccessPermission( - BluetoothDevice.ACCESS_REJECTED); + boolean result = + mRemoteDevice.setSimAccessPermission( + BluetoothDevice.ACCESS_REJECTED); Log.v(TAG, "setSimAccessPermission(ACCESS_REJECTED) result=" + result); } - boolean result = setConnectionPolicy(mRemoteDevice, - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + boolean result = + setConnectionPolicy( + mRemoteDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); Log.d(TAG, "setConnectionPolicy FORBIDDEN, result = " + result); // Ensure proper cleanup, and prepare for new connect. mSessionStatusHandler.sendEmptyMessage(MSG_SERVERSESSION_CLOSE); @@ -867,7 +896,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } } - //Binder object: Must be static class or memory leak may occur + // Binder object: Must be static class or memory leak may occur /** * This class implements the IBluetoothSap interface - or actually it validates the diff --git a/android/app/src/com/android/bluetooth/sdp/SdpManager.java b/android/app/src/com/android/bluetooth/sdp/SdpManager.java index cb9d62df67c..69b5f54f4b8 100644 --- a/android/app/src/com/android/bluetooth/sdp/SdpManager.java +++ b/android/app/src/com/android/bluetooth/sdp/SdpManager.java @@ -1,17 +1,17 @@ /* -* Copyright (C) 2015 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2015 Samsung System LSI + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.bluetooth.sdp; import static android.Manifest.permission.BLUETOOTH_CONNECT; @@ -512,7 +512,7 @@ public class SdpManager { intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle()); if (!moreResults) { - //Remove the outstanding UUID request + // Remove the outstanding UUID request mSdpSearchTracker.remove(inst); mSearchInProgress = false; startSearch(); diff --git a/android/app/src/com/android/bluetooth/tbs/BluetoothGattServerProxy.java b/android/app/src/com/android/bluetooth/tbs/BluetoothGattServerProxy.java index 9c7501d03fa..46ee51777a0 100644 --- a/android/app/src/com/android/bluetooth/tbs/BluetoothGattServerProxy.java +++ b/android/app/src/com/android/bluetooth/tbs/BluetoothGattServerProxy.java @@ -32,9 +32,9 @@ import java.util.UUID; /** * A proxy class that facilitates testing of the TbsService class. * - * This is necessary due to the "final" attribute of the BluetoothGattServer class. In order to test - * the correct functioning of the TbsService class, the final class must be put into a container - * that can be mocked correctly. + *

This is necessary due to the "final" attribute of the BluetoothGattServer class. In order to + * test the correct functioning of the TbsService class, the final class must be put into a + * container that can be mocked correctly. */ public class BluetoothGattServerProxy { @@ -65,26 +65,26 @@ public class BluetoothGattServerProxy { } /** - * A proxy that Returns a {@link BluetoothGattService} from the list of services offered - * by this device. + * A proxy that Returns a {@link BluetoothGattService} from the list of services offered by this + * device. * - *

If multiple instances of the same service (as identified by UUID) - * exist, the first instance of the service is returned. + *

If multiple instances of the same service (as identified by UUID) exist, the first + * instance of the service is returned. * * @param uuid UUID of the requested service * @return BluetoothGattService if supported, or null if the requested service is not offered by - * this device. + * this device. */ public BluetoothGattService getService(UUID uuid) { return mBluetoothGattServer.getService(uuid); } /** - * See {@link android.bluetooth.BluetoothGattServer#sendResponse( - * android.bluetooth.BluetoothDevice, int, int, int, byte[])} - */ - public boolean sendResponse(BluetoothDevice device, int requestId, int status, int offset, - byte[] value) { + * See {@link android.bluetooth.BluetoothGattServer#sendResponse( + * android.bluetooth.BluetoothDevice, int, int, int, byte[])} + */ + public boolean sendResponse( + BluetoothDevice device, int requestId, int status, int offset, byte[] value) { return mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); } @@ -92,23 +92,27 @@ public class BluetoothGattServerProxy { * See {@link android.bluetooth.BluetoothGattServer#notifyCharacteristicChanged( * android.bluetooth.BluetoothDevice, BluetoothGattCharacteristic, boolean, byte[])}. */ - public int notifyCharacteristicChanged(BluetoothDevice device, - BluetoothGattCharacteristic characteristic, boolean confirm, byte[] value) { - return mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, confirm, - value); + public int notifyCharacteristicChanged( + BluetoothDevice device, + BluetoothGattCharacteristic characteristic, + boolean confirm, + byte[] value) { + return mBluetoothGattServer.notifyCharacteristicChanged( + device, characteristic, confirm, value); } /** * See {@link android.bluetooth.BluetoothGattServer#notifyCharacteristicChanged( * android.bluetooth.BluetoothDevice, BluetoothGattCharacteristic, boolean)}. */ - public boolean notifyCharacteristicChanged(BluetoothDevice device, - BluetoothGattCharacteristic characteristic, boolean confirm) { + public boolean notifyCharacteristicChanged( + BluetoothDevice device, BluetoothGattCharacteristic characteristic, boolean confirm) { return mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, confirm); } /** * Get connected devices + * * @return list of connected devices */ public List getConnectedDevices() { diff --git a/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java b/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java index 06099c907e0..8c4c3718b38 100644 --- a/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java +++ b/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java @@ -53,18 +53,24 @@ public class BluetoothLeCallControlProxy { } public void closeBluetoothLeCallControlProxy(Context context) { - final BluetoothManager btManager = - context.getSystemService(BluetoothManager.class); + final BluetoothManager btManager = context.getSystemService(BluetoothManager.class); if (btManager != null) { - btManager.getAdapter().closeProfileProxy(BluetoothProfile.LE_CALL_CONTROL, - mBluetoothLeCallControl); + btManager + .getAdapter() + .closeProfileProxy(BluetoothProfile.LE_CALL_CONTROL, mBluetoothLeCallControl); } } - public boolean registerBearer(String uci, List uriSchemes, int featureFlags, - String provider, int technology, Executor executor, BluetoothLeCallControl.Callback callback) { - return mBluetoothLeCallControl.registerBearer(uci, uriSchemes, featureFlags, provider, technology, - executor, callback); + public boolean registerBearer( + String uci, + List uriSchemes, + int featureFlags, + String provider, + int technology, + Executor executor, + BluetoothLeCallControl.Callback callback) { + return mBluetoothLeCallControl.registerBearer( + uci, uriSchemes, featureFlags, provider, technology, executor, callback); } public void unregisterBearer() { diff --git a/android/app/src/com/android/bluetooth/tbs/TbsCall.java b/android/app/src/com/android/bluetooth/tbs/TbsCall.java index 7e000b7e9c0..4776ab9943f 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsCall.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsCall.java @@ -95,16 +95,14 @@ public class TbsCall { } public static TbsCall create(BluetoothLeCall call) { - return new TbsCall(call.getState(), call.getUri(), call.getCallFlags(), - call.getFriendlyName()); + return new TbsCall( + call.getState(), call.getUri(), call.getCallFlags(), call.getFriendlyName()); } @Override public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; TbsCall that = (TbsCall) o; // check the state only return mState == that.mState; @@ -143,7 +141,8 @@ public class TbsCall { * * @return safe Friendly Name */ - public String getSafeFriendlyName() {; + public String getSafeFriendlyName() { + ; if (mFriendlyName == null) { return null; } diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java index ac23e52d761..75ad1298678 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java @@ -58,74 +58,53 @@ public class TbsGatt { private static final String UUID_SUFFIX = "-0000-1000-8000-00805f9b34fb"; /* TBS assigned uuid's */ - @VisibleForTesting - static final UUID UUID_TBS = makeUuid("184B"); - @VisibleForTesting - public static final UUID UUID_GTBS = makeUuid("184C"); - @VisibleForTesting - static final UUID UUID_BEARER_PROVIDER_NAME = makeUuid("2BB3"); - @VisibleForTesting - static final UUID UUID_BEARER_UCI = makeUuid("2BB4"); - @VisibleForTesting - static final UUID UUID_BEARER_TECHNOLOGY = makeUuid("2BB5"); - @VisibleForTesting - static final UUID UUID_BEARER_URI_SCHEMES_SUPPORTED_LIST = makeUuid("2BB6"); - @VisibleForTesting - static final UUID UUID_BEARER_LIST_CURRENT_CALLS = makeUuid("2BB9"); - @VisibleForTesting - static final UUID UUID_CONTENT_CONTROL_ID = makeUuid("2BBA"); - @VisibleForTesting - static final UUID UUID_STATUS_FLAGS = makeUuid("2BBB"); - @VisibleForTesting - static final UUID UUID_CALL_STATE = makeUuid("2BBD"); - @VisibleForTesting - static final UUID UUID_CALL_CONTROL_POINT = makeUuid("2BBE"); + @VisibleForTesting static final UUID UUID_TBS = makeUuid("184B"); + @VisibleForTesting public static final UUID UUID_GTBS = makeUuid("184C"); + @VisibleForTesting static final UUID UUID_BEARER_PROVIDER_NAME = makeUuid("2BB3"); + @VisibleForTesting static final UUID UUID_BEARER_UCI = makeUuid("2BB4"); + @VisibleForTesting static final UUID UUID_BEARER_TECHNOLOGY = makeUuid("2BB5"); + @VisibleForTesting static final UUID UUID_BEARER_URI_SCHEMES_SUPPORTED_LIST = makeUuid("2BB6"); + @VisibleForTesting static final UUID UUID_BEARER_LIST_CURRENT_CALLS = makeUuid("2BB9"); + @VisibleForTesting static final UUID UUID_CONTENT_CONTROL_ID = makeUuid("2BBA"); + @VisibleForTesting static final UUID UUID_STATUS_FLAGS = makeUuid("2BBB"); + @VisibleForTesting static final UUID UUID_CALL_STATE = makeUuid("2BBD"); + @VisibleForTesting static final UUID UUID_CALL_CONTROL_POINT = makeUuid("2BBE"); + @VisibleForTesting static final UUID UUID_CALL_CONTROL_POINT_OPTIONAL_OPCODES = makeUuid("2BBF"); - @VisibleForTesting - static final UUID UUID_TERMINATION_REASON = makeUuid("2BC0"); - @VisibleForTesting - static final UUID UUID_INCOMING_CALL = makeUuid("2BC1"); - @VisibleForTesting - static final UUID UUID_CALL_FRIENDLY_NAME = makeUuid("2BC2"); + + @VisibleForTesting static final UUID UUID_TERMINATION_REASON = makeUuid("2BC0"); + @VisibleForTesting static final UUID UUID_INCOMING_CALL = makeUuid("2BC1"); + @VisibleForTesting static final UUID UUID_CALL_FRIENDLY_NAME = makeUuid("2BC2"); + @VisibleForTesting static final UUID UUID_CLIENT_CHARACTERISTIC_CONFIGURATION = makeUuid("2902"); - @VisibleForTesting - static final int STATUS_FLAG_INBAND_RINGTONE_ENABLED = 0x0001; - @VisibleForTesting - static final int STATUS_FLAG_SILENT_MODE_ENABLED = 0x0002; + @VisibleForTesting static final int STATUS_FLAG_INBAND_RINGTONE_ENABLED = 0x0001; + @VisibleForTesting static final int STATUS_FLAG_SILENT_MODE_ENABLED = 0x0002; - @VisibleForTesting - static final int CALL_CONTROL_POINT_OPTIONAL_OPCODE_LOCAL_HOLD = 0x0001; - @VisibleForTesting - static final int CALL_CONTROL_POINT_OPTIONAL_OPCODE_JOIN = 0x0002; + @VisibleForTesting static final int CALL_CONTROL_POINT_OPTIONAL_OPCODE_LOCAL_HOLD = 0x0001; + @VisibleForTesting static final int CALL_CONTROL_POINT_OPTIONAL_OPCODE_JOIN = 0x0002; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_OPCODE_ACCEPT = 0x00; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_OPCODE_TERMINATE = 0x01; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD = 0x02; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE = 0x03; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_OPCODE_ORIGINATE = 0x04; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_OPCODE_JOIN = 0x05; + @VisibleForTesting public static final int CALL_CONTROL_POINT_OPCODE_ACCEPT = 0x00; + @VisibleForTesting public static final int CALL_CONTROL_POINT_OPCODE_TERMINATE = 0x01; + @VisibleForTesting public static final int CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD = 0x02; + @VisibleForTesting public static final int CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE = 0x03; + @VisibleForTesting public static final int CALL_CONTROL_POINT_OPCODE_ORIGINATE = 0x04; + @VisibleForTesting public static final int CALL_CONTROL_POINT_OPCODE_JOIN = 0x05; + + @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_SUCCESS = 0x00; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_RESULT_SUCCESS = 0x00; @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED = 0x01; + @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE = 0x02; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_RESULT_INVALID_CALL_INDEX = 0x03; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_RESULT_STATE_MISMATCH = 0x04; - @VisibleForTesting - public static final int CALL_CONTROL_POINT_RESULT_LACK_OF_RESOURCES = 0x05; + + @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_INVALID_CALL_INDEX = 0x03; + @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_STATE_MISMATCH = 0x04; + @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_LACK_OF_RESOURCES = 0x05; + @VisibleForTesting public static final int CALL_CONTROL_POINT_RESULT_INVALID_OUTGOING_URI = 0x06; @@ -146,8 +125,10 @@ public class TbsGatt { private final GattCharacteristic mCallFriendlyNameCharacteristic; private boolean mSilentMode = false; private Map mStatusFlagValue = new HashMap<>(); + @GuardedBy("mPendingGattOperationsLock") private Map> mPendingGattOperations = new HashMap<>(); + private BluetoothGattServerProxy mBluetoothGattServer; private Handler mHandler; private Callback mCallback; @@ -192,18 +173,18 @@ public class TbsGatt { } } - public static abstract class Callback { + public abstract static class Callback { public abstract void onServiceAdded(boolean success); - public abstract void onCallControlPointRequest(BluetoothDevice device, int opcode, - byte[] args); + public abstract void onCallControlPointRequest( + BluetoothDevice device, int opcode, byte[] args); /** * Check if device has enabled inband ringtone * * @param device device which is checked for inband ringtone availability - * @return {@code true} if enabled, {@code false} otherwise + * @return {@code true} if enabled, {@code false} otherwise */ public abstract boolean isInbandRingtoneEnabled(BluetoothDevice device); } @@ -216,9 +197,15 @@ public class TbsGatt { WRITE_DESCRIPTOR, } - GattOpContext(Operation operation, int requestId, - BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor, - boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { + GattOpContext( + Operation operation, + int requestId, + BluetoothGattCharacteristic characteristic, + BluetoothGattDescriptor descriptor, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value) { mOperation = operation; mRequestId = requestId; mCharacteristic = characteristic; @@ -229,8 +216,11 @@ public class TbsGatt { mValue = value; } - GattOpContext(Operation operation, int requestId, - BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor) { + GattOpContext( + Operation operation, + int requestId, + BluetoothGattCharacteristic characteristic, + BluetoothGattDescriptor descriptor) { mOperation = operation; mRequestId = requestId; mCharacteristic = characteristic; @@ -261,52 +251,73 @@ public class TbsGatt { mAdapterService.registerBluetoothStateCallback( mContext.getMainExecutor(), mBluetoothStateChangeCallback); - mBearerProviderNameCharacteristic = new GattCharacteristic(UUID_BEARER_PROVIDER_NAME, - BluetoothGattCharacteristic.PROPERTY_READ - | BluetoothGattCharacteristic.PROPERTY_NOTIFY, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mBearerProviderNameCharacteristic = + new GattCharacteristic( + UUID_BEARER_PROVIDER_NAME, + BluetoothGattCharacteristic.PROPERTY_READ + | BluetoothGattCharacteristic.PROPERTY_NOTIFY, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); mBearerUciCharacteristic = - new GattCharacteristic(UUID_BEARER_UCI, BluetoothGattCharacteristic.PROPERTY_READ, + new GattCharacteristic( + UUID_BEARER_UCI, + BluetoothGattCharacteristic.PROPERTY_READ, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mBearerTechnologyCharacteristic = + new GattCharacteristic( + UUID_BEARER_TECHNOLOGY, + BluetoothGattCharacteristic.PROPERTY_READ + | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); - mBearerTechnologyCharacteristic = new GattCharacteristic(UUID_BEARER_TECHNOLOGY, - BluetoothGattCharacteristic.PROPERTY_READ - | BluetoothGattCharacteristic.PROPERTY_NOTIFY, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); mBearerUriSchemesSupportedListCharacteristic = - new GattCharacteristic(UUID_BEARER_URI_SCHEMES_SUPPORTED_LIST, + new GattCharacteristic( + UUID_BEARER_URI_SCHEMES_SUPPORTED_LIST, BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); mBearerListCurrentCallsCharacteristic = - new GattCharacteristic(UUID_BEARER_LIST_CURRENT_CALLS, + new GattCharacteristic( + UUID_BEARER_LIST_CURRENT_CALLS, + BluetoothGattCharacteristic.PROPERTY_READ + | BluetoothGattCharacteristic.PROPERTY_NOTIFY, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mContentControlIdCharacteristic = + new GattCharacteristic( + UUID_CONTENT_CONTROL_ID, + BluetoothGattCharacteristic.PROPERTY_READ, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mStatusFlagsCharacteristic = + new GattCharacteristic( + UUID_STATUS_FLAGS, + BluetoothGattCharacteristic.PROPERTY_READ + | BluetoothGattCharacteristic.PROPERTY_NOTIFY, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mCallStateCharacteristic = + new GattCharacteristic( + UUID_CALL_STATE, BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); - mContentControlIdCharacteristic = new GattCharacteristic(UUID_CONTENT_CONTROL_ID, - BluetoothGattCharacteristic.PROPERTY_READ, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); - mStatusFlagsCharacteristic = new GattCharacteristic(UUID_STATUS_FLAGS, - BluetoothGattCharacteristic.PROPERTY_READ - | BluetoothGattCharacteristic.PROPERTY_NOTIFY, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); - mCallStateCharacteristic = new GattCharacteristic(UUID_CALL_STATE, - BluetoothGattCharacteristic.PROPERTY_READ - | BluetoothGattCharacteristic.PROPERTY_NOTIFY, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); mCallControlPointCharacteristic = new CallControlPointCharacteristic(); - mCallControlPointOptionalOpcodesCharacteristic = new GattCharacteristic( - UUID_CALL_CONTROL_POINT_OPTIONAL_OPCODES, BluetoothGattCharacteristic.PROPERTY_READ, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); - mTerminationReasonCharacteristic = new GattCharacteristic(UUID_TERMINATION_REASON, - BluetoothGattCharacteristic.PROPERTY_NOTIFY, 0); - mIncomingCallCharacteristic = new GattCharacteristic(UUID_INCOMING_CALL, - BluetoothGattCharacteristic.PROPERTY_READ - | BluetoothGattCharacteristic.PROPERTY_NOTIFY, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); - mCallFriendlyNameCharacteristic = new GattCharacteristic(UUID_CALL_FRIENDLY_NAME, - BluetoothGattCharacteristic.PROPERTY_READ - | BluetoothGattCharacteristic.PROPERTY_NOTIFY, - BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mCallControlPointOptionalOpcodesCharacteristic = + new GattCharacteristic( + UUID_CALL_CONTROL_POINT_OPTIONAL_OPCODES, + BluetoothGattCharacteristic.PROPERTY_READ, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mTerminationReasonCharacteristic = + new GattCharacteristic( + UUID_TERMINATION_REASON, BluetoothGattCharacteristic.PROPERTY_NOTIFY, 0); + mIncomingCallCharacteristic = + new GattCharacteristic( + UUID_INCOMING_CALL, + BluetoothGattCharacteristic.PROPERTY_READ + | BluetoothGattCharacteristic.PROPERTY_NOTIFY, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); + mCallFriendlyNameCharacteristic = + new GattCharacteristic( + UUID_CALL_FRIENDLY_NAME, + BluetoothGattCharacteristic.PROPERTY_READ + | BluetoothGattCharacteristic.PROPERTY_NOTIFY, + BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED); mTbsService = tbsService; mBluetoothGattServer = null; @@ -317,9 +328,15 @@ public class TbsGatt { mBluetoothGattServer = proxy; } - public boolean init(int ccid, String uci, List uriSchemes, - boolean isLocalHoldOpcodeSupported, boolean isJoinOpcodeSupported, String providerName, - int technology, Callback callback) { + public boolean init( + int ccid, + String uci, + List uriSchemes, + boolean isLocalHoldOpcodeSupported, + boolean isJoinOpcodeSupported, + String providerName, + int technology, + Callback callback) { mCccDescriptorValues = new HashMap<>(); mBearerProviderNameCharacteristic.setValue(providerName); mBearerTechnologyCharacteristic.setValue(new byte[] {(byte) (technology & 0xFF)}); @@ -356,8 +373,9 @@ public class TbsGatt { gattService.addCharacteristic(mIncomingCallCharacteristic); gattService.addCharacteristic(mCallFriendlyNameCharacteristic); - mEventLogger = new BluetoothEventLogger(LOG_NB_EVENTS, - TAG + " instance (CCID= " + ccid + ") event log"); + mEventLogger = + new BluetoothEventLogger( + LOG_NB_EVENTS, TAG + " instance (CCID= " + ccid + ") event log"); mEventLogger.add("Initializing"); return mBluetoothGattServer.addService(gattService); @@ -387,16 +405,18 @@ public class TbsGatt { uuidList = new ArrayList<>(Arrays.asList(Utils.byteArrayToUuid(gtbs_cccd))); if (!uuidList.contains(charUuid)) { - Log.d(TAG, "Characteristic CCCD can't be removed (not cached): " - + charUuid.toString()); + Log.d( + TAG, + "Characteristic CCCD can't be removed (not cached): " + + charUuid.toString()); return; } } uuidList.remove(charUuid); - if (!device.setMetadata(METADATA_GTBS_CCCD, - Utils.uuidsToByteArray(uuidList.toArray(new ParcelUuid[0])))) { + if (!device.setMetadata( + METADATA_GTBS_CCCD, Utils.uuidsToByteArray(uuidList.toArray(new ParcelUuid[0])))) { Log.e(TAG, "Can't set CCCD for GTBS characteristic UUID: " + charUuid + ", (remove)"); } } @@ -418,8 +438,8 @@ public class TbsGatt { uuidList.add(charUuid); - if (!device.setMetadata(METADATA_GTBS_CCCD, - Utils.uuidsToByteArray(uuidList.toArray(new ParcelUuid[0])))) { + if (!device.setMetadata( + METADATA_GTBS_CCCD, Utils.uuidsToByteArray(uuidList.toArray(new ParcelUuid[0])))) { Log.e(TAG, "Can't set CCCD for GTBS characteristic UUID: " + charUuid + ", (add)"); } } @@ -432,11 +452,17 @@ public class TbsGatt { mCccDescriptorValues.put(device, characteristicCcc); } - characteristicCcc.put(charUuid, - ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN).getShort()); + characteristicCcc.put( + charUuid, ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN).getShort()); - Log.d(TAG, "setCcc, device: " + device.getAddress() + ", UUID: " + charUuid + ", value: " - + characteristicCcc.get(charUuid)); + Log.d( + TAG, + "setCcc, device: " + + device.getAddress() + + ", UUID: " + + charUuid + + ", value: " + + characteristicCcc.get(charUuid)); } private byte[] getCccBytes(BluetoothDevice device, UUID charUuid) { @@ -455,8 +481,8 @@ public class TbsGatt { /** Class that handles GATT characteristic notifications */ private class BluetoothGattCharacteristicNotifier { - public int setSubscriptionConfiguration(BluetoothDevice device, UUID uuid, - byte[] configuration) { + public int setSubscriptionConfiguration( + BluetoothDevice device, UUID uuid, byte[] configuration) { setCcc(device, uuid, configuration); return BluetoothGatt.GATT_SUCCESS; @@ -467,22 +493,22 @@ public class TbsGatt { } public boolean isSubscribed(BluetoothDevice device, UUID uuid) { - return Arrays.equals(getCccBytes(device, uuid), - BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + return Arrays.equals( + getCccBytes(device, uuid), BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } - private void notifyCharacteristicChanged(BluetoothDevice device, - BluetoothGattCharacteristic characteristic, byte[] value) { + private void notifyCharacteristicChanged( + BluetoothDevice device, BluetoothGattCharacteristic characteristic, byte[] value) { if (getDeviceAuthorization(device) != BluetoothDevice.ACCESS_ALLOWED) return; if (value == null) return; if (mBluetoothGattServer != null) { - mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false, - value); + mBluetoothGattServer.notifyCharacteristicChanged( + device, characteristic, false, value); } } - private void notifyCharacteristicChanged(BluetoothDevice device, - BluetoothGattCharacteristic characteristic) { + private void notifyCharacteristicChanged( + BluetoothDevice device, BluetoothGattCharacteristic characteristic) { if (getDeviceAuthorization(device) != BluetoothDevice.ACCESS_ALLOWED) return; if (mBluetoothGattServer != null) { @@ -490,8 +516,8 @@ public class TbsGatt { } } - public void notifyWithValue(BluetoothDevice device, - BluetoothGattCharacteristic characteristic, byte[] value) { + public void notifyWithValue( + BluetoothDevice device, BluetoothGattCharacteristic characteristic, byte[] value) { if (isSubscribed(device, characteristic.getUuid())) { notifyCharacteristicChanged(device, characteristic, value); } @@ -529,8 +555,8 @@ public class TbsGatt { return mNotifier.getSubscriptionConfiguration(device, uuid); } - public int setSubscriptionConfiguration(BluetoothDevice device, UUID uuid, - byte[] configuration) { + public int setSubscriptionConfiguration( + BluetoothDevice device, UUID uuid, byte[] configuration) { return mNotifier.setSubscriptionConfiguration(device, uuid, configuration); } @@ -595,11 +621,11 @@ public class TbsGatt { return success; } - public void handleWriteRequest(BluetoothDevice device, int requestId, - boolean responseNeeded, byte[] value) { + public void handleWriteRequest( + BluetoothDevice device, int requestId, boolean responseNeeded, byte[] value) { if (responseNeeded) { - mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, - value); + mBluetoothGattServer.sendResponse( + device, requestId, BluetoothGatt.GATT_FAILURE, 0, value); } } } @@ -607,14 +633,15 @@ public class TbsGatt { private class CallControlPointCharacteristic extends GattCharacteristic { public CallControlPointCharacteristic() { - super(UUID_CALL_CONTROL_POINT, + super( + UUID_CALL_CONTROL_POINT, PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY, PERMISSION_WRITE_ENCRYPTED); } @Override - public void handleWriteRequest(BluetoothDevice device, int requestId, - boolean responseNeeded, byte[] value) { + public void handleWriteRequest( + BluetoothDevice device, int requestId, boolean responseNeeded, byte[] value) { int status; if (value.length < 2) { // at least opcode is required and value is at least 1 byte @@ -632,12 +659,12 @@ public class TbsGatt { } int opcode = (int) value[0]; - mCallback.onCallControlPointRequest(device, opcode, - Arrays.copyOfRange(value, 1, value.length)); + mCallback.onCallControlPointRequest( + device, opcode, Arrays.copyOfRange(value, 1, value.length)); } - public void setResult(BluetoothDevice device, int requestedOpcode, int callIndex, - int requestResult) { + public void setResult( + BluetoothDevice device, int requestedOpcode, int callIndex, int requestResult) { byte[] value = new byte[3]; value[0] = (byte) (requestedOpcode); value[1] = (byte) (callIndex); @@ -653,14 +680,15 @@ public class TbsGatt { private class ClientCharacteristicConfigurationDescriptor extends BluetoothGattDescriptor { ClientCharacteristicConfigurationDescriptor() { - super(UUID_CLIENT_CHARACTERISTIC_CONFIGURATION, + super( + UUID_CLIENT_CHARACTERISTIC_CONFIGURATION, PERMISSION_WRITE_ENCRYPTED | PERMISSION_READ_ENCRYPTED); } public byte[] getValue(BluetoothDevice device) { GattCharacteristic characteristic = (GattCharacteristic) getCharacteristic(); - byte[] value = characteristic.getSubscriptionConfiguration(device, - characteristic.getUuid()); + byte[] value = + characteristic.getSubscriptionConfiguration(device, characteristic.getUuid()); if (value == null) { return BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE; } @@ -676,12 +704,16 @@ public class TbsGatt { return BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH; } else if ((!Arrays.equals(value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) - && !Arrays.equals(value, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE) - && !Arrays.equals(value, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) - || ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0 && Arrays - .equals(value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) - || ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == 0 && Arrays - .equals(value, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE))) { + && !Arrays.equals( + value, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE) + && !Arrays.equals( + value, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) + || ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0 + && Arrays.equals( + value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) + || ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == 0 + && Arrays.equals( + value, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE))) { return BluetoothGatt.GATT_FAILURE; } @@ -693,8 +725,8 @@ public class TbsGatt { Log.e(TAG, "Not handled CCC value: " + Arrays.toString(value)); } - return characteristic.setSubscriptionConfiguration(device, characteristic.getUuid(), - value); + return characteristic.setSubscriptionConfiguration( + device, characteristic.getUuid(), value); } } @@ -703,13 +735,13 @@ public class TbsGatt { } public boolean setBearerTechnology(int technology) { - return mBearerTechnologyCharacteristic.setValue(technology, - BluetoothGattCharacteristic.FORMAT_UINT8, 0); + return mBearerTechnologyCharacteristic.setValue( + technology, BluetoothGattCharacteristic.FORMAT_UINT8, 0); } public boolean setBearerUriSchemesSupportedList(List bearerUriSchemesSupportedList) { - return mBearerUriSchemesSupportedListCharacteristic - .setValue(String.join(",", bearerUriSchemesSupportedList)); + return mBearerUriSchemesSupportedListCharacteristic.setValue( + String.join(",", bearerUriSchemesSupportedList)); } public boolean setCallState(Map callsList) { @@ -740,7 +772,7 @@ public class TbsGatt { int uri_len = 0; if (call.getUri() != null) { - uri_len = call.getUri().getBytes().length; + uri_len = call.getUri().getBytes().length; } int listItemLength = Math.min(listItemLengthMax, 3 + uri_len); @@ -767,8 +799,8 @@ public class TbsGatt { private boolean updateStatusFlagsInbandRingtone(BluetoothDevice device, boolean set) { boolean entryExist = mStatusFlagValue.containsKey(device); if (entryExist - && (((mStatusFlagValue.get(device) - & STATUS_FLAG_INBAND_RINGTONE_ENABLED) != 0) == set)) { + && (((mStatusFlagValue.get(device) & STATUS_FLAG_INBAND_RINGTONE_ENABLED) != 0) + == set)) { Log.i(TAG, "Silent mode already set for " + device); return false; } @@ -786,11 +818,11 @@ public class TbsGatt { private boolean updateStatusFlagsSilentMode(boolean set) { mSilentMode = set; - for (BluetoothDevice device: mCccDescriptorValues.keySet()) { + for (BluetoothDevice device : mCccDescriptorValues.keySet()) { boolean entryExist = mStatusFlagValue.containsKey(device); if (entryExist - && (((mStatusFlagValue.get(device) - & STATUS_FLAG_SILENT_MODE_ENABLED) != 0) == set)) { + && (((mStatusFlagValue.get(device) & STATUS_FLAG_SILENT_MODE_ENABLED) != 0) + == set)) { Log.i(TAG, "Silent mode already set for " + device); continue; } @@ -809,26 +841,25 @@ public class TbsGatt { } /** - * Set inband ringtone for the device. - * When set, notification will be sent to given device. + * Set inband ringtone for the device. When set, notification will be sent to given device. * - * @param device device for which inband ringtone has been set - * @return true, when notification has been sent, false otherwise + * @param device device for which inband ringtone has been set + * @return true, when notification has been sent, false otherwise */ public boolean setInbandRingtoneFlag(BluetoothDevice device) { return updateStatusFlagsInbandRingtone(device, true); } /** - * Clear inband ringtone for the device. - * When set, notification will be sent to given device. + * Clear inband ringtone for the device. When set, notification will be sent to given device. * - * @param device device for which inband ringtone has been cleared - * @return true, when notification has been sent, false otherwise + * @param device device for which inband ringtone has been cleared + * @return true, when notification has been sent, false otherwise */ public boolean clearInbandRingtoneFlag(BluetoothDevice device) { return updateStatusFlagsInbandRingtone(device, false); } + public boolean setSilentModeFlag() { return updateStatusFlagsSilentMode(true); } @@ -837,8 +868,8 @@ public class TbsGatt { return updateStatusFlagsSilentMode(false); } - private void setCallControlPointOptionalOpcodes(boolean isLocalHoldOpcodeSupported, - boolean isJoinOpcodeSupported) { + private void setCallControlPointOptionalOpcodes( + boolean isLocalHoldOpcodeSupported, boolean isJoinOpcodeSupported) { int valueInt = 0; if (isLocalHoldOpcodeSupported) { valueInt |= CALL_CONTROL_POINT_OPTIONAL_OPCODE_LOCAL_HOLD; @@ -855,8 +886,12 @@ public class TbsGatt { } public boolean setTerminationReason(int callIndex, int terminationReason) { - Log.d(TAG, "setTerminationReason: callIndex=" + callIndex + " terminationReason=" - + terminationReason); + Log.d( + TAG, + "setTerminationReason: callIndex=" + + callIndex + + " terminationReason=" + + terminationReason); byte[] value = new byte[2]; value[0] = (byte) (callIndex & 0xff); value[1] = (byte) (terminationReason & 0xff); @@ -896,8 +931,12 @@ public class TbsGatt { } public boolean setCallFriendlyName(int callIndex, String callFriendlyName) { - Log.d(TAG, "setCallFriendlyName: callIndex=" + callIndex + "callFriendlyName=" - + callFriendlyName); + Log.d( + TAG, + "setCallFriendlyName: callIndex=" + + callIndex + + "callFriendlyName=" + + callFriendlyName); byte[] value = new byte[callFriendlyName.length() + 1]; value[0] = (byte) (callIndex & 0xff); System.arraycopy(callFriendlyName.getBytes(), 0, value, 1, callFriendlyName.length()); @@ -919,14 +958,20 @@ public class TbsGatt { return mCallFriendlyNameCharacteristic.clearValue(false); } - public void setCallControlPointResult(BluetoothDevice device, int requestedOpcode, - int callIndex, int requestResult) { - Log.d(TAG, - "setCallControlPointResult: device=" + device + " requestedOpcode=" - + requestedOpcode + " callIndex=" + callIndex + " requesuResult=" + public void setCallControlPointResult( + BluetoothDevice device, int requestedOpcode, int callIndex, int requestResult) { + Log.d( + TAG, + "setCallControlPointResult: device=" + + device + + " requestedOpcode=" + + requestedOpcode + + " callIndex=" + + callIndex + + " requesuResult=" + requestResult); - mCallControlPointCharacteristic.setResult(device, requestedOpcode, callIndex, - requestResult); + mCallControlPointCharacteristic.setResult( + device, requestedOpcode, callIndex, requestResult); } private static UUID makeUuid(String uuid16) { @@ -984,35 +1029,58 @@ public class TbsGatt { } private void onRejectedAuthorizationGattOperation(BluetoothDevice device, GattOpContext op) { - UUID charUuid = (op.mCharacteristic != null ? op.mCharacteristic.getUuid() - : (op.mDescriptor != null ? op.mDescriptor.getCharacteristic().getUuid() : null)); - mEventLogger.logw(TAG, "onRejectedAuthorizationGattOperation device: " + device - + ", opcode= " + op.mOperation + UUID charUuid = + (op.mCharacteristic != null + ? op.mCharacteristic.getUuid() + : (op.mDescriptor != null + ? op.mDescriptor.getCharacteristic().getUuid() + : null)); + mEventLogger.logw( + TAG, + "onRejectedAuthorizationGattOperation device: " + + device + + ", opcode= " + + op.mOperation + ", characteristic= " + (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN")); switch (op.mOperation) { case READ_CHARACTERISTIC: case READ_DESCRIPTOR: - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, + op.mOffset, + null); break; case WRITE_CHARACTERISTIC: if (op.mResponseNeeded) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, + op.mOffset, + null); } else { // In case of control point operations we can send an application error code if (op.mCharacteristic.getUuid().equals(UUID_CALL_CONTROL_POINT)) { - setCallControlPointResult(device, op.mOperation.ordinal(), 0, + setCallControlPointResult( + device, + op.mOperation.ordinal(), + 0, TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE); } } break; case WRITE_DESCRIPTOR: if (op.mResponseNeeded) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, - BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, op.mOffset, null); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION, + op.mOffset, + null); } break; @@ -1095,8 +1163,8 @@ public class TbsGatt { mBluetoothGattServer.sendResponse( device, op.mRequestId, BluetoothGatt.GATT_SUCCESS, op.mOffset, buffer); } else { - mEventLogger.loge(TAG, "Missing characteristic value for char: " - + tbsUuidToString(charUuid)); + mEventLogger.loge( + TAG, "Missing characteristic value for char: " + tbsUuidToString(charUuid)); mBluetoothGattServer.sendResponse( device, op.mRequestId, @@ -1107,17 +1175,25 @@ public class TbsGatt { } private void onUnauthorizedGattOperation(BluetoothDevice device, GattOpContext op) { - UUID charUuid = (op.mCharacteristic != null ? op.mCharacteristic.getUuid() - : (op.mDescriptor != null ? op.mDescriptor.getCharacteristic().getUuid() : null)); - mEventLogger.logw(TAG, "onUnauthorizedGattOperation device: " + device - + ", opcode= " + op.mOperation + UUID charUuid = + (op.mCharacteristic != null + ? op.mCharacteristic.getUuid() + : (op.mDescriptor != null + ? op.mDescriptor.getCharacteristic().getUuid() + : null)); + mEventLogger.logw( + TAG, + "onUnauthorizedGattOperation device: " + + device + + ", opcode= " + + op.mOperation + ", characteristic= " + (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN")); int status = BluetoothGatt.GATT_SUCCESS; switch (op.mOperation) { - /* Allow not yet authorized devices to subscribe for notifications */ + /* Allow not yet authorized devices to subscribe for notifications */ case READ_DESCRIPTOR: byte[] value = getCccBytes(device, op.mDescriptor.getCharacteristic().getUuid()); if (value.length < op.mOffset) { @@ -1176,10 +1252,18 @@ public class TbsGatt { ClientCharacteristicConfigurationDescriptor cccd; byte[] value; - UUID charUuid = (op.mCharacteristic != null ? op.mCharacteristic.getUuid() - : (op.mDescriptor != null ? op.mDescriptor.getCharacteristic().getUuid() : null)); - mEventLogger.logd(TAG, "onAuthorizedGattOperation device: " + device - + ", opcode= " + op.mOperation + UUID charUuid = + (op.mCharacteristic != null + ? op.mCharacteristic.getUuid() + : (op.mDescriptor != null + ? op.mDescriptor.getCharacteristic().getUuid() + : null)); + mEventLogger.logd( + TAG, + "onAuthorizedGattOperation device: " + + device + + ", opcode= " + + op.mOperation + ", characteristic= " + (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN")); @@ -1234,14 +1318,14 @@ public class TbsGatt { } else if (op.mOffset > 0) { status = BluetoothGatt.GATT_INVALID_OFFSET; } else { - gattCharacteristic.handleWriteRequest(device, op.mRequestId, op.mResponseNeeded, - op.mValue); + gattCharacteristic.handleWriteRequest( + device, op.mRequestId, op.mResponseNeeded, op.mValue); return; } if (op.mResponseNeeded) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, status, op.mOffset, - op.mValue); + mBluetoothGattServer.sendResponse( + device, op.mRequestId, status, op.mOffset, op.mValue); } break; @@ -1286,8 +1370,8 @@ public class TbsGatt { } if (op.mResponseNeeded) { - mBluetoothGattServer.sendResponse(device, op.mRequestId, status, op.mOffset, - op.mValue); + mBluetoothGattServer.sendResponse( + device, op.mRequestId, status, op.mOffset, op.mValue); } break; @@ -1335,9 +1419,16 @@ public class TbsGatt { */ public void onDeviceAuthorizationSet(BluetoothDevice device) { int auth = getDeviceAuthorization(device); - mEventLogger.logd(TAG, "onDeviceAuthorizationSet: device= " + device - + ", authorization= " + (auth == BluetoothDevice.ACCESS_ALLOWED ? "ALLOWED" - : (auth == BluetoothDevice.ACCESS_REJECTED ? "REJECTED" : "UNKNOWN"))); + mEventLogger.logd( + TAG, + "onDeviceAuthorizationSet: device= " + + device + + ", authorization= " + + (auth == BluetoothDevice.ACCESS_ALLOWED + ? "ALLOWED" + : (auth == BluetoothDevice.ACCESS_REJECTED + ? "REJECTED" + : "UNKNOWN"))); processPendingGattOperations(device); if (auth != BluetoothDevice.ACCESS_ALLOWED) { @@ -1398,158 +1489,233 @@ public class TbsGatt { * characteristics and descriptors are handled here. */ @VisibleForTesting - final BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() { - @Override - public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { - super.onConnectionStateChange(device, status, newState); - Log.d(TAG, "BluetoothGattServerCallback: onConnectionStateChange"); - if (newState == BluetoothProfile.STATE_DISCONNECTED) { - clearUnauthorizedGattOperationss(device); - } - } - - @Override - public void onServiceAdded(int status, BluetoothGattService service) { - Log.d(TAG, "onServiceAdded: status=" + status); - if (mCallback != null) { - mCallback.onServiceAdded(status == BluetoothGatt.GATT_SUCCESS); - } + final BluetoothGattServerCallback mGattServerCallback = + new BluetoothGattServerCallback() { + @Override + public void onConnectionStateChange( + BluetoothDevice device, int status, int newState) { + super.onConnectionStateChange(device, status, newState); + Log.d(TAG, "BluetoothGattServerCallback: onConnectionStateChange"); + if (newState == BluetoothProfile.STATE_DISCONNECTED) { + clearUnauthorizedGattOperationss(device); + } + } - restoreCccValuesForStoredDevices(); - } + @Override + public void onServiceAdded(int status, BluetoothGattService service) { + Log.d(TAG, "onServiceAdded: status=" + status); + if (mCallback != null) { + mCallback.onServiceAdded(status == BluetoothGatt.GATT_SUCCESS); + } - @Override - public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattCharacteristic characteristic) { - super.onCharacteristicReadRequest(device, requestId, offset, characteristic); - Log.d(TAG, "BluetoothGattServerCallback: onCharacteristicReadRequest offset= " - + offset + " entire value= " + Arrays.toString(characteristic.getValue())); - - if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) == 0) { - mBluetoothGattServer.sendResponse(device, requestId, - BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, offset, null); - return; - } + restoreCccValuesForStoredDevices(); + } - GattOpContext op = new GattOpContext( - GattOpContext.Operation.READ_CHARACTERISTIC, requestId, characteristic, null); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } + @Override + public void onCharacteristicReadRequest( + BluetoothDevice device, + int requestId, + int offset, + BluetoothGattCharacteristic characteristic) { + super.onCharacteristicReadRequest(device, requestId, offset, characteristic); + Log.d( + TAG, + "BluetoothGattServerCallback: onCharacteristicReadRequest offset= " + + offset + + " entire value= " + + Arrays.toString(characteristic.getValue())); + + if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) + == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, + offset, + null); + return; + } - @Override - public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattCharacteristic characteristic, boolean preparedWrite, - boolean responseNeeded, int offset, byte[] value) { - super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, - responseNeeded, offset, value); - Log.d(TAG, - "BluetoothGattServerCallback: " - + "onCharacteristicWriteRequest"); - - if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) - == 0) { - mBluetoothGattServer.sendResponse( - device, requestId, BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, offset, value); - return; - } + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.READ_CHARACTERISTIC, + requestId, + characteristic, + null); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } - GattOpContext op = new GattOpContext(GattOpContext.Operation.WRITE_CHARACTERISTIC, - requestId, characteristic, null, preparedWrite, responseNeeded, offset, value); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } + @Override + public void onCharacteristicWriteRequest( + BluetoothDevice device, + int requestId, + BluetoothGattCharacteristic characteristic, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value) { + super.onCharacteristicWriteRequest( + device, + requestId, + characteristic, + preparedWrite, + responseNeeded, + offset, + value); + Log.d(TAG, "BluetoothGattServerCallback: " + "onCharacteristicWriteRequest"); + + if ((characteristic.getProperties() + & BluetoothGattCharacteristic.PROPERTY_WRITE) + == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, + offset, + value); + return; + } - @Override - public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattDescriptor descriptor) { - super.onDescriptorReadRequest(device, requestId, offset, descriptor); - Log.d(TAG, - "BluetoothGattServerCallback: " - + "onDescriptorReadRequest"); + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.WRITE_CHARACTERISTIC, + requestId, + characteristic, + null, + preparedWrite, + responseNeeded, + offset, + value); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } - if ((descriptor.getPermissions() & BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED) - == 0) { - mBluetoothGattServer.sendResponse( - device, requestId, BluetoothGatt.GATT_READ_NOT_PERMITTED, offset, null); - return; - } + @Override + public void onDescriptorReadRequest( + BluetoothDevice device, + int requestId, + int offset, + BluetoothGattDescriptor descriptor) { + super.onDescriptorReadRequest(device, requestId, offset, descriptor); + Log.d(TAG, "BluetoothGattServerCallback: " + "onDescriptorReadRequest"); + + if ((descriptor.getPermissions() + & BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED) + == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_READ_NOT_PERMITTED, + offset, + null); + return; + } - GattOpContext op = new GattOpContext( - GattOpContext.Operation.READ_DESCRIPTOR, requestId, null, descriptor); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.READ_DESCRIPTOR, + requestId, + null, + descriptor); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } - @Override - public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, - int offset, byte[] value) { - super.onDescriptorWriteRequest( - device, requestId, descriptor, preparedWrite, responseNeeded, offset, value); - Log.d(TAG, - "BluetoothGattServerCallback: " - + "onDescriptorWriteRequest"); - - if ((descriptor.getPermissions() & BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED) - == 0) { - mBluetoothGattServer.sendResponse( - device, requestId, BluetoothGatt.GATT_WRITE_NOT_PERMITTED, offset, value); - return; - } + @Override + public void onDescriptorWriteRequest( + BluetoothDevice device, + int requestId, + BluetoothGattDescriptor descriptor, + boolean preparedWrite, + boolean responseNeeded, + int offset, + byte[] value) { + super.onDescriptorWriteRequest( + device, + requestId, + descriptor, + preparedWrite, + responseNeeded, + offset, + value); + Log.d(TAG, "BluetoothGattServerCallback: " + "onDescriptorWriteRequest"); + + if ((descriptor.getPermissions() + & BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED) + == 0) { + mBluetoothGattServer.sendResponse( + device, + requestId, + BluetoothGatt.GATT_WRITE_NOT_PERMITTED, + offset, + value); + return; + } - GattOpContext op = new GattOpContext(GattOpContext.Operation.WRITE_DESCRIPTOR, - requestId, null, descriptor, preparedWrite, responseNeeded, offset, value); - switch (getDeviceAuthorization(device)) { - case BluetoothDevice.ACCESS_REJECTED: - onRejectedAuthorizationGattOperation(device, op); - break; - case BluetoothDevice.ACCESS_UNKNOWN: - onUnauthorizedGattOperation(device, op); - break; - default: - onAuthorizedGattOperation(device, op); - break; - } - } - }; + GattOpContext op = + new GattOpContext( + GattOpContext.Operation.WRITE_DESCRIPTOR, + requestId, + null, + descriptor, + preparedWrite, + responseNeeded, + offset, + value); + switch (getDeviceAuthorization(device)) { + case BluetoothDevice.ACCESS_REJECTED: + onRejectedAuthorizationGattOperation(device, op); + break; + case BluetoothDevice.ACCESS_UNKNOWN: + onUnauthorizedGattOperation(device, op); + break; + default: + onAuthorizedGattOperation(device, op); + break; + } + } + }; public void dump(StringBuilder sb) { sb.append("\n\tSilent mode: " + mSilentMode); - for (Map.Entry> deviceEntry - : mCccDescriptorValues.entrySet()) { + for (Map.Entry> deviceEntry : + mCccDescriptorValues.entrySet()) { sb.append("\n\tCCC states for device: " + deviceEntry.getKey()); for (Map.Entry entry : deviceEntry.getValue().entrySet()) { - sb.append("\n\t\tCharacteristic: " + tbsUuidToString(entry.getKey()) + ", value: " - + Utils.cccIntToStr(entry.getValue())); + sb.append( + "\n\t\tCharacteristic: " + + tbsUuidToString(entry.getKey()) + + ", value: " + + Utils.cccIntToStr(entry.getValue())); } } diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java b/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java index 3c116fdb7fa..bb24ac247ba 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java @@ -75,7 +75,10 @@ public class TbsGeneric { this.callIndex = callIndex; } - public Request(BluetoothDevice device, List callIds, int requestedOpcode, + public Request( + BluetoothDevice device, + List callIds, + int requestedOpcode, int callIndex) { this.device = device; this.callIdList = new ArrayList<>(); @@ -155,22 +158,32 @@ public class TbsGeneric { } } } - }; + } + ; public synchronized boolean init(TbsGatt tbsGatt) { Log.d(TAG, "init"); mTbsGatt = tbsGatt; - int ccid = ContentControlIdKeeper.acquireCcid(new ParcelUuid(TbsGatt.UUID_GTBS), - BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL); + int ccid = + ContentControlIdKeeper.acquireCcid( + new ParcelUuid(TbsGatt.UUID_GTBS), + BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL); if (!isCcidValid(ccid)) { Log.e(TAG, " CCID is not valid"); cleanup(); return false; } - if (!mTbsGatt.init(ccid, UCI, mUriSchemes, true, true, DEFAULT_PROVIDER_NAME, - DEFAULT_BEARER_TECHNOLOGY, mTbsGattCallback)) { + if (!mTbsGatt.init( + ccid, + UCI, + mUriSchemes, + true, + true, + DEFAULT_PROVIDER_NAME, + DEFAULT_BEARER_TECHNOLOGY, + mTbsGattCallback)) { Log.e(TAG, " TbsGatt init failed"); cleanup(); return false; @@ -228,10 +241,9 @@ public class TbsGeneric { } /** - * Set inband ringtone for the device. - * When set, notification will be sent to given device. + * Set inband ringtone for the device. When set, notification will be sent to given device. * - * @param device device for which inband ringtone has been set + * @param device device for which inband ringtone has been set */ public synchronized void setInbandRingtoneSupport(BluetoothDevice device) { if (mTbsGatt == null) { @@ -242,10 +254,9 @@ public class TbsGeneric { } /** - * Clear inband ringtone for the device. - * When set, notification will be sent to given device. + * Clear inband ringtone for the device. When set, notification will be sent to given device. * - * @param device device for which inband ringtone has been cleared + * @param device device for which inband ringtone has been cleared */ public synchronized void clearInbandRingtoneSupport(BluetoothDevice device) { if (mTbsGatt == null) { @@ -299,13 +310,28 @@ public class TbsGeneric { return null; } - public synchronized boolean addBearer(String token, IBluetoothLeCallControlCallback callback, - String uci, List uriSchemes, int capabilities, String providerName, + public synchronized boolean addBearer( + String token, + IBluetoothLeCallControlCallback callback, + String uci, + List uriSchemes, + int capabilities, + String providerName, int technology) { - Log.d(TAG, - "addBearer: token=" + token + " uci=" + uci + " uriSchemes=" + uriSchemes - + " capabilities=" + capabilities + " providerName=" + providerName - + " technology=" + technology); + Log.d( + TAG, + "addBearer: token=" + + token + + " uci=" + + uci + + " uriSchemes=" + + uriSchemes + + " capabilities=" + + capabilities + + " providerName=" + + providerName + + " technology=" + + technology); if (!mIsInitialized) { Log.w(TAG, "addBearer called while not initialized."); return false; @@ -457,11 +483,10 @@ public class TbsGeneric { } } else { result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; - } - mTbsGatt.setCallControlPointResult(request.device, request.requestedOpcode, - request.callIndex, result); + mTbsGatt.setCallControlPointResult( + request.device, request.requestedOpcode, request.callIndex, result); bearer.requestMap.remove(requestId); } @@ -480,8 +505,7 @@ public class TbsGeneric { } public synchronized void requestResult(int ccid, int requestId, int result) { - Log.d(TAG, "requestResult: ccid=" + ccid + " requestId=" + requestId + " result=" - + result); + Log.d(TAG, "requestResult: ccid=" + ccid + " requestId=" + requestId + " result=" + result); if (!mIsInitialized) { Log.w(TAG, "requestResult called while not initialized."); @@ -507,8 +531,8 @@ public class TbsGeneric { } int tbsResult = getTbsResult(result, request.requestedOpcode); - mTbsGatt.setCallControlPointResult(request.device, request.requestedOpcode, - request.callIndex, tbsResult); + mTbsGatt.setCallControlPointResult( + request.device, request.requestedOpcode, request.callIndex, tbsResult); } public synchronized void callAdded(int ccid, BluetoothLeCall call) { @@ -693,8 +717,14 @@ public class TbsGeneric { } public synchronized void networkStateChanged(int ccid, String providerName, int technology) { - Log.d(TAG, "networkStateChanged: ccid=" + ccid + " providerName=" + providerName - + " technology=" + technology); + Log.d( + TAG, + "networkStateChanged: ccid=" + + ccid + + " providerName=" + + providerName + + " technology=" + + technology); if (!mIsInitialized) { Log.w(TAG, "networkStateChanged called while not initialized."); @@ -738,13 +768,20 @@ public class TbsGeneric { Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.parse(uri)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mTbsGatt.getContext().startActivity(intent); - mTbsGatt.setCallControlPointResult(device, TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE, - TbsCall.INDEX_UNASSIGNED, TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS); + mTbsGatt.setCallControlPointResult( + device, + TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE, + TbsCall.INDEX_UNASSIGNED, + TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS); } else { UUID callId = UUID.randomUUID(); int requestId = mLastRequestIdAssigned + 1; - Request request = new Request(device, callId, - TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE, TbsCall.INDEX_UNASSIGNED); + Request request = + new Request( + device, + callId, + TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE, + TbsCall.INDEX_UNASSIGNED); Bearer bearer = getBearerSupportingUri(uri); if (bearer == null) { @@ -766,174 +803,217 @@ public class TbsGeneric { return TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; } - private final TbsGatt.Callback mTbsGattCallback = new TbsGatt.Callback() { - - @Override - public void onServiceAdded(boolean success) { - synchronized (TbsGeneric.this) { - Log.d(TAG, "onServiceAdded: success=" + success); - } - } - - @Override - public boolean isInbandRingtoneEnabled(BluetoothDevice device) { - if (!isLeAudioServiceAvailable()) { - Log.i(TAG, "LeAudio service not available"); - return false; - } - int groupId = mLeAudioService.getGroupId(device); - return mLeAudioService.isInbandRingtoneEnabled(groupId); - } - - @Override - public void onCallControlPointRequest(BluetoothDevice device, int opcode, byte[] args) { - synchronized (TbsGeneric.this) { - Log.d(TAG, "onCallControlPointRequest: device=" + device + " opcode=" - + callControlRequestOpcodeStr(opcode) + "(" + opcode + ")" - + " argsLen=" + args.length); + private final TbsGatt.Callback mTbsGattCallback = + new TbsGatt.Callback() { - if (!mIsInitialized) { - Log.w(TAG, "onCallControlPointRequest called while not initialized."); - return; + @Override + public void onServiceAdded(boolean success) { + synchronized (TbsGeneric.this) { + Log.d(TAG, "onServiceAdded: success=" + success); + } } - int result; - - switch (opcode) { - case TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT: - case TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE: - case TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD: - case TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE: { - if (args.length == 0) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; - break; - } - - int callIndex = args[0]; - Map.Entry entry = getCallIdByIndex(callIndex); - if (entry == null) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_INVALID_CALL_INDEX; - break; - } + @Override + public boolean isInbandRingtoneEnabled(BluetoothDevice device) { + if (!isLeAudioServiceAvailable()) { + Log.i(TAG, "LeAudio service not available"); + return false; + } + int groupId = mLeAudioService.getGroupId(device); + return mLeAudioService.isInbandRingtoneEnabled(groupId); + } - TbsCall call = mCurrentCallsList.get(callIndex); - if (!isCallStateTransitionValid(call.getState(), opcode)) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_STATE_MISMATCH; - break; + @Override + public void onCallControlPointRequest( + BluetoothDevice device, int opcode, byte[] args) { + synchronized (TbsGeneric.this) { + Log.d( + TAG, + "onCallControlPointRequest: device=" + + device + + " opcode=" + + callControlRequestOpcodeStr(opcode) + + "(" + + opcode + + ")" + + " argsLen=" + + args.length); + + if (!mIsInitialized) { + Log.w(TAG, "onCallControlPointRequest called while not initialized."); + return; } - Bearer bearer = entry.getValue(); - UUID callId = entry.getKey(); - int requestId = mLastRequestIdAssigned + 1; - Request request = new Request(device, callId, opcode, callIndex); - try { - if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT) { - setActiveLeDevice(device); - bearer.callback.onAcceptCall(requestId, new ParcelUuid(callId)); - } else if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE) { - bearer.callback.onTerminateCall(requestId, new ParcelUuid(callId)); - } else if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD) { - if ((bearer.capabilities - & BluetoothLeCallControl.CAPABILITY_HOLD_CALL) == 0) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED; + int result; + + switch (opcode) { + case TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT: + case TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE: + case TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD: + case TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_RETRIEVE: + { + if (args.length == 0) { + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; + break; + } + + int callIndex = args[0]; + Map.Entry entry = getCallIdByIndex(callIndex); + if (entry == null) { + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_INVALID_CALL_INDEX; + break; + } + + TbsCall call = mCurrentCallsList.get(callIndex); + if (!isCallStateTransitionValid(call.getState(), opcode)) { + result = TbsGatt.CALL_CONTROL_POINT_RESULT_STATE_MISMATCH; + break; + } + + Bearer bearer = entry.getValue(); + UUID callId = entry.getKey(); + int requestId = mLastRequestIdAssigned + 1; + Request request = + new Request(device, callId, opcode, callIndex); + try { + if (opcode == TbsGatt.CALL_CONTROL_POINT_OPCODE_ACCEPT) { + setActiveLeDevice(device); + bearer.callback.onAcceptCall( + requestId, new ParcelUuid(callId)); + } else if (opcode + == TbsGatt.CALL_CONTROL_POINT_OPCODE_TERMINATE) { + bearer.callback.onTerminateCall( + requestId, new ParcelUuid(callId)); + } else if (opcode + == TbsGatt.CALL_CONTROL_POINT_OPCODE_LOCAL_HOLD) { + if ((bearer.capabilities + & BluetoothLeCallControl + .CAPABILITY_HOLD_CALL) + == 0) { + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED; + break; + } + bearer.callback.onHoldCall( + requestId, new ParcelUuid(callId)); + } else { + if ((bearer.capabilities + & BluetoothLeCallControl + .CAPABILITY_HOLD_CALL) + == 0) { + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED; + break; + } + bearer.callback.onUnholdCall( + requestId, new ParcelUuid(callId)); + } + } catch (RemoteException e) { + e.printStackTrace(); + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; + break; + } + + bearer.requestMap.put(requestId, request); + mLastRequestIdAssigned = requestId; + + result = TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; break; } - bearer.callback.onHoldCall(requestId, new ParcelUuid(callId)); - } else { - if ((bearer.capabilities - & BluetoothLeCallControl.CAPABILITY_HOLD_CALL) == 0) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED; + + case TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE: + { + result = processOriginateCall(device, new String(args)); break; } - bearer.callback.onUnholdCall(requestId, new ParcelUuid(callId)); - } - } catch (RemoteException e) { - e.printStackTrace(); - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; - break; - } - - bearer.requestMap.put(requestId, request); - mLastRequestIdAssigned = requestId; - - result = TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; - break; - } - - case TbsGatt.CALL_CONTROL_POINT_OPCODE_ORIGINATE: { - result = processOriginateCall(device, new String(args)); - break; - } - case TbsGatt.CALL_CONTROL_POINT_OPCODE_JOIN: { - // at least 2 call indices are required - if (args.length < 2) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; - break; - } - - Map.Entry firstEntry = null; - List parcelUuids = new ArrayList<>(); - result = TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; - for (int callIndex : args) { - Map.Entry entry = getCallIdByIndex(callIndex); - if (entry == null) { - result = TbsGatt.CALL_CONTROL_POINT_RESULT_INVALID_CALL_INDEX; - break; - } - - // state transition is valid, because a call in any state - // can requested to join - - if (firstEntry == null) { - firstEntry = entry; - } + case TbsGatt.CALL_CONTROL_POINT_OPCODE_JOIN: + { + // at least 2 call indices are required + if (args.length < 2) { + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; + break; + } + + Map.Entry firstEntry = null; + List parcelUuids = new ArrayList<>(); + result = TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; + for (int callIndex : args) { + Map.Entry entry = getCallIdByIndex(callIndex); + if (entry == null) { + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_INVALID_CALL_INDEX; + break; + } + + // state transition is valid, because a call in any state + // can requested to join + + if (firstEntry == null) { + firstEntry = entry; + } + + if (firstEntry.getValue() != entry.getValue()) { + Log.w(TAG, "Cannot join calls from different bearers!"); + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; + break; + } + + parcelUuids.add(new ParcelUuid(entry.getKey())); + } + + if (result != TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS) { + break; + } + + Bearer bearer = firstEntry.getValue(); + Request request = + new Request(device, parcelUuids, opcode, args[0]); + int requestId = mLastRequestIdAssigned + 1; + try { + bearer.callback.onJoinCalls(requestId, parcelUuids); + } catch (RemoteException e) { + e.printStackTrace(); + result = + TbsGatt + .CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; + break; + } + + bearer.requestMap.put(requestId, request); + mLastIndexAssigned = requestId; + + result = TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; + break; + } - if (firstEntry.getValue() != entry.getValue()) { - Log.w(TAG, "Cannot join calls from different bearers!"); - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; + default: + result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED; break; - } - - parcelUuids.add(new ParcelUuid(entry.getKey())); - } - - if (result != TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS) { - break; } - Bearer bearer = firstEntry.getValue(); - Request request = new Request(device, parcelUuids, opcode, args[0]); - int requestId = mLastRequestIdAssigned + 1; - try { - bearer.callback.onJoinCalls(requestId, parcelUuids); - } catch (RemoteException e) { - e.printStackTrace(); - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE; - break; + if (result == TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS) { + // return here and wait for the request completition from application + return; } - bearer.requestMap.put(requestId, request); - mLastIndexAssigned = requestId; - - result = TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS; - break; + mTbsGatt.setCallControlPointResult(device, opcode, 0, result); } - - default: - result = TbsGatt.CALL_CONTROL_POINT_RESULT_OPCODE_NOT_SUPPORTED; - break; } - - if (result == TbsGatt.CALL_CONTROL_POINT_RESULT_SUCCESS) { - // return here and wait for the request completition from application - return; - } - - mTbsGatt.setCallControlPointResult(device, opcode, 0, result); - } - } - }; + }; private String callControlRequestOpcodeStr(int opcode) { switch (opcode) { @@ -1170,7 +1250,7 @@ public class TbsGeneric { for (TbsCall call : mCurrentCallsList.values()) { sb.append("\n\t\tFriendly name: " + call.getSafeFriendlyName()); sb.append("\n\t\t\tState: " + TbsCall.stateToString(call.getState())); - sb.append("\n\t\t\tURI: " + call.getSafeUri()); + sb.append("\n\t\t\tURI: " + call.getSafeUri()); sb.append("\n\t\t\tFlags: " + TbsCall.flagsToString(call.getFlags())); } diff --git a/android/app/src/com/android/bluetooth/tbs/TbsService.java b/android/app/src/com/android/bluetooth/tbs/TbsService.java index 77dc1cafaf4..988c75bc6ef 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsService.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsService.java @@ -152,8 +152,8 @@ public class TbsService extends ProfileService { */ public void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { Log.i(TAG, "setDeviceAuthorized(): device: " + device + ", isAuthorized: " + isAuthorized); - int authorization = isAuthorized ? BluetoothDevice.ACCESS_ALLOWED - : BluetoothDevice.ACCESS_REJECTED; + int authorization = + isAuthorized ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; mDeviceAuthorizations.put(device, authorization); if (mTbsGeneric != null) { @@ -166,10 +166,8 @@ public class TbsService extends ProfileService { * * @param device device that would be authorized * @return authorization value for device - * - * Possible authorization values: - * {@link BluetoothDevice.ACCESS_UNKNOWN}, - * {@link BluetoothDevice.ACCESS_ALLOWED} + *

Possible authorization values: {@link BluetoothDevice.ACCESS_UNKNOWN}, {@link + * BluetoothDevice.ACCESS_ALLOWED} */ public int getDeviceAuthorization(BluetoothDevice device) { /* Telephony Bearer Service is allowed for @@ -177,8 +175,12 @@ public class TbsService extends ProfileService { * 2. authorized devices * 3. Any LeAudio devices which are allowed to connect */ - int authorization = mDeviceAuthorizations.getOrDefault(device, Utils.isPtsTestMode() - ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_UNKNOWN); + int authorization = + mDeviceAuthorizations.getOrDefault( + device, + Utils.isPtsTestMode() + ? BluetoothDevice.ACCESS_ALLOWED + : BluetoothDevice.ACCESS_UNKNOWN); if (authorization != BluetoothDevice.ACCESS_UNKNOWN) { return authorization; } @@ -201,10 +203,9 @@ public class TbsService extends ProfileService { } /** - * Set inband ringtone for the device. - * When set, notification will be sent to given device. + * Set inband ringtone for the device. When set, notification will be sent to given device. * - * @param device device for which inband ringtone has been set + * @param device device for which inband ringtone has been set */ public void setInbandRingtoneSupport(BluetoothDevice device) { if (mTbsGeneric == null) { @@ -215,10 +216,9 @@ public class TbsService extends ProfileService { } /** - * Clear inband ringtone for the device. - * When set, notification will be sent to given device. + * Clear inband ringtone for the device. When set, notification will be sent to given device. * - * @param device device for which inband ringtone has been clear + * @param device device for which inband ringtone has been clear */ public void clearInbandRingtoneSupport(BluetoothDevice device) { if (mTbsGeneric == null) { @@ -228,10 +228,10 @@ public class TbsService extends ProfileService { mTbsGeneric.clearInbandRingtoneSupport(device); } - /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting - static class TbsServerBinder extends IBluetoothLeCallControl.Stub implements IProfileServiceBinder { + static class TbsServerBinder extends IBluetoothLeCallControl.Stub + implements IProfileServiceBinder { private TbsService mService; private TbsService getService(AttributionSource source) { @@ -262,21 +262,26 @@ public class TbsService extends ProfileService { } @Override - public void registerBearer(String token, IBluetoothLeCallControlCallback callback, String uci, - List uriSchemes, int capabilities, String providerName, int technology, + public void registerBearer( + String token, + IBluetoothLeCallControlCallback callback, + String uci, + List uriSchemes, + int capabilities, + String providerName, + int technology, AttributionSource source) { TbsService service = getService(source); if (service != null) { - service.registerBearer(token, callback, uci, uriSchemes, capabilities, providerName, - technology); + service.registerBearer( + token, callback, uci, uriSchemes, capabilities, providerName, technology); } else { Log.w(TAG, "Service not active"); } } @Override - public void unregisterBearer(String token, - AttributionSource source) { + public void unregisterBearer(String token, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.unregisterBearer(token); @@ -286,8 +291,7 @@ public class TbsService extends ProfileService { } @Override - public void requestResult(int ccid, int requestId, int result, - AttributionSource source) { + public void requestResult(int ccid, int requestId, int result, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.requestResult(ccid, requestId, result); @@ -297,8 +301,7 @@ public class TbsService extends ProfileService { } @Override - public void callAdded(int ccid, BluetoothLeCall call, - AttributionSource source) { + public void callAdded(int ccid, BluetoothLeCall call, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.callAdded(ccid, call); @@ -308,8 +311,7 @@ public class TbsService extends ProfileService { } @Override - public void callRemoved(int ccid, ParcelUuid callId, int reason, - AttributionSource source) { + public void callRemoved(int ccid, ParcelUuid callId, int reason, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.callRemoved(ccid, callId.getUuid(), reason); @@ -319,8 +321,8 @@ public class TbsService extends ProfileService { } @Override - public void callStateChanged(int ccid, ParcelUuid callId, int state, - AttributionSource source) { + public void callStateChanged( + int ccid, ParcelUuid callId, int state, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.callStateChanged(ccid, callId.getUuid(), state); @@ -330,8 +332,8 @@ public class TbsService extends ProfileService { } @Override - public void currentCallsList(int ccid, List calls, - AttributionSource source) { + public void currentCallsList( + int ccid, List calls, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.currentCallsList(ccid, calls); @@ -341,8 +343,8 @@ public class TbsService extends ProfileService { } @Override - public void networkStateChanged(int ccid, String providerName, int technology, - AttributionSource source) { + public void networkStateChanged( + int ccid, String providerName, int technology, AttributionSource source) { TbsService service = getService(source); if (service != null) { service.networkStateChanged(ccid, providerName, technology); @@ -353,18 +355,28 @@ public class TbsService extends ProfileService { } @VisibleForTesting - void registerBearer(String token, IBluetoothLeCallControlCallback callback, String uci, - List uriSchemes, int capabilities, String providerName, int technology) { + void registerBearer( + String token, + IBluetoothLeCallControlCallback callback, + String uci, + List uriSchemes, + int capabilities, + String providerName, + int technology) { Log.d(TAG, "registerBearer: token=" + token); - boolean success = mTbsGeneric.addBearer(token, callback, uci, uriSchemes, capabilities, - providerName, technology); + boolean success = + mTbsGeneric.addBearer( + token, callback, uci, uriSchemes, capabilities, providerName, technology); if (success) { try { - callback.asBinder().linkToDeath(() -> { - Log.e(TAG, token + " application died, removing..."); - unregisterBearer(token); - }, 0); + callback.asBinder() + .linkToDeath( + () -> { + Log.e(TAG, token + " application died, removing..."); + unregisterBearer(token); + }, + 0); } catch (RemoteException e) { e.printStackTrace(); } @@ -382,8 +394,7 @@ public class TbsService extends ProfileService { @VisibleForTesting public void requestResult(int ccid, int requestId, int result) { - Log.d(TAG, "requestResult: ccid=" + ccid + " requestId=" + requestId + " result=" - + result); + Log.d(TAG, "requestResult: ccid=" + ccid + " requestId=" + requestId + " result=" + result); mTbsGeneric.requestResult(ccid, requestId, result); } @@ -418,8 +429,14 @@ public class TbsService extends ProfileService { @VisibleForTesting void networkStateChanged(int ccid, String providerName, int technology) { - Log.d(TAG, "networkStateChanged: ccid=" + ccid + " providerName=" + providerName - + " technology=" + technology); + Log.d( + TAG, + "networkStateChanged: ccid=" + + ccid + + " providerName=" + + providerName + + " technology=" + + technology); mTbsGeneric.networkStateChanged(ccid, providerName, technology); } diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothCall.java b/android/app/src/com/android/bluetooth/telephony/BluetoothCall.java index ae199b4b073..ba350df3c3a 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothCall.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothCall.java @@ -33,14 +33,13 @@ import java.util.List; import java.util.UUID; /** - * A proxy class of android.telecom.Call that - * 1) facilitates testing of the BluetoothInCallService class; We can't mock the final class - * Call directly; - * 2) Some helper functions, to let Call have same methods as com.android.server.telecom.Call + * A proxy class of android.telecom.Call that 1) facilitates testing of the BluetoothInCallService + * class; We can't mock the final class Call directly; 2) Some helper functions, to let Call have + * same methods as com.android.server.telecom.Call * - * This is necessary due to the "final" attribute of the Call class. In order to - * test the correct functioning of the BluetoothInCallService class, the final class must be put - * into a container that can be mocked correctly. + *

This is necessary due to the "final" attribute of the Call class. In order to test the correct + * functioning of the BluetoothInCallService class, the final class must be put into a container + * that can be mocked correctly. */ @VisibleForTesting public class BluetoothCall { @@ -183,9 +182,7 @@ public class BluetoothCall { mCall.removeExtras(keys); } - /** - * Returns the parent Call id. - */ + /** Returns the parent Call id. */ public Integer getParentId() { Call parent = mCall.getParent(); if (parent != null) { @@ -281,8 +278,8 @@ public class BluetoothCall { // helper functions public boolean isSilentRingingRequested() { - return BluetoothCallShimImpl.newInstance().isSilentRingingRequested( - getDetails().getExtras()); + return BluetoothCallShimImpl.newInstance() + .isSilentRingingRequested(getDetails().getExtras()); } public boolean isConference() { @@ -318,17 +315,15 @@ public class BluetoothCall { } public boolean wasConferencePreviouslyMerged() { - return can(Call.Details.CAPABILITY_SWAP_CONFERENCE) && - !can(Call.Details.CAPABILITY_MERGE_CONFERENCE); + return can(Call.Details.CAPABILITY_SWAP_CONFERENCE) + && !can(Call.Details.CAPABILITY_MERGE_CONFERENCE); } public DisconnectCause getDisconnectCause() { return getDetails().getDisconnectCause(); } - /** - * Returns the list of ids of corresponding Call List. - */ + /** Returns the list of ids of corresponding Call List. */ public static List getIds(List calls) { List result = new ArrayList<>(); for (Call call : calls) { diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 8b2c3c17db0..7f372008b16 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -71,8 +71,8 @@ import java.util.concurrent.Executors; /** * Used to receive updates about calls from the Telecom component. This service is bound to Telecom * while there exist calls which potentially require UI. This includes ringing (incoming), dialing - * (outgoing), and active calls. When the last BluetoothCall is disconnected, Telecom will unbind - * to the service triggering InCallActivity (via CallList) to finish soon after. + * (outgoing), and active calls. When the last BluetoothCall is disconnected, Telecom will unbind to + * the service triggering InCallActivity (via CallList) to finish soon after. */ public class BluetoothInCallService extends InCallService { @@ -110,23 +110,18 @@ public class BluetoothInCallService extends InCallService { private boolean mHeadsetUpdatedRecently = false; private boolean mIsDisconnectedTonePlaying = false; - @VisibleForTesting - boolean mIsTerminatedByClient = false; + @VisibleForTesting boolean mIsTerminatedByClient = false; private static final Object LOCK = new Object(); - @VisibleForTesting - BluetoothHeadsetProxy mBluetoothHeadset; + @VisibleForTesting BluetoothHeadsetProxy mBluetoothHeadset; - @VisibleForTesting - BluetoothLeCallControlProxy mBluetoothLeCallControl; + @VisibleForTesting BluetoothLeCallControlProxy mBluetoothLeCallControl; private ExecutorService mExecutor; - @VisibleForTesting - public TelephonyManager mTelephonyManager; + @VisibleForTesting public TelephonyManager mTelephonyManager; - @VisibleForTesting - public TelecomManager mTelecomManager; + @VisibleForTesting public TelecomManager mTelecomManager; @VisibleForTesting public final HashMap mCallbacks = new HashMap<>(); @@ -191,8 +186,8 @@ public class BluetoothInCallService extends InCallService { Log.w(TAG, "BluetoothAdapterReceiver: Intent action " + intent.getAction()); return; } - int state = intent - .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); + int state = + intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); Log.d(TAG, "Bluetooth Adapter state: " + state); if (state == BluetoothAdapter.STATE_ON) { queryPhoneState(); @@ -201,15 +196,13 @@ public class BluetoothInCallService extends InCallService { } } } - }; + } + ; - /** - * Receives events for global state changes of the bluetooth adapter. - */ + /** Receives events for global state changes of the bluetooth adapter. */ // TODO: The code is moved from Telecom stack. Since we're running in the BT process itself, // we may be able to simplify this in a future patch. - @VisibleForTesting - public BluetoothAdapterReceiver mBluetoothAdapterReceiver; + @VisibleForTesting public BluetoothAdapterReceiver mBluetoothAdapterReceiver; @VisibleForTesting public class CallStateCallback extends Call.Callback { @@ -299,7 +292,8 @@ public class BluetoothInCallService extends InCallService { if (call.getParentId() != null) { // If this BluetoothCall is newly conferenced, ignore the callback. // We only care about the one sent for the parent conference call. - Log.d(TAG, + Log.d( + TAG, "Ignoring onIsConferenceChanged from child BluetoothCall with new parent"); return; } @@ -309,8 +303,7 @@ public class BluetoothInCallService extends InCallService { @Override public void onParentChanged(Call call, Call parent) { super.onParentChanged(call, parent); - onParentChanged( - getBluetoothCallById(System.identityHashCode(call))); + onParentChanged(getBluetoothCallById(System.identityHashCode(call))); } public void onChildrenChanged(BluetoothCall call, List children) { @@ -323,8 +316,7 @@ public class BluetoothInCallService extends InCallService { // ignore the callback as well since the minimum number of child calls to // start a conference BluetoothCall is 2. We expect this to be called again // when the parent BluetoothCall has another child BluetoothCall added. - Log.d(TAG, - "Ignoring onIsConferenceChanged from parent with only one child call"); + Log.d(TAG, "Ignoring onIsConferenceChanged from parent with only one child call"); return; } updateHeadsetWithCallState(false /* force */); @@ -426,7 +418,7 @@ public class BluetoothInCallService extends InCallService { } @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public String getNetworkOperator() { + public String getNetworkOperator() { synchronized (LOCK) { enforceModifyPermission(); Log.i(TAG, "getNetworkOperator"); @@ -445,7 +437,7 @@ public class BluetoothInCallService extends InCallService { * @return bearer technology as defined in Bluetooth Assigned Numbers */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public int getBearerTechnology() { + public int getBearerTechnology() { synchronized (LOCK) { enforceModifyPermission(); Log.i(TAG, "getBearerTechnology"); @@ -459,7 +451,7 @@ public class BluetoothInCallService extends InCallService { case TelephonyManager.NETWORK_TYPE_GPRS: return BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_2G; - case TelephonyManager.NETWORK_TYPE_EDGE : + case TelephonyManager.NETWORK_TYPE_EDGE: case TelephonyManager.NETWORK_TYPE_EVDO_0: case TelephonyManager.NETWORK_TYPE_EVDO_A: case TelephonyManager.NETWORK_TYPE_HSDPA: @@ -646,8 +638,7 @@ public class BluetoothInCallService extends InCallService { .setPacketsNotReceivedCount(packetsNotReceiveCount) .setNegativeAcknowledgementCount(negativeAcknowledgementCount) .build()); - call.sendCallEvent( - BluetoothCallQualityReport.EVENT_BLUETOOTH_CALL_QUALITY_REPORT, b); + call.sendCallEvent(BluetoothCallQualityReport.EVENT_BLUETOOTH_CALL_QUALITY_REPORT, b); } @Override @@ -661,9 +652,9 @@ public class BluetoothInCallService extends InCallService { * * @param call the {@code BluetoothCall} to remove * @param forceRemoveCallback if true, this will always unregister this {@code InCallService} as - * a callback for the given {@code BluetoothCall}, when false, this - * will not remove the callback when the {@code BluetoothCall} is - * external so that the call can be added back if no longer external. + * a callback for the given {@code BluetoothCall}, when false, this will not remove the + * callback when the {@code BluetoothCall} is external so that the call can be added back if + * no longer external. */ public void onCallRemoved(BluetoothCall call, boolean forceRemoveCallback) { Log.d(TAG, "onCallRemoved"); @@ -699,7 +690,8 @@ public class BluetoothInCallService extends InCallService { updateHeadsetWithCallState(false /* force */); if (mBluetoothLeCallControl != null) { - mBluetoothLeCallControl.onCallRemoved(call.getTbsCallId(), getTbsTerminationReason(call)); + mBluetoothLeCallControl.onCallRemoved( + call.getTbsCallId(), getTbsTerminationReason(call)); } } @@ -720,7 +712,6 @@ public class BluetoothInCallService extends InCallService { Log.d(TAG, "onCallAudioStateChanged, audioState == " + audioState); } - @Override public void onCreate() { Log.d(TAG, "onCreate"); @@ -776,8 +767,8 @@ public class BluetoothInCallService extends InCallService { private static boolean isConferenceWithNoChildren(BluetoothCall call) { return call.isConference() - && (call.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN) - || call.getChildrenIds().isEmpty()); + && (call.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN) + || call.getChildrenIds().isEmpty()); } private void sendListOfCalls(boolean shouldLog) { @@ -918,9 +909,7 @@ public class BluetoothInCallService extends InCallService { } } - /** - * Sends a single clcc (C* List Current Calls) event for the specified call. - */ + /** Sends a single clcc (C* List Current Calls) event for the specified call. */ private void sendClccForCall(BluetoothCall call, boolean shouldLog) { boolean isForeground = mCallInfo.getForegroundCall() == call; int state = getBtCallState(call, isForeground); @@ -1000,21 +989,33 @@ public class BluetoothInCallService extends InCallService { int addressType = address == null ? -1 : PhoneNumberUtils.toaFromString(address); if (shouldLog) { - Log.i(TAG, "sending clcc for BluetoothCall " - + index + ", " - + direction + ", " - + state + ", " - + isPartOfConference + ", " + Log.i( + TAG, + "sending clcc for BluetoothCall " + + index + + ", " + + direction + + ", " + + state + + ", " + + isPartOfConference + + ", " + addressType); } if (mBluetoothHeadset == null) { - Log.w(TAG, "mBluetoothHeasdset is null when sending clcc for BluetoothCall " - + index + ", " - + direction + ", " - + state + ", " - + isPartOfConference + ", " - + addressType); + Log.w( + TAG, + "mBluetoothHeasdset is null when sending clcc for BluetoothCall " + + index + + ", " + + direction + + ", " + + state + + ", " + + isPartOfConference + + ", " + + addressType); } else { mBluetoothHeadset.clccResponse( index, direction, state, 0, isPartOfConference, address, addressType); @@ -1062,7 +1063,6 @@ public class BluetoothInCallService extends InCallService { return call.mClccIndex; } - private boolean _processChld(int chld) { BluetoothCall activeCall = mCallInfo.getActiveCall(); BluetoothCall ringingCall = mCallInfo.getRingingOrSimulatedRingingCall(); @@ -1074,10 +1074,16 @@ public class BluetoothInCallService extends InCallService { BluetoothCall heldCall = mCallInfo.getHeldCall(); - Log.i(TAG, "Active: " + activeCall - + " Ringing: " + ringingCall - + " Held: " + heldCall - + " chld: " + chld); + Log.i( + TAG, + "Active: " + + activeCall + + " Ringing: " + + ringingCall + + " Held: " + + heldCall + + " chld: " + + chld); if (chld == CHLD_TYPE_RELEASEHELD) { Log.i(TAG, "chld is CHLD_TYPE_RELEASEHELD"); @@ -1137,8 +1143,8 @@ public class BluetoothInCallService extends InCallService { activeCall.mergeConference(); return true; } else { - List conferenceable = getBluetoothCallsByIds( - activeCall.getConferenceableCalls()); + List conferenceable = + getBluetoothCallsByIds(activeCall.getConferenceableCalls()); if (!conferenceable.isEmpty()) { activeCall.conference(conferenceable.get(0)); return true; @@ -1152,9 +1158,9 @@ public class BluetoothInCallService extends InCallService { /** * Sends an update of the current BluetoothCall state to the current Headset. * - * @param force {@code true} if the headset state should be sent regardless if no changes to - * the state have occurred, {@code false} if the state should only be sent if the state - * has changed. + * @param force {@code true} if the headset state should be sent regardless if no changes to the + * state have occurred, {@code false} if the state should only be sent if the state has + * changed. */ private void updateHeadsetWithCallState(boolean force) { BluetoothCall activeCall = mCallInfo.getActiveCall(); @@ -1166,7 +1172,8 @@ public class BluetoothInCallService extends InCallService { String ringingAddress = null; int ringingAddressType = DEFAULT_RINGING_ADDRESS_TYPE; String ringingName = null; - if (!mCallInfo.isNullCall(ringingCall) && ringingCall.getHandle() != null + if (!mCallInfo.isNullCall(ringingCall) + && ringingCall.getHandle() != null && !ringingCall.isSilentRingingRequested()) { ringingAddress = ringingCall.getHandle().getSchemeSpecificPart(); if (ringingAddress != null) { @@ -1195,14 +1202,15 @@ public class BluetoothInCallService extends InCallService { // conference (namely CDMA calls) we need to expose that as a held BluetoothCall // in order for the BT device to show "swap" and "merge" functionality. boolean ignoreHeldCallChange = false; - if (!mCallInfo.isNullCall(activeCall) && activeCall.isConference() + if (!mCallInfo.isNullCall(activeCall) + && activeCall.isConference() && !activeCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) { if (activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) { // Indicate that BT device should show SWAP command by indicating that there is a // BluetoothCall on hold, but only if the conference wasn't previously merged. numHeldCalls = activeCall.wasConferencePreviouslyMerged() ? 0 : 1; } else if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) { - numHeldCalls = 1; // Merge is available, so expose via numHeldCalls. + numHeldCalls = 1; // Merge is available, so expose via numHeldCalls. } for (Integer id : activeCall.getChildrenIds()) { @@ -1218,20 +1226,21 @@ public class BluetoothInCallService extends InCallService { if (mBluetoothHeadset != null && (force - || (!callsPendingSwitch - && (numActiveCalls != mNumActiveCalls - || numChildrenOfActiveCall != mNumChildrenOfActiveCall - || numHeldCalls != mNumHeldCalls - || bluetoothCallState != mBluetoothCallState - || !TextUtils.equals(ringingAddress, mRingingAddress) - || ringingAddressType != mRingingAddressType - || (heldCall != mOldHeldCall && !ignoreHeldCallChange))))) { + || (!callsPendingSwitch + && (numActiveCalls != mNumActiveCalls + || numChildrenOfActiveCall != mNumChildrenOfActiveCall + || numHeldCalls != mNumHeldCalls + || bluetoothCallState != mBluetoothCallState + || !TextUtils.equals(ringingAddress, mRingingAddress) + || ringingAddressType != mRingingAddressType + || (heldCall != mOldHeldCall && !ignoreHeldCallChange))))) { // If the BluetoothCall is transitioning into the alerting state, send DIALING first. // Some devices expect to see a DIALING state prior to seeing an ALERTING state // so we need to send it first. - boolean sendDialingFirst = mBluetoothCallState != bluetoothCallState - && bluetoothCallState == CALL_STATE_ALERTING; + boolean sendDialingFirst = + mBluetoothCallState != bluetoothCallState + && bluetoothCallState == CALL_STATE_ALERTING; mOldHeldCall = heldCall; mNumActiveCalls = numActiveCalls; @@ -1243,11 +1252,20 @@ public class BluetoothInCallService extends InCallService { if (sendDialingFirst) { // Log in full to make logs easier to debug. - Log.i(TAG, "updateHeadsetWithCallState " - + "numActive " + mNumActiveCalls + ", " - + "numHeld " + mNumHeldCalls + ", " - + "callState " + CALL_STATE_DIALING + ", " - + "ringing type " + mRingingAddressType); + Log.i( + TAG, + "updateHeadsetWithCallState " + + "numActive " + + mNumActiveCalls + + ", " + + "numHeld " + + mNumHeldCalls + + ", " + + "callState " + + CALL_STATE_DIALING + + ", " + + "ringing type " + + mRingingAddressType); mBluetoothHeadset.phoneStateChanged( mNumActiveCalls, mNumHeldCalls, @@ -1257,11 +1275,20 @@ public class BluetoothInCallService extends InCallService { ringingName); } - Log.i(TAG, "updateHeadsetWithCallState " - + "numActive " + mNumActiveCalls + ", " - + "numHeld " + mNumHeldCalls + ", " - + "callState " + mBluetoothCallState + ", " - + "ringing type " + mRingingAddressType); + Log.i( + TAG, + "updateHeadsetWithCallState " + + "numActive " + + mNumActiveCalls + + ", " + + "numHeld " + + mNumHeldCalls + + ", " + + "callState " + + mBluetoothCallState + + ", " + + "ringing type " + + mRingingAddressType); mBluetoothHeadset.phoneStateChanged( mNumActiveCalls, @@ -1475,9 +1502,9 @@ public class BluetoothInCallService extends InCallService { } /** - * Returns the best phone account to use for the given state of all calls. - * First, tries to return the phone account for the foreground call, second the default - * phone account for PhoneAccount.SCHEME_TEL. + * Returns the best phone account to use for the given state of all calls. First, tries to + * return the phone account for the foreground call, second the default phone account for + * PhoneAccount.SCHEME_TEL. */ public PhoneAccount getBestPhoneAccount() { BluetoothCall call = getForegroundCall(); @@ -1523,43 +1550,48 @@ public class BluetoothInCallService extends InCallService { } return null; } - }; + } + ; @VisibleForTesting public void setBluetoothLeCallControl(BluetoothLeCallControlProxy bluetoothTbs) { mBluetoothLeCallControl = bluetoothTbs; if ((mBluetoothLeCallControl) != null && (mTelecomManager != null)) { - mBluetoothLeCallControl.registerBearer(TAG, + mBluetoothLeCallControl.registerBearer( + TAG, new ArrayList(Arrays.asList("tel")), - BluetoothLeCallControl.CAPABILITY_HOLD_CALL, getNetworkOperator(), - getBearerTechnology(), mExecutor, mBluetoothLeCallControlCallback); + BluetoothLeCallControl.CAPABILITY_HOLD_CALL, + getNetworkOperator(), + getBearerTechnology(), + mExecutor, + mBluetoothLeCallControlCallback); } } private Integer getTbsCallState(BluetoothCall call) { switch (call.getState()) { - case Call.STATE_ACTIVE: - return BluetoothLeCall.STATE_ACTIVE; + case Call.STATE_ACTIVE: + return BluetoothLeCall.STATE_ACTIVE; - case Call.STATE_CONNECTING: - case Call.STATE_SELECT_PHONE_ACCOUNT: - return BluetoothLeCall.STATE_DIALING; + case Call.STATE_CONNECTING: + case Call.STATE_SELECT_PHONE_ACCOUNT: + return BluetoothLeCall.STATE_DIALING; - case Call.STATE_DIALING: - case Call.STATE_PULLING_CALL: - return BluetoothLeCall.STATE_ALERTING; + case Call.STATE_DIALING: + case Call.STATE_PULLING_CALL: + return BluetoothLeCall.STATE_ALERTING; - case Call.STATE_HOLDING: - return BluetoothLeCall.STATE_LOCALLY_HELD; + case Call.STATE_HOLDING: + return BluetoothLeCall.STATE_LOCALLY_HELD; - case Call.STATE_RINGING: - case Call.STATE_SIMULATED_RINGING: - if (call.isSilentRingingRequested()) { - return null; - } else { - return BluetoothLeCall.STATE_INCOMING; - } + case Call.STATE_RINGING: + case Call.STATE_SIMULATED_RINGING: + if (call.isSilentRingingRequested()) { + return null; + } else { + return BluetoothLeCall.STATE_INCOMING; + } } return null; } @@ -1573,23 +1605,23 @@ public class BluetoothInCallService extends InCallService { } switch (cause.getCode()) { - case DisconnectCause.BUSY: - return BluetoothLeCallControl.TERMINATION_REASON_LINE_BUSY; - case DisconnectCause.REMOTE: - case DisconnectCause.REJECTED: - return BluetoothLeCallControl.TERMINATION_REASON_REMOTE_HANGUP; - case DisconnectCause.LOCAL: - if (mIsTerminatedByClient) { - mIsTerminatedByClient = false; - return BluetoothLeCallControl.TERMINATION_REASON_CLIENT_HANGUP; - } - return BluetoothLeCallControl.TERMINATION_REASON_SERVER_HANGUP; - case DisconnectCause.ERROR: - return BluetoothLeCallControl.TERMINATION_REASON_NETWORK_CONGESTION; - case DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED: - return BluetoothLeCallControl.TERMINATION_REASON_INVALID_URI; - default: - return BluetoothLeCallControl.TERMINATION_REASON_FAIL; + case DisconnectCause.BUSY: + return BluetoothLeCallControl.TERMINATION_REASON_LINE_BUSY; + case DisconnectCause.REMOTE: + case DisconnectCause.REJECTED: + return BluetoothLeCallControl.TERMINATION_REASON_REMOTE_HANGUP; + case DisconnectCause.LOCAL: + if (mIsTerminatedByClient) { + mIsTerminatedByClient = false; + return BluetoothLeCallControl.TERMINATION_REASON_CLIENT_HANGUP; + } + return BluetoothLeCallControl.TERMINATION_REASON_SERVER_HANGUP; + case DisconnectCause.ERROR: + return BluetoothLeCallControl.TERMINATION_REASON_NETWORK_CONGESTION; + case DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED: + return BluetoothLeCallControl.TERMINATION_REASON_INVALID_URI; + default: + return BluetoothLeCallControl.TERMINATION_REASON_FAIL; } } @@ -1614,14 +1646,14 @@ public class BluetoothInCallService extends InCallService { // ACTIVE BluetoothCall and that the conference itself has a notion of // the current "active" child call. BluetoothCall activeChild = - getBluetoothCallById(conferenceCall.getGenericConferenceActiveChildCallId()); + getBluetoothCallById(conferenceCall.getGenericConferenceActiveChildCallId()); if (state == BluetoothLeCall.STATE_ACTIVE && !mCallInfo.isNullCall(activeChild)) { // Reevaluate state if we can MERGE or if we can SWAP without previously having // MERGED. boolean shouldReevaluateState = conferenceCall.can(Connection.CAPABILITY_MERGE_CONFERENCE) - || (conferenceCall.can(Connection.CAPABILITY_SWAP_CONFERENCE) - && !conferenceCall.wasConferencePreviouslyMerged()); + || (conferenceCall.can(Connection.CAPABILITY_SWAP_CONFERENCE) + && !conferenceCall.wasConferencePreviouslyMerged()); if (shouldReevaluateState) { if (call == activeChild) { @@ -1683,117 +1715,122 @@ public class BluetoothInCallService extends InCallService { final BluetoothLeCallControl.Callback mBluetoothLeCallControlCallback = new BluetoothLeCallControl.Callback() { - @Override - public void onAcceptCall(int requestId, UUID callId) { - synchronized (LOCK) { - enforceModifyPermission(); - Log.i(TAG, "TBS - accept call=" + callId); - int result = BluetoothLeCallControl.RESULT_SUCCESS; - BluetoothCall call = mCallInfo.getCallByCallId(callId); - if (mCallInfo.isNullCall(call)) { - result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; - } else { - call.answer(VideoProfile.STATE_AUDIO_ONLY); + @Override + public void onAcceptCall(int requestId, UUID callId) { + synchronized (LOCK) { + enforceModifyPermission(); + Log.i(TAG, "TBS - accept call=" + callId); + int result = BluetoothLeCallControl.RESULT_SUCCESS; + BluetoothCall call = mCallInfo.getCallByCallId(callId); + if (mCallInfo.isNullCall(call)) { + result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + } else { + call.answer(VideoProfile.STATE_AUDIO_ONLY); + } + mBluetoothLeCallControl.requestResult(requestId, result); + } } - mBluetoothLeCallControl.requestResult(requestId, result); - } - } - @Override - public void onTerminateCall(int requestId, UUID callId) { - synchronized (LOCK) { - enforceModifyPermission(); - Log.i(TAG, "TBS - terminate call=" + callId); - int result = BluetoothLeCallControl.RESULT_SUCCESS; - BluetoothCall call = mCallInfo.getCallByCallId(callId); - if (mCallInfo.isNullCall(call)) { - result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; - } else { - mIsTerminatedByClient = true; - call.disconnect(); + @Override + public void onTerminateCall(int requestId, UUID callId) { + synchronized (LOCK) { + enforceModifyPermission(); + Log.i(TAG, "TBS - terminate call=" + callId); + int result = BluetoothLeCallControl.RESULT_SUCCESS; + BluetoothCall call = mCallInfo.getCallByCallId(callId); + if (mCallInfo.isNullCall(call)) { + result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + } else { + mIsTerminatedByClient = true; + call.disconnect(); + } + mBluetoothLeCallControl.requestResult(requestId, result); + } } - mBluetoothLeCallControl.requestResult(requestId, result); - } - } - @Override - public void onHoldCall(int requestId, UUID callId) { - synchronized (LOCK) { - enforceModifyPermission(); - Log.i(TAG, "TBS - hold call=" + callId); - int result = BluetoothLeCallControl.RESULT_SUCCESS; - BluetoothCall call = mCallInfo.getCallByCallId(callId); - if (mCallInfo.isNullCall(call)) { - result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; - } else { - call.hold(); + @Override + public void onHoldCall(int requestId, UUID callId) { + synchronized (LOCK) { + enforceModifyPermission(); + Log.i(TAG, "TBS - hold call=" + callId); + int result = BluetoothLeCallControl.RESULT_SUCCESS; + BluetoothCall call = mCallInfo.getCallByCallId(callId); + if (mCallInfo.isNullCall(call)) { + result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + } else { + call.hold(); + } + mBluetoothLeCallControl.requestResult(requestId, result); + } } - mBluetoothLeCallControl.requestResult(requestId, result); - } - } - @Override - public void onUnholdCall(int requestId, UUID callId) { - synchronized (LOCK) { - enforceModifyPermission(); - Log.i(TAG, "TBS - unhold call=" + callId); - int result = BluetoothLeCallControl.RESULT_SUCCESS; - BluetoothCall call = mCallInfo.getCallByCallId(callId); - if (mCallInfo.isNullCall(call)) { - result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; - } else { - call.unhold(); + @Override + public void onUnholdCall(int requestId, UUID callId) { + synchronized (LOCK) { + enforceModifyPermission(); + Log.i(TAG, "TBS - unhold call=" + callId); + int result = BluetoothLeCallControl.RESULT_SUCCESS; + BluetoothCall call = mCallInfo.getCallByCallId(callId); + if (mCallInfo.isNullCall(call)) { + result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + } else { + call.unhold(); + } + mBluetoothLeCallControl.requestResult(requestId, result); + } } - mBluetoothLeCallControl.requestResult(requestId, result); - } - } - @Override - public void onPlaceCall(int requestId, UUID callId, String uri) { - mBluetoothLeCallControl.requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_APPLICATION); - } - - @Override - public void onJoinCalls(int requestId, @NonNull List callIds) { - synchronized (LOCK) { - Log.i(TAG, "TBS - onJoinCalls"); - int result = BluetoothLeCallControl.RESULT_SUCCESS; - List alreadyJoinedCalls = new ArrayList<>(); - BluetoothCall baseCallInstance = null; - - if (callIds.size() < 2) { - Log.e(TAG, "TBS - onJoinCalls, join call number is invalid: " + callIds.size()); - result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; - mBluetoothLeCallControl.requestResult(requestId, result); - return; + @Override + public void onPlaceCall(int requestId, UUID callId, String uri) { + mBluetoothLeCallControl.requestResult( + requestId, BluetoothLeCallControl.RESULT_ERROR_APPLICATION); } - for (UUID callToJoinUuid : callIds) { - BluetoothCall callToJoinInstance = mCallInfo.getCallByCallId(callToJoinUuid); - - /* Skip invalid and already add device */ - if ((callToJoinInstance == null) - || (alreadyJoinedCalls.contains(callToJoinUuid))) { - continue; - } + @Override + public void onJoinCalls(int requestId, @NonNull List callIds) { + synchronized (LOCK) { + Log.i(TAG, "TBS - onJoinCalls"); + int result = BluetoothLeCallControl.RESULT_SUCCESS; + List alreadyJoinedCalls = new ArrayList<>(); + BluetoothCall baseCallInstance = null; + + if (callIds.size() < 2) { + Log.e( + TAG, + "TBS - onJoinCalls, join call number is invalid: " + + callIds.size()); + result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + mBluetoothLeCallControl.requestResult(requestId, result); + return; + } - /* Lets make first valid call the base call */ - if (baseCallInstance == null) { - baseCallInstance = callToJoinInstance; - alreadyJoinedCalls.add(callToJoinUuid); - continue; - } + for (UUID callToJoinUuid : callIds) { + BluetoothCall callToJoinInstance = + mCallInfo.getCallByCallId(callToJoinUuid); + + /* Skip invalid and already add device */ + if ((callToJoinInstance == null) + || (alreadyJoinedCalls.contains(callToJoinUuid))) { + continue; + } + + /* Lets make first valid call the base call */ + if (baseCallInstance == null) { + baseCallInstance = callToJoinInstance; + alreadyJoinedCalls.add(callToJoinUuid); + continue; + } + + baseCallInstance.conference(callToJoinInstance); + alreadyJoinedCalls.add(callToJoinUuid); + } - baseCallInstance.conference(callToJoinInstance); - alreadyJoinedCalls.add(callToJoinUuid); - } + if ((baseCallInstance == null) || (alreadyJoinedCalls.size() < 2)) { + result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + } - if ((baseCallInstance == null) || (alreadyJoinedCalls.size() < 2)) { - result = BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID; + mBluetoothLeCallControl.requestResult(requestId, result); + } } - - mBluetoothLeCallControl.requestResult(requestId, result); - } - } - }; + }; } diff --git a/android/app/src/com/android/bluetooth/util/DevicePolicyUtils.java b/android/app/src/com/android/bluetooth/util/DevicePolicyUtils.java index b45a77b533a..92abb816572 100644 --- a/android/app/src/com/android/bluetooth/util/DevicePolicyUtils.java +++ b/android/app/src/com/android/bluetooth/util/DevicePolicyUtils.java @@ -43,12 +43,13 @@ public final class DevicePolicyUtils { } /** - * Returns a URI to query all phones on the device. If a managed profile exists - * and the policy allows, it will be a URI that supports the managed profile. + * Returns a URI to query all phones on the device. If a managed profile exists and the policy + * allows, it will be a URI that supports the managed profile. */ // TODO: Make primary profile can also support getBluetoothContactSharingDisabled() public static Uri getEnterprisePhoneUri(Context context) { - return isBluetoothWorkContactSharingDisabled(context) ? Phone.CONTENT_URI + return isBluetoothWorkContactSharingDisabled(context) + ? Phone.CONTENT_URI : Phone.ENTERPRISE_CONTENT_URI; } } diff --git a/android/app/src/com/android/bluetooth/util/GsmAlphabet.java b/android/app/src/com/android/bluetooth/util/GsmAlphabet.java index c348af31c16..17611954a47 100644 --- a/android/app/src/com/android/bluetooth/util/GsmAlphabet.java +++ b/android/app/src/com/android/bluetooth/util/GsmAlphabet.java @@ -20,84 +20,71 @@ import android.util.Log; import android.util.SparseIntArray; /** - * This class implements the character set mapping between - * the GSM SMS 7-bit alphabet specified in TS 23.038 6.2.1 - * and UTF-16 + * This class implements the character set mapping between the GSM SMS 7-bit alphabet specified in + * TS 23.038 6.2.1 and UTF-16 */ public class GsmAlphabet { private static final String TAG = "GSM"; /** - * This escapes extended characters, and when present indicates that the - * following character should be looked up in the "extended" table. + * This escapes extended characters, and when present indicates that the following character + * should be looked up in the "extended" table. * - * gsmToChar(GSM_EXTENDED_ESCAPE) returns 0xffff + *

gsmToChar(GSM_EXTENDED_ESCAPE) returns 0xffff */ public static final byte GSM_EXTENDED_ESCAPE = 0x1B; /** - * User data header requires one octet for length. Count as one septet, because - * all combinations of header elements below will have at least one free bit - * when padding to the nearest septet boundary. + * User data header requires one octet for length. Count as one septet, because all combinations + * of header elements below will have at least one free bit when padding to the nearest septet + * boundary. */ public static final int UDH_SEPTET_COST_LENGTH = 1; /** - * Using a non-default language locking shift table OR single shift table - * requires a user data header of 3 octets, or 4 septets, plus UDH length. + * Using a non-default language locking shift table OR single shift table requires a user data + * header of 3 octets, or 4 septets, plus UDH length. */ public static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4; /** - * Using a non-default language locking shift table AND single shift table - * requires a user data header of 6 octets, or 7 septets, plus UDH length. + * Using a non-default language locking shift table AND single shift table requires a user data + * header of 6 octets, or 7 septets, plus UDH length. */ public static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7; /** - * Multi-part messages require a user data header of 5 octets, or 6 septets, - * plus UDH length. + * Multi-part messages require a user data header of 5 octets, or 6 septets, plus UDH length. */ public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; /** - * For a specific text string, this object describes protocol - * properties of encoding it for transmission as message user - * data. + * For a specific text string, this object describes protocol properties of encoding it for + * transmission as message user data. */ public static class TextEncodingDetails { - public TextEncodingDetails() { - } + public TextEncodingDetails() {} - /** - * The number of SMS's required to encode the text. - */ + /** The number of SMS's required to encode the text. */ public int msgCount; /** - * The number of code units consumed so far, where code units - * are basically characters in the encoding -- for example, - * septets for the standard ASCII and GSM encodings, and 16 + * The number of code units consumed so far, where code units are basically characters in + * the encoding -- for example, septets for the standard ASCII and GSM encodings, and 16 * bits for Unicode. */ public int codeUnitCount; - /** - * How many code units are still available without spilling - * into an additional message. - */ + /** How many code units are still available without spilling into an additional message. */ public int codeUnitsRemaining; /** - * The encoding code unit size (specified using - * android.telephony.SmsMessage ENCODING_*). + * The encoding code unit size (specified using android.telephony.SmsMessage ENCODING_*). */ public int codeUnitSize; - /** - * The GSM national language table to use, or 0 for the default 7-bit alphabet. - */ + /** The GSM national language table to use, or 0 for the default 7-bit alphabet. */ public int languageTable; /** @@ -108,35 +95,44 @@ public class GsmAlphabet { @Override public String toString() { return "TextEncodingDetails " - + "{ msgCount=" + msgCount - + ", codeUnitCount=" + codeUnitCount - + ", codeUnitsRemaining=" + codeUnitsRemaining - + ", codeUnitSize=" + codeUnitSize - + ", languageTable=" + languageTable - + ", languageShiftTable=" + languageShiftTable - + " }"; + + "{ msgCount=" + + msgCount + + ", codeUnitCount=" + + codeUnitCount + + ", codeUnitsRemaining=" + + codeUnitsRemaining + + ", codeUnitSize=" + + codeUnitSize + + ", languageTable=" + + languageTable + + ", languageShiftTable=" + + languageShiftTable + + " }"; } } /** - * Convert a GSM alphabet 7 bit packed string (SMS string) into a - * {@link java.lang.String}. + * Convert a GSM alphabet 7 bit packed string (SMS string) into a {@link java.lang.String}. * - * See TS 23.038 6.1.2.1 for SMS Character Packing + *

See TS 23.038 6.1.2.1 for SMS Character Packing * * @param pdu the raw data from the pdu * @param offset the byte offset of * @param lengthSeptets string length in septets, not bytes - * @param numPaddingBits the number of padding bits before the start of the - * string in the first byte + * @param numPaddingBits the number of padding bits before the start of the string in the first + * byte * @param languageTable the 7 bit language table, or 0 for the default GSM alphabet - * @param shiftTable the 7 bit single shift language table, or 0 for the default - * GSM extension table + * @param shiftTable the 7 bit single shift language table, or 0 for the default GSM extension + * table * @return String representation or null on decoding exception */ - public static String gsm7BitPackedToString(byte[] pdu, int offset, int lengthSeptets, - int numPaddingBits, int languageTable, - int shiftTable) { + public static String gsm7BitPackedToString( + byte[] pdu, + int offset, + int lengthSeptets, + int numPaddingBits, + int languageTable, + int shiftTable) { StringBuilder ret = new StringBuilder(lengthSeptets); if (languageTable < 0 || languageTable > sLanguageTables.length) { @@ -181,7 +177,7 @@ public class GsmAlphabet { if (prevCharWasEscape) { if (gsmVal == GSM_EXTENDED_ESCAPE) { - ret.append(' '); // display ' ' for reserved double escape sequence + ret.append(' '); // display ' ' for reserved double escape sequence } else { char c = shiftTableToChar.charAt(gsmVal); if (c == ' ') { @@ -206,8 +202,9 @@ public class GsmAlphabet { } /** - * Convert a string into an 8-bit unpacked GSM alphabet byte array. - * Always uses GSM default 7-bit alphabet and extension table. + * Convert a string into an 8-bit unpacked GSM alphabet byte array. Always uses GSM default + * 7-bit alphabet and extension table. + * * @param s the string to encode * @return the 8-bit GSM encoded byte array for the string */ @@ -225,16 +222,15 @@ public class GsmAlphabet { } /** - * Write a String into a GSM 8-bit unpacked field of - * Field is padded with 0xff's, string is truncated if necessary + * Write a String into a GSM 8-bit unpacked field of Field is padded with 0xff's, string is + * truncated if necessary * * @param s the string to encode * @param dest the destination byte array * @param offset the starting offset for the encoded string * @param length the maximum number of bytes to write */ - public static void stringToGsm8BitUnpackedField(String s, byte[] dest, int offset, - int length) { + public static void stringToGsm8BitUnpackedField(String s, byte[] dest, int offset, int length) { int outByteIndex = offset; SparseIntArray charToLanguageTable = sCharsToGsmTables[0]; SparseIntArray charToShiftTable = sCharsToShiftTables[0]; @@ -246,7 +242,7 @@ public class GsmAlphabet { if (v == -1) { v = charToShiftTable.get(c, -1); if (v == -1) { - v = charToLanguageTable.get(' ', ' '); // fall back to ASCII space + v = charToLanguageTable.get(' ', ' '); // fall back to ASCII space } else { // make sure we can fit an escaped char if (!(outByteIndex + 1 - offset < length)) { @@ -267,20 +263,20 @@ public class GsmAlphabet { } /** - * Returns the count of 7-bit GSM alphabet characters needed - * to represent this string, using the specified 7-bit language table - * and extension table (0 for GSM default tables). + * Returns the count of 7-bit GSM alphabet characters needed to represent this string, using the + * specified 7-bit language table and extension table (0 for GSM default tables). + * * @param s the Unicode string that will be encoded - * @param use7bitOnly allow using space in place of unencodable character if true, - * otherwise, return -1 if any characters are unencodable + * @param use7bitOnly allow using space in place of unencodable character if true, otherwise, + * return -1 if any characters are unencodable * @param languageTable the 7 bit language table, or 0 for the default GSM alphabet - * @param languageShiftTable the 7 bit single shift language table, or 0 for the default - * GSM extension table - * @return the septet count for s using the specified language tables, or -1 if any - * characters are unencodable and use7bitOnly is false + * @param languageShiftTable the 7 bit single shift language table, or 0 for the default GSM + * extension table + * @return the septet count for s using the specified language tables, or -1 if any characters + * are unencodable and use7bitOnly is false */ - public static int countGsmSeptetsUsingTables(CharSequence s, boolean use7bitOnly, - int languageTable, int languageShiftTable) { + public static int countGsmSeptetsUsingTables( + CharSequence s, boolean use7bitOnly, int languageTable, int languageShiftTable) { int count = 0; int sz = s.length(); SparseIntArray charToLanguageTable = sCharsToGsmTables[languageTable]; @@ -296,9 +292,9 @@ public class GsmAlphabet { } else if (charToShiftTable.get(c, -1) != -1) { count += 2; // escape + shift table index } else if (use7bitOnly) { - count++; // encode as space + count++; // encode as space } else { - return -1; // caller must check for this case + return -1; // caller must check for this case } } return count; @@ -311,340 +307,393 @@ public class GsmAlphabet { private static final SparseIntArray[] sCharsToShiftTables; /** - * GSM default 7 bit alphabet plus national language locking shift character tables. - * Comment lines above strings indicate the lower four bits of the table position. + * GSM default 7 bit alphabet plus national language locking shift character tables. Comment + * lines above strings indicate the lower four bits of the table position. */ private static final String[] sLanguageTables = { /* 3GPP TS 23.038 V9.1.1 section 6.2.1 - GSM 7 bit Default Alphabet - 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */ + 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */ "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_" - // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... - + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u00c6\u00e6\u00df" - // F.....012.34.....56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789A - + "\u00c9 !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ" - // B.....C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... - + "\u00c4\u00d6\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1" - // E.....F..... - + "\u00fc\u00e0", + // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... + + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u00c6\u00e6\u00df" + // F.....012.34.....56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789A + + "\u00c9 !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // B.....C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... + + "\u00c4\u00d6\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1" + // E.....F..... + + "\u00fc\u00e0", /* A.3.1 Turkish National Language Locking Shift Table - 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */ + 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */ "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_" - // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... - + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u015e\u015f\u00df" - // F.....012.34.....56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789A - + "\u00c9 !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ" - // B.....C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... - + "\u00c4\u00d6\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1" - // E.....F..... - + "\u00fc\u00e0", + // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... + + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u015e\u015f\u00df" + // F.....012.34.....56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789A + + "\u00c9 !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // B.....C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... + + "\u00c4\u00d6\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1" + // E.....F..... + + "\u00fc\u00e0", /* A.3.2 Void (no locking shift table for Spanish) */ "", /* A.3.3 Portuguese National Language Locking Shift Table - 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */ + 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */ "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_" - // 2.....3.....4.....5.....67.8.....9.....AB.....C.....D.....E.....F.....012.34..... - + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|\uffff\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba" - // 56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789AB.....C.....D.....E..... - + "%&'()*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc" - // F.....0123456789ABCDEF0123456789AB.....C.....DE.....F..... - + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0", + // 2.....3.....4.....5.....67.8.....9.....AB.....C.....D.....E.....F.....012.34..... + + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|\uffff\u00c2\u00e2\u00ca\u00c9" + + " !\"#\u00ba" + // 56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789AB.....C.....D.....E..... + + "%&'()*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc" + // F.....0123456789ABCDEF0123456789AB.....C.....DE.....F..... + + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0", /* A.3.4 Bengali National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....0..... */ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....0..... */ "\u0981\u0982\u0983\u0985\u0986\u0987\u0988\u0989\u098a\u098b\n\u098c \r \u098f\u0990" - // 123.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F..... - + " \u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099a\uffff\u099b\u099c\u099d\u099e" - // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC - + " !\u099f\u09a0\u09a1\u09a2\u09a3\u09a4)(\u09a5\u09a6,\u09a7.\u09a80123456789:; " - // D.....E.....F0.....1.....2.....3.....4.....56.....789A.....B.....C.....D..... - + "\u09aa\u09ab?\u09ac\u09ad\u09ae\u09af\u09b0 \u09b2 \u09b6\u09b7\u09b8\u09b9" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E..... - + "\u09bc\u09bd\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c4 \u09c7\u09c8 \u09cb\u09cc" - // F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F..... - + "\u09cd\u09ceabcdefghijklmnopqrstuvwxyz\u09d7\u09dc\u09dd\u09f0\u09f1", + // 123.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F..... + + " \u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099a\uffff\u099b\u099c\u099d\u099e" + // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC + + " !\u099f\u09a0\u09a1\u09a2\u09a3\u09a4)(\u09a5\u09a6,\u09a7.\u09a80123456789:; " + // D.....E.....F0.....1.....2.....3.....4.....56.....789A.....B.....C.....D..... + + "\u09aa\u09ab?\u09ac\u09ad\u09ae\u09af\u09b0 \u09b2 \u09b6\u09b7\u09b8\u09b9" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E..... + + "\u09bc\u09bd\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c4 \u09c7\u09c8 " + + " \u09cb\u09cc" + // F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F..... + + "\u09cd\u09ceabcdefghijklmnopqrstuvwxyz\u09d7\u09dc\u09dd\u09f0\u09f1", /* A.3.5 Gujarati National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.EF.....0.....*/ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.EF.....0.....*/ "\u0a81\u0a82\u0a83\u0a85\u0a86\u0a87\u0a88\u0a89\u0a8a\u0a8b\n\u0a8c\u0a8d\r \u0a8f\u0a90" - // 1.....23.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... - + "\u0a91 \u0a93\u0a94\u0a95\u0a96\u0a97\u0a98\u0a99\u0a9a\uffff\u0a9b\u0a9c\u0a9d" - // F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789AB - + "\u0a9e !\u0a9f\u0aa0\u0aa1\u0aa2\u0aa3\u0aa4)(\u0aa5\u0aa6,\u0aa7.\u0aa80123456789:;" - // CD.....E.....F0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C..... - + " \u0aaa\u0aab?\u0aac\u0aad\u0aae\u0aaf\u0ab0 \u0ab2\u0ab3 \u0ab5\u0ab6\u0ab7\u0ab8" - // D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89.....A..... - + "\u0ab9\u0abc\u0abd\u0abe\u0abf\u0ac0\u0ac1\u0ac2\u0ac3\u0ac4\u0ac5 \u0ac7\u0ac8" - // B.....CD.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E..... - + "\u0ac9 \u0acb\u0acc\u0acd\u0ad0abcdefghijklmnopqrstuvwxyz\u0ae0\u0ae1\u0ae2\u0ae3" - // F..... - + "\u0af1", + // 1.....23.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... + + "\u0a91 \u0a93\u0a94\u0a95\u0a96\u0a97\u0a98\u0a99\u0a9a\uffff\u0a9b\u0a9c\u0a9d" + // F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789AB + + "\u0a9e" + + " !\u0a9f\u0aa0\u0aa1\u0aa2\u0aa3\u0aa4)(\u0aa5\u0aa6,\u0aa7.\u0aa80123456789:;" + // CD.....E.....F0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C..... + + " \u0aaa\u0aab?\u0aac\u0aad\u0aae\u0aaf\u0ab0 \u0ab2\u0ab3" + + " \u0ab5\u0ab6\u0ab7\u0ab8" + // D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89.....A..... + + "\u0ab9\u0abc\u0abd\u0abe\u0abf\u0ac0\u0ac1\u0ac2\u0ac3\u0ac4\u0ac5 \u0ac7\u0ac8" + // B.....CD.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E..... + + "\u0ac9" + + " \u0acb\u0acc\u0acd\u0ad0abcdefghijklmnopqrstuvwxyz\u0ae0\u0ae1\u0ae2\u0ae3" + // F..... + + "\u0af1", /* A.3.6 Hindi National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....*/ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....*/ "\u0901\u0902\u0903\u0905\u0906\u0907\u0908\u0909\u090a\u090b\n\u090c\u090d\r\u090e\u090f" - // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D..... - + "\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\uffff\u091b\u091c" - // E.....F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....012345 - + "\u091d\u091e !\u091f\u0920\u0921\u0922\u0923\u0924)(\u0925\u0926,\u0927.\u0928012345" - // 6789ABC.....D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8..... - + "6789:;\u0929\u092a\u092b?\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934" - // 9.....A.....B.....C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6..... - + "\u0935\u0936\u0937\u0938\u0939\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944" - // 7.....8.....9.....A.....B.....C.....D.....E.....F.....0.....123456789ABCDEF012345678 - + "\u0945\u0946\u0947\u0948\u0949\u094a\u094b\u094c\u094d\u0950abcdefghijklmnopqrstuvwx" - // 9AB.....C.....D.....E.....F..... - + "yz\u0972\u097b\u097c\u097e\u097f", + // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D..... + + "\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\uffff\u091b\u091c" + // E.....F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....012345 + + "\u091d\u091e" + + " !\u091f\u0920\u0921\u0922\u0923\u0924)(\u0925\u0926,\u0927.\u0928012345" + // 6789ABC.....D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8..... + + "6789:;\u0929\u092a\u092b?\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934" + // 9.....A.....B.....C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6..... + + "\u0935\u0936\u0937\u0938\u0939\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944" + // 7.....8.....9.....A.....B.....C.....D.....E.....F.....0.....123456789ABCDEF012345678 + + "\u0945\u0946\u0947\u0948\u0949\u094a\u094b\u094c\u094d\u0950abcdefghijklmnopqrstuvwx" + // 9AB.....C.....D.....E.....F..... + + "yz\u0972\u097b\u097c\u097e\u097f", /* A.3.7 Kannada National Language Locking Shift Table - NOTE: TS 23.038 V9.1.1 shows code 0x24 as \u0caa, corrected to \u0ca1 (typo) - 01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....1 */ + NOTE: TS 23.038 V9.1.1 shows code 0x24 as \u0caa, corrected to \u0ca1 (typo) + 01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....1 */ " \u0c82\u0c83\u0c85\u0c86\u0c87\u0c88\u0c89\u0c8a\u0c8b\n\u0c8c \r\u0c8e\u0c8f\u0c90 " - // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F..... - + "\u0c92\u0c93\u0c94\u0c95\u0c96\u0c97\u0c98\u0c99\u0c9a\uffff\u0c9b\u0c9c\u0c9d\u0c9e" - // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC - + " !\u0c9f\u0ca0\u0ca1\u0ca2\u0ca3\u0ca4)(\u0ca5\u0ca6,\u0ca7.\u0ca80123456789:; " - // D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B..... - + "\u0caa\u0cab?\u0cac\u0cad\u0cae\u0caf\u0cb0\u0cb1\u0cb2\u0cb3 \u0cb5\u0cb6\u0cb7" - // C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....78.....9..... - + "\u0cb8\u0cb9\u0cbc\u0cbd\u0cbe\u0cbf\u0cc0\u0cc1\u0cc2\u0cc3\u0cc4 \u0cc6\u0cc7" - // A.....BC.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... - + "\u0cc8 \u0cca\u0ccb\u0ccc\u0ccd\u0cd5abcdefghijklmnopqrstuvwxyz\u0cd6\u0ce0\u0ce1" - // E.....F..... - + "\u0ce2\u0ce3", + // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F..... + + "\u0c92\u0c93\u0c94\u0c95\u0c96\u0c97\u0c98\u0c99\u0c9a\uffff\u0c9b\u0c9c\u0c9d\u0c9e" + // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC + + " !\u0c9f\u0ca0\u0ca1\u0ca2\u0ca3\u0ca4)(\u0ca5\u0ca6,\u0ca7.\u0ca80123456789:; " + // D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B..... + + "\u0caa\u0cab?\u0cac\u0cad\u0cae\u0caf\u0cb0\u0cb1\u0cb2\u0cb3 \u0cb5\u0cb6\u0cb7" + // C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....78.....9..... + + "\u0cb8\u0cb9\u0cbc\u0cbd\u0cbe\u0cbf\u0cc0\u0cc1\u0cc2\u0cc3\u0cc4 \u0cc6\u0cc7" + // A.....BC.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... + + "\u0cc8" + + " \u0cca\u0ccb\u0ccc\u0ccd\u0cd5abcdefghijklmnopqrstuvwxyz\u0cd6\u0ce0\u0ce1" + // E.....F..... + + "\u0ce2\u0ce3", /* A.3.8 Malayalam National Language Locking Shift Table - 01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....1 */ + 01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....1 */ " \u0d02\u0d03\u0d05\u0d06\u0d07\u0d08\u0d09\u0d0a\u0d0b\n\u0d0c \r\u0d0e\u0d0f\u0d10 " - // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F..... - + "\u0d12\u0d13\u0d14\u0d15\u0d16\u0d17\u0d18\u0d19\u0d1a\uffff\u0d1b\u0d1c\u0d1d\u0d1e" - // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC - + " !\u0d1f\u0d20\u0d21\u0d22\u0d23\u0d24)(\u0d25\u0d26,\u0d27.\u0d280123456789:; " - // D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A..... - + "\u0d2a\u0d2b?\u0d2c\u0d2d\u0d2e\u0d2f\u0d30\u0d31\u0d32\u0d33\u0d34\u0d35\u0d36" - // B.....C.....D.....EF.....0.....1.....2.....3.....4.....5.....6.....78.....9..... - + "\u0d37\u0d38\u0d39 \u0d3d\u0d3e\u0d3f\u0d40\u0d41\u0d42\u0d43\u0d44 \u0d46\u0d47" - // A.....BC.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... - + "\u0d48 \u0d4a\u0d4b\u0d4c\u0d4d\u0d57abcdefghijklmnopqrstuvwxyz\u0d60\u0d61\u0d62" - // E.....F..... - + "\u0d63\u0d79", + // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F..... + + "\u0d12\u0d13\u0d14\u0d15\u0d16\u0d17\u0d18\u0d19\u0d1a\uffff\u0d1b\u0d1c\u0d1d\u0d1e" + // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC + + " !\u0d1f\u0d20\u0d21\u0d22\u0d23\u0d24)(\u0d25\u0d26,\u0d27.\u0d280123456789:; " + // D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A..... + + "\u0d2a\u0d2b?\u0d2c\u0d2d\u0d2e\u0d2f\u0d30\u0d31\u0d32\u0d33\u0d34\u0d35\u0d36" + // B.....C.....D.....EF.....0.....1.....2.....3.....4.....5.....6.....78.....9..... + + "\u0d37\u0d38\u0d39 \u0d3d\u0d3e\u0d3f\u0d40\u0d41\u0d42\u0d43\u0d44 \u0d46\u0d47" + // A.....BC.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D..... + + "\u0d48" + + " \u0d4a\u0d4b\u0d4c\u0d4d\u0d57abcdefghijklmnopqrstuvwxyz\u0d60\u0d61\u0d62" + // E.....F..... + + "\u0d63\u0d79", /* A.3.9 Oriya National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....0.....12 */ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....0.....12 */ "\u0b01\u0b02\u0b03\u0b05\u0b06\u0b07\u0b08\u0b09\u0b0a\u0b0b\n\u0b0c \r \u0b0f\u0b10 " - // 3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....01 - + "\u0b13\u0b14\u0b15\u0b16\u0b17\u0b18\u0b19\u0b1a\uffff\u0b1b\u0b1c\u0b1d\u0b1e !" - // 2.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABCD..... - + "\u0b1f\u0b20\u0b21\u0b22\u0b23\u0b24)(\u0b25\u0b26,\u0b27.\u0b280123456789:; \u0b2a" - // E.....F0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C.....D..... - + "\u0b2b?\u0b2c\u0b2d\u0b2e\u0b2f\u0b30 \u0b32\u0b33 \u0b35\u0b36\u0b37\u0b38\u0b39" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E..... - + "\u0b3c\u0b3d\u0b3e\u0b3f\u0b40\u0b41\u0b42\u0b43\u0b44 \u0b47\u0b48 \u0b4b\u0b4c" - // F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F..... - + "\u0b4d\u0b56abcdefghijklmnopqrstuvwxyz\u0b57\u0b60\u0b61\u0b62\u0b63", + // 3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....01 + + "\u0b13\u0b14\u0b15\u0b16\u0b17\u0b18\u0b19\u0b1a\uffff\u0b1b\u0b1c\u0b1d\u0b1e !" + // 2.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABCD..... + + "\u0b1f\u0b20\u0b21\u0b22\u0b23\u0b24)(\u0b25\u0b26,\u0b27.\u0b280123456789:;" + + " \u0b2a" + // E.....F0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C.....D..... + + "\u0b2b?\u0b2c\u0b2d\u0b2e\u0b2f\u0b30 \u0b32\u0b33" + + " \u0b35\u0b36\u0b37\u0b38\u0b39" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E..... + + "\u0b3c\u0b3d\u0b3e\u0b3f\u0b40\u0b41\u0b42\u0b43\u0b44 \u0b47\u0b48 " + + " \u0b4b\u0b4c" + // F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F..... + + "\u0b4d\u0b56abcdefghijklmnopqrstuvwxyz\u0b57\u0b60\u0b61\u0b62\u0b63", /* A.3.10 Punjabi National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.EF.....0.....123.....4.....*/ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.EF.....0.....123.....4.....*/ "\u0a01\u0a02\u0a03\u0a05\u0a06\u0a07\u0a08\u0a09\u0a0a \n \r \u0a0f\u0a10 \u0a13\u0a14" - // 5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....012.....3..... - + "\u0a15\u0a16\u0a17\u0a18\u0a19\u0a1a\uffff\u0a1b\u0a1c\u0a1d\u0a1e !\u0a1f\u0a20" - // 4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABCD.....E.....F0..... - + "\u0a21\u0a22\u0a23\u0a24)(\u0a25\u0a26,\u0a27.\u0a280123456789:; \u0a2a\u0a2b?\u0a2c" - // 1.....2.....3.....4.....56.....7.....89.....A.....BC.....D.....E.....F0.....1..... - + "\u0a2d\u0a2e\u0a2f\u0a30 \u0a32\u0a33 \u0a35\u0a36 \u0a38\u0a39\u0a3c \u0a3e\u0a3f" - // 2.....3.....4.....56789.....A.....BCD.....E.....F.....0.....123456789ABCDEF012345678 - + "\u0a40\u0a41\u0a42 \u0a47\u0a48 \u0a4b\u0a4c\u0a4d\u0a51abcdefghijklmnopqrstuvwx" - // 9AB.....C.....D.....E.....F..... - + "yz\u0a70\u0a71\u0a72\u0a73\u0a74", + // 5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....012.....3..... + + "\u0a15\u0a16\u0a17\u0a18\u0a19\u0a1a\uffff\u0a1b\u0a1c\u0a1d\u0a1e !\u0a1f\u0a20" + // 4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABCD.....E.....F0..... + + "\u0a21\u0a22\u0a23\u0a24)(\u0a25\u0a26,\u0a27.\u0a280123456789:;" + + " \u0a2a\u0a2b?\u0a2c" + // 1.....2.....3.....4.....56.....7.....89.....A.....BC.....D.....E.....F0.....1..... + + "\u0a2d\u0a2e\u0a2f\u0a30 \u0a32\u0a33 \u0a35\u0a36 \u0a38\u0a39\u0a3c" + + " \u0a3e\u0a3f" + // 2.....3.....4.....56789.....A.....BCD.....E.....F.....0.....123456789ABCDEF012345678 + + "\u0a40\u0a41\u0a42 \u0a47\u0a48 " + + " \u0a4b\u0a4c\u0a4d\u0a51abcdefghijklmnopqrstuvwx" + // 9AB.....C.....D.....E.....F..... + + "yz\u0a70\u0a71\u0a72\u0a73\u0a74", /* A.3.11 Tamil National Language Locking Shift Table - 01.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.E.....F.....0.....12.....3..... */ + 01.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.E.....F.....0.....12.....3..... */ " \u0b82\u0b83\u0b85\u0b86\u0b87\u0b88\u0b89\u0b8a \n \r\u0b8e\u0b8f\u0b90 \u0b92\u0b93" - // 4.....5.....6789.....A.....B.....CD.....EF.....012.....3456.....7.....89ABCDEF..... - + "\u0b94\u0b95 \u0b99\u0b9a\uffff \u0b9c \u0b9e !\u0b9f \u0ba3\u0ba4)( , .\u0ba8" - // 0123456789ABC.....D.....EF012.....3.....4.....5.....6.....7.....8.....9.....A..... - + "0123456789:;\u0ba9\u0baa ? \u0bae\u0baf\u0bb0\u0bb1\u0bb2\u0bb3\u0bb4\u0bb5\u0bb6" - // B.....C.....D.....EF0.....1.....2.....3.....4.....5678.....9.....A.....BC.....D..... - + "\u0bb7\u0bb8\u0bb9 \u0bbe\u0bbf\u0bc0\u0bc1\u0bc2 \u0bc6\u0bc7\u0bc8 \u0bca\u0bcb" - // E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F..... - + "\u0bcc\u0bcd\u0bd0abcdefghijklmnopqrstuvwxyz\u0bd7\u0bf0\u0bf1\u0bf2\u0bf9", + // 4.....5.....6789.....A.....B.....CD.....EF.....012.....3456.....7.....89ABCDEF..... + + "\u0b94\u0b95 \u0b99\u0b9a\uffff \u0b9c \u0b9e !\u0b9f \u0ba3\u0ba4)( ," + + " .\u0ba8" + // 0123456789ABC.....D.....EF012.....3.....4.....5.....6.....7.....8.....9.....A..... + + "0123456789:;\u0ba9\u0baa ? " + + " \u0bae\u0baf\u0bb0\u0bb1\u0bb2\u0bb3\u0bb4\u0bb5\u0bb6" + // B.....C.....D.....EF0.....1.....2.....3.....4.....5678.....9.....A.....BC.....D..... + + "\u0bb7\u0bb8\u0bb9 \u0bbe\u0bbf\u0bc0\u0bc1\u0bc2 \u0bc6\u0bc7\u0bc8" + + " \u0bca\u0bcb" + // E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F..... + + "\u0bcc\u0bcd\u0bd0abcdefghijklmnopqrstuvwxyz\u0bd7\u0bf0\u0bf1\u0bf2\u0bf9", /* A.3.12 Telugu National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....*/ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....*/ "\u0c01\u0c02\u0c03\u0c05\u0c06\u0c07\u0c08\u0c09\u0c0a\u0c0b\n\u0c0c \r\u0c0e\u0c0f\u0c10" - // 12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... - + " \u0c12\u0c13\u0c14\u0c15\u0c16\u0c17\u0c18\u0c19\u0c1a\uffff\u0c1b\u0c1c\u0c1d" - // F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789AB - + "\u0c1e !\u0c1f\u0c20\u0c21\u0c22\u0c23\u0c24)(\u0c25\u0c26,\u0c27.\u0c280123456789:;" - // CD.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B..... - + " \u0c2a\u0c2b?\u0c2c\u0c2d\u0c2e\u0c2f\u0c30\u0c31\u0c32\u0c33 \u0c35\u0c36\u0c37" - // C.....D.....EF.....0.....1.....2.....3.....4.....5.....6.....78.....9.....A.....B - + "\u0c38\u0c39 \u0c3d\u0c3e\u0c3f\u0c40\u0c41\u0c42\u0c43\u0c44 \u0c46\u0c47\u0c48 " - // C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E..... - + "\u0c4a\u0c4b\u0c4c\u0c4d\u0c55abcdefghijklmnopqrstuvwxyz\u0c56\u0c60\u0c61\u0c62" - // F..... - + "\u0c63", + // 12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E..... + + " \u0c12\u0c13\u0c14\u0c15\u0c16\u0c17\u0c18\u0c19\u0c1a\uffff\u0c1b\u0c1c\u0c1d" + // F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789AB + + "\u0c1e" + + " !\u0c1f\u0c20\u0c21\u0c22\u0c23\u0c24)(\u0c25\u0c26,\u0c27.\u0c280123456789:;" + // CD.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B..... + + " \u0c2a\u0c2b?\u0c2c\u0c2d\u0c2e\u0c2f\u0c30\u0c31\u0c32\u0c33" + + " \u0c35\u0c36\u0c37" + // C.....D.....EF.....0.....1.....2.....3.....4.....5.....6.....78.....9.....A.....B + + "\u0c38\u0c39 \u0c3d\u0c3e\u0c3f\u0c40\u0c41\u0c42\u0c43\u0c44 \u0c46\u0c47\u0c48" + + " " + // C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E..... + + "\u0c4a\u0c4b\u0c4c\u0c4d\u0c55abcdefghijklmnopqrstuvwxyz\u0c56\u0c60\u0c61\u0c62" + // F..... + + "\u0c63", /* A.3.13 Urdu National Language Locking Shift Table - 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....*/ + 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....*/ "\u0627\u0622\u0628\u067b\u0680\u067e\u06a6\u062a\u06c2\u067f\n\u0679\u067d\r\u067a\u067c" - // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D..... - + "\u062b\u062c\u0681\u0684\u0683\u0685\u0686\u0687\u062d\u062e\u062f\uffff\u068c\u0688" - // E.....F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....012345 - + "\u0689\u068a !\u068f\u068d\u0630\u0631\u0691\u0693)(\u0699\u0632,\u0696.\u0698012345" - // 6789ABC.....D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8..... - + "6789:;\u069a\u0633\u0634?\u0635\u0636\u0637\u0638\u0639\u0641\u0642\u06a9\u06aa" - // 9.....A.....B.....C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6..... - + "\u06ab\u06af\u06b3\u06b1\u0644\u0645\u0646\u06ba\u06bb\u06bc\u0648\u06c4\u06d5\u06c1" - // 7.....8.....9.....A.....B.....C.....D.....E.....F.....0.....123456789ABCDEF012345678 - + "\u06be\u0621\u06cc\u06d0\u06d2\u064d\u0650\u064f\u0657\u0654abcdefghijklmnopqrstuvwx" - // 9AB.....C.....D.....E.....F..... - + "yz\u0655\u0651\u0653\u0656\u0670" + // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D..... + + "\u062b\u062c\u0681\u0684\u0683\u0685\u0686\u0687\u062d\u062e\u062f\uffff\u068c\u0688" + // E.....F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....012345 + + "\u0689\u068a" + + " !\u068f\u068d\u0630\u0631\u0691\u0693)(\u0699\u0632,\u0696.\u0698012345" + // 6789ABC.....D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8..... + + "6789:;\u069a\u0633\u0634?\u0635\u0636\u0637\u0638\u0639\u0641\u0642\u06a9\u06aa" + // 9.....A.....B.....C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6..... + + "\u06ab\u06af\u06b3\u06b1\u0644\u0645\u0646\u06ba\u06bb\u06bc\u0648\u06c4\u06d5\u06c1" + // 7.....8.....9.....A.....B.....C.....D.....E.....F.....0.....123456789ABCDEF012345678 + + "\u06be\u0621\u06cc\u06d0\u06d2\u064d\u0650\u064f\u0657\u0654abcdefghijklmnopqrstuvwx" + // 9AB.....C.....D.....E.....F..... + + "yz\u0655\u0651\u0653\u0656\u0670" }; - /** - * GSM default extension table plus national language single shift character tables. - */ - private static final String[] sLanguageShiftTables = new String[]{ - /* 6.2.1.1 GSM 7 bit Default Alphabet Extension Table - 0123456789A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF0123456789ABCDEF */ - " \u000c ^ {} \\ [~] | " - // 0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF - + " \u20ac ", - - /* A.2.1 Turkish National Language Single Shift Table - 0123456789A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF01234567.....8 */ - " \u000c ^ {} \\ [~] | \u011e " - // 9.....ABCDEF0123.....456789ABCDEF0123.....45.....67.....89.....ABCDEF0123..... - + "\u0130 \u015e \u00e7 \u20ac \u011f \u0131 \u015f" - // 456789ABCDEF - + " ", - - /* A.2.2 Spanish National Language Single Shift Table - 0123456789.....A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF01.....23 */ - " \u00e7\u000c ^ {} \\ [~] |\u00c1 " - // 456789.....ABCDEF.....012345.....6789ABCDEF01.....2345.....6789.....ABCDEF.....012 - + " \u00cd \u00d3 \u00da \u00e1 \u20ac \u00ed \u00f3 " - // 345.....6789ABCDEF - + " \u00fa ", - - /* A.2.3 Portuguese National Language Single Shift Table - 012345.....6789.....A.....B.....C.....DE.....F.....012.....3.....45.....6.....7.....8....*/ - " \u00ea \u00e7\u000c\u00d4\u00f4 \u00c1\u00e1 \u03a6\u0393^\u03a9\u03a0\u03a8\u03a3" - // 9.....ABCDEF.....0123456789ABCDEF.0123456789ABCDEF01.....23456789.....ABCDE - + "\u0398 \u00ca {} \\ [~] |\u00c0 \u00cd " - // F.....012345.....6789AB.....C.....DEF01.....2345.....6789.....ABCDEF.....01234 - + "\u00d3 \u00da \u00c3\u00d5 \u00c2 \u20ac \u00ed \u00f3 " - // 5.....6789AB.....C.....DEF..... - + "\u00fa \u00e3\u00f5 \u00e2", - - /* A.2.4 Bengali National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u09e6\u09e7 \u09e8\u09e9" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... - + "\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09df\u09e0\u09e1\u09e2{}\u09e3\u09f2\u09f3" - // D.....E.....F.0.....1.....2.....3.....4.....56789ABCDEF0123456789ABCDEF - + "\u09f4\u09f5\\\u09f6\u09f7\u09f8\u09f9\u09fa [~] |ABCDEFGHIJKLMNO" - // 0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF - + "PQRSTUVWXYZ \u20ac ", - - /* A.2.5 Gujarati National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0ae6\u0ae7" - // E.....F.....0.....1.....2.....3.....4.....5.....6789ABCDEF.0123456789ABCDEF - + "\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef {} \\ [~] " - // 0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF - + "|ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac ", - - /* A.2.6 Hindi National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0966\u0967" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... - + "\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0951\u0952{}\u0953\u0954\u0958" - // D.....E.....F.0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A..... - + "\u0959\u095a\\\u095b\u095c\u095d\u095e\u095f\u0960\u0961\u0962\u0963\u0970\u0971" - // BCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF - + " [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac ", - - /* A.2.7 Kannada National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0ce6\u0ce7" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....BCDEF.01234567 - + "\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0cde\u0cf1{}\u0cf2 \\ " - // 89ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF - + " [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac ", - - /* A.2.8 Malayalam National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0d66\u0d67" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... - + "\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0d70\u0d71{}\u0d72\u0d73\u0d74" - // D.....E.....F.0.....1.....2.....3.....4.....56789ABCDEF0123456789ABCDEF0123456789A - + "\u0d75\u0d7a\\\u0d7b\u0d7c\u0d7d\u0d7e\u0d7f [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ" - // BCDEF012345.....6789ABCDEF0123456789ABCDEF - + " \u20ac ", - - /* A.2.9 Oriya National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0b66\u0b67" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....DE - + "\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0b5c\u0b5d{}\u0b5f\u0b70\u0b71 " - // F.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789A - + "\\ [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " - // BCDEF - + " ", - - /* A.2.10 Punjabi National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0a66\u0a67" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... - + "\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a59\u0a5a{}\u0a5b\u0a5c\u0a5e" - // D.....EF.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF01 - + "\u0a75 \\ [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " - // 23456789ABCDEF - + " ", - - /* A.2.11 Tamil National Language Single Shift Table - NOTE: TS 23.038 V9.1.1 shows code 0x24 as \u0bef, corrected to \u0bee (typo) - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0be6\u0be7" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... - + "\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0bf3\u0bf4{}\u0bf5\u0bf6\u0bf7" - // D.....E.....F.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABC - + "\u0bf8\u0bfa\\ [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " - // DEF0123456789ABCDEF - + " ", - - /* A.2.12 Telugu National Language Single Shift Table - NOTE: TS 23.038 V9.1.1 shows code 0x22-0x23 as \u06cc\u06cd, corrected to \u0c6c\u0c6d - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789ABC.....D.....E.....F..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#* \u0c66\u0c67\u0c68\u0c69" - // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F. - + "\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0c58\u0c59{}\u0c78\u0c79\u0c7a\u0c7b\u0c7c\\" - // 0.....1.....2.....3456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCD - + "\u0c7d\u0c7e\u0c7f [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " - // EF0123456789ABCDEF - + " ", - - /* A.2.13 Urdu National Language Single Shift Table - 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ - "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0600\u0601 \u06f0\u06f1" - // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... - + "\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u060d{}\u060e\u060f\u0610" - // D.....E.....F.0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A..... - + "\u0611\u0612\\\u0613\u0614\u061b\u061f\u0640\u0652\u0658\u066b\u066c\u0672\u0673" - // B.....CDEF.....0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF - + "\u06cd[~]\u06d4|ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " - }; + /** GSM default extension table plus national language single shift character tables. */ + private static final String[] sLanguageShiftTables = + new String[] { + /* 6.2.1.1 GSM 7 bit Default Alphabet Extension Table + 0123456789A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF0123456789ABCDEF */ + " \u000c ^ {} \\ [~] | " + + " " + // 0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF + + " \u20ac ", + + /* A.2.1 Turkish National Language Single Shift Table + 0123456789A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF01234567.....8 */ + " \u000c ^ {} \\ [~] | " + + " \u011e " + // 9.....ABCDEF0123.....456789ABCDEF0123.....45.....67.....89.....ABCDEF0123..... + + "\u0130 \u015e \u00e7 \u20ac \u011f \u0131 " + + " \u015f" + // 456789ABCDEF + + " ", + + /* A.2.2 Spanish National Language Single Shift Table + 0123456789.....A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF01.....23 */ + " \u00e7\u000c ^ {} \\ [~] |\u00c1" + + " " + // 456789.....ABCDEF.....012345.....6789ABCDEF01.....2345.....6789.....ABCDEF.....012 + + " \u00cd \u00d3 \u00da \u00e1 \u20ac \u00ed " + + " \u00f3 " + // 345.....6789ABCDEF + + " \u00fa ", + + /* A.2.3 Portuguese National Language Single Shift Table + 012345.....6789.....A.....B.....C.....DE.....F.....012.....3.....45.....6.....7.....8....*/ + " \u00ea \u00e7\u000c\u00d4\u00f4 \u00c1\u00e1 " + + " \u03a6\u0393^\u03a9\u03a0\u03a8\u03a3" + // 9.....ABCDEF.....0123456789ABCDEF.0123456789ABCDEF01.....23456789.....ABCDE + + "\u0398 \u00ca {} \\ [~] |\u00c0 \u00cd " + + " " + // F.....012345.....6789AB.....C.....DEF01.....2345.....6789.....ABCDEF.....01234 + + "\u00d3 \u00da \u00c3\u00d5 \u00c2 \u20ac \u00ed " + + " \u00f3 " + // 5.....6789AB.....C.....DEF..... + + "\u00fa \u00e3\u00f5 \u00e2", + + /* A.2.4 Bengali National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u09e6\u09e7" + + " \u09e8\u09e9" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... + + "\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09df\u09e0\u09e1\u09e2{}\u09e3\u09f2\u09f3" + // D.....E.....F.0.....1.....2.....3.....4.....56789ABCDEF0123456789ABCDEF + + "\u09f4\u09f5\\\u09f6\u09f7\u09f8\u09f9\u09fa [~] |ABCDEFGHIJKLMNO" + // 0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF + + "PQRSTUVWXYZ \u20ac ", + + /* A.2.5 Gujarati National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0ae6\u0ae7" + // E.....F.....0.....1.....2.....3.....4.....5.....6789ABCDEF.0123456789ABCDEF + + "\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef {} \\ " + + " [~] " + // 0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF + + "|ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac ", + + /* A.2.6 Hindi National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0966\u0967" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... + + "\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0951\u0952{}\u0953\u0954\u0958" + // D.....E.....F.0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A..... + + "\u0959\u095a\\\u095b\u095c\u095d\u095e\u095f\u0960\u0961\u0962\u0963\u0970\u0971" + // BCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF + + " [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " + + " ", + + /* A.2.7 Kannada National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0ce6\u0ce7" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....BCDEF.01234567 + + "\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0cde\u0cf1{}\u0cf2 " + + " \\ " + // 89ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF + + " [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " + + " ", + + /* A.2.8 Malayalam National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0d66\u0d67" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... + + "\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0d70\u0d71{}\u0d72\u0d73\u0d74" + // D.....E.....F.0.....1.....2.....3.....4.....56789ABCDEF0123456789ABCDEF0123456789A + + "\u0d75\u0d7a\\\u0d7b\u0d7c\u0d7d\u0d7e\u0d7f [~]" + + " |ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // BCDEF012345.....6789ABCDEF0123456789ABCDEF + + " \u20ac ", + + /* A.2.9 Oriya National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0b66\u0b67" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....DE + + "\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0b5c\u0b5d{}\u0b5f\u0b70\u0b71" + + " " + // F.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789A + + "\\ [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " + + " " + // BCDEF + + " ", + + /* A.2.10 Punjabi National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0a66\u0a67" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... + + "\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a59\u0a5a{}\u0a5b\u0a5c\u0a5e" + // D.....EF.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF01 + + "\u0a75 \\ [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " + + " " + // 23456789ABCDEF + + " ", + + /* A.2.11 Tamil National Language Single Shift Table + NOTE: TS 23.038 V9.1.1 shows code 0x24 as \u0bef, corrected to \u0bee (typo) + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965" + + " \u0be6\u0be7" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... + + "\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0bf3\u0bf4{}\u0bf5\u0bf6\u0bf7" + // D.....E.....F.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABC + + "\u0bf8\u0bfa\\ [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + " \u20ac " + // DEF0123456789ABCDEF + + " ", + + /* A.2.12 Telugu National Language Single Shift Table + NOTE: TS 23.038 V9.1.1 shows code 0x22-0x23 as \u06cc\u06cd, corrected to \u0c6c\u0c6d + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789ABC.....D.....E.....F..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#* " + + " \u0c66\u0c67\u0c68\u0c69" + // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F. + + "\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0c58\u0c59{}\u0c78\u0c79\u0c7a\u0c7b\u0c7c\\" + // 0.....1.....2.....3456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCD + + "\u0c7d\u0c7e\u0c7f [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + " \u20ac " + // EF0123456789ABCDEF + + " ", + + /* A.2.13 Urdu National Language Single Shift Table + 01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */ + "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0600\u0601" + + " \u06f0\u06f1" + // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C..... + + "\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u060d{}\u060e\u060f\u0610" + // D.....E.....F.0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A..... + + "\u0611\u0612\\\u0613\u0614\u061b\u061f\u0640\u0652\u0658\u066b\u066c\u0672\u0673" + // B.....CDEF.....0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF + + "\u06cd[~]\u06d4|ABCDEFGHIJKLMNOPQRSTUVWXYZ \u20ac " + + " " + }; static { int numTables = sLanguageTables.length; int numShiftTables = sLanguageShiftTables.length; if (numTables != numShiftTables) { - Log.e(TAG, "Error: language tables array length " + numTables - + " != shift tables array length " + numShiftTables); + Log.e( + TAG, + "Error: language tables array length " + + numTables + + " != shift tables array length " + + numShiftTables); } sCharsToGsmTables = new SparseIntArray[numTables]; @@ -653,8 +702,13 @@ public class GsmAlphabet { int tableLen = table.length(); if (tableLen != 0 && tableLen != 128) { - Log.e(TAG, "Error: language tables index " + i - + " length " + tableLen + " (expected 128 or 0)"); + Log.e( + TAG, + "Error: language tables index " + + i + + " length " + + tableLen + + " (expected 128 or 0)"); } SparseIntArray charToGsmTable = new SparseIntArray(tableLen); @@ -671,8 +725,13 @@ public class GsmAlphabet { int shiftTableLen = shiftTable.length(); if (shiftTableLen != 0 && shiftTableLen != 128) { - Log.e(TAG, "Error: language shift tables index " + i - + " length " + shiftTableLen + " (expected 128 or 0)"); + Log.e( + TAG, + "Error: language shift tables index " + + i + + " length " + + shiftTableLen + + " (expected 128 or 0)"); } SparseIntArray charToShiftTable = new SparseIntArray(shiftTableLen); diff --git a/android/app/src/com/android/bluetooth/util/NumberUtils.java b/android/app/src/com/android/bluetooth/util/NumberUtils.java index 1d27456601a..0884b7c411b 100644 --- a/android/app/src/com/android/bluetooth/util/NumberUtils.java +++ b/android/app/src/com/android/bluetooth/util/NumberUtils.java @@ -16,21 +16,15 @@ package com.android.bluetooth.util; -/** - * Utility for parsing numbers in Bluetooth. - */ +/** Utility for parsing numbers in Bluetooth. */ public class NumberUtils { - /** - * Convert a byte to unsigned int. - */ + /** Convert a byte to unsigned int. */ public static int unsignedByteToInt(byte b) { return b & 0xFF; } - /** - * Convert a little endian byte array to integer. - */ + /** Convert a little endian byte array to integer. */ public static int littleEndianByteArrayToInt(byte[] bytes) { int length = bytes.length; if (length == 0) { diff --git a/android/app/src/com/android/bluetooth/util/WorkSourceUtil.java b/android/app/src/com/android/bluetooth/util/WorkSourceUtil.java index c25f55ea0d8..6ded2e64512 100644 --- a/android/app/src/com/android/bluetooth/util/WorkSourceUtil.java +++ b/android/app/src/com/android/bluetooth/util/WorkSourceUtil.java @@ -21,9 +21,7 @@ import android.os.WorkSource; import java.util.ArrayList; import java.util.List; -/** - * Class for general helper methods for WorkSource operations. - */ +/** Class for general helper methods for WorkSource operations. */ public class WorkSourceUtil { private final int[] mUids; private final String[] mTags; diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java index 818d18d5197..4f69e5edc61 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java @@ -41,9 +41,7 @@ public class VolumeControlNativeInterface { } } - /** - * Get singleton instance. - */ + /** Get singleton instance. */ public static VolumeControlNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { @@ -64,16 +62,14 @@ public class VolumeControlNativeInterface { /** * Initializes the native interface. * - * priorities to configure. + *

priorities to configure. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { initNative(); } - /** - * Cleanup the native interface. - */ + /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { cleanupNative(); @@ -103,6 +99,7 @@ public class VolumeControlNativeInterface { /** * Sets the VolumeControl volume + * * @param device * @param volume */ @@ -113,6 +110,7 @@ public class VolumeControlNativeInterface { /** * Sets the VolumeControl volume for the group + * * @param groupId * @param volume */ @@ -121,8 +119,9 @@ public class VolumeControlNativeInterface { setGroupVolumeNative(groupId, volume); } - /** + /** * Mute the VolumeControl volume + * * @param device * @param unmute */ @@ -133,6 +132,7 @@ public class VolumeControlNativeInterface { /** * Mute the VolumeControl volume in the group + * * @param groupId * @param unmute */ @@ -141,16 +141,15 @@ public class VolumeControlNativeInterface { muteGroupNative(groupId); } - /** - * Unmute the VolumeControl volume - */ + /** Unmute the VolumeControl volume */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void unmute(BluetoothDevice device) { unmuteNative(getByteAddress(device)); } - /** + /** * Unmute the VolumeControl volume group + * * @param groupId * @param unmute */ @@ -180,8 +179,8 @@ public class VolumeControlNativeInterface { * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public boolean setExtAudioOutVolumeOffset(BluetoothDevice device, int externalOutputId, - int offset) { + public boolean setExtAudioOutVolumeOffset( + BluetoothDevice device, int externalOutputId, int offset) { if (Utils.isPtsTestMode()) { setVolumeNative(getByteAddress(device), offset); return true; @@ -210,8 +209,8 @@ public class VolumeControlNativeInterface { * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public boolean setExtAudioOutLocation(BluetoothDevice device, int externalOutputId, - int location) { + public boolean setExtAudioOutLocation( + BluetoothDevice device, int externalOutputId, int location) { return setExtAudioOutLocationNative(getByteAddress(device), externalOutputId, location); } @@ -236,8 +235,8 @@ public class VolumeControlNativeInterface { * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public boolean setExtAudioOutDescription(BluetoothDevice device, int externalOutputId, - String descr) { + public boolean setExtAudioOutDescription( + BluetoothDevice device, int externalOutputId, String descr) { return setExtAudioOutDescriptionNative(getByteAddress(device), externalOutputId, descr); } @@ -277,8 +276,7 @@ public class VolumeControlNativeInterface { } @VisibleForTesting - void onVolumeStateChanged(int volume, boolean mute, byte[] address, - boolean isAutonomous) { + void onVolumeStateChanged(int volume, boolean mute, byte[] address, boolean isAutonomous) { VolumeControlStackEvent event = new VolumeControlStackEvent( VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED); @@ -293,8 +291,7 @@ public class VolumeControlNativeInterface { } @VisibleForTesting - void onGroupVolumeStateChanged(int volume, boolean mute, int groupId, - boolean isAutonomous) { + void onGroupVolumeStateChanged(int volume, boolean mute, int groupId, boolean isAutonomous) { VolumeControlStackEvent event = new VolumeControlStackEvent( VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED); @@ -309,11 +306,9 @@ public class VolumeControlNativeInterface { } @VisibleForTesting - void onDeviceAvailable(int numOfExternalOutputs, - byte[] address) { + void onDeviceAvailable(int numOfExternalOutputs, byte[] address) { VolumeControlStackEvent event = - new VolumeControlStackEvent( - VolumeControlStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + new VolumeControlStackEvent(VolumeControlStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); event.device = getDevice(address); event.valueInt1 = numOfExternalOutputs; @@ -322,11 +317,10 @@ public class VolumeControlNativeInterface { } @VisibleForTesting - void onExtAudioOutVolumeOffsetChanged(int externalOutputId, int offset, - byte[] address) { + void onExtAudioOutVolumeOffsetChanged(int externalOutputId, int offset, byte[] address) { VolumeControlStackEvent event = new VolumeControlStackEvent( - VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED); + VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED); event.device = getDevice(address); event.valueInt1 = externalOutputId; event.valueInt2 = offset; @@ -336,11 +330,10 @@ public class VolumeControlNativeInterface { } @VisibleForTesting - void onExtAudioOutLocationChanged(int externalOutputId, int location, - byte[] address) { + void onExtAudioOutLocationChanged(int externalOutputId, int location, byte[] address) { VolumeControlStackEvent event = new VolumeControlStackEvent( - VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED); + VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED); event.device = getDevice(address); event.valueInt1 = externalOutputId; event.valueInt2 = location; @@ -350,11 +343,10 @@ public class VolumeControlNativeInterface { } @VisibleForTesting - void onExtAudioOutDescriptionChanged(int externalOutputId, String descr, - byte[] address) { + void onExtAudioOutDescriptionChanged(int externalOutputId, String descr, byte[] address) { VolumeControlStackEvent event = new VolumeControlStackEvent( - VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED); + VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED); event.device = getDevice(address); event.valueInt1 = externalOutputId; event.valueString1 = descr; @@ -365,22 +357,37 @@ public class VolumeControlNativeInterface { // Native methods that call into the JNI interface private native void initNative(); + private native void cleanupNative(); + private native boolean connectVolumeControlNative(byte[] address); + private native boolean disconnectVolumeControlNative(byte[] address); + private native void setVolumeNative(byte[] address, int volume); + private native void setGroupVolumeNative(int groupId, int volume); + private native void muteNative(byte[] address); + private native void muteGroupNative(int groupId); + private native void unmuteNative(byte[] address); + private native void unmuteGroupNative(int groupId); + private native boolean getExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId); - private native boolean setExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId, - int offset); + + private native boolean setExtAudioOutVolumeOffsetNative( + byte[] address, int externalOutputId, int offset); + private native boolean getExtAudioOutLocationNative(byte[] address, int externalOutputId); - private native boolean setExtAudioOutLocationNative(byte[] address, int externalOutputId, - int location); + + private native boolean setExtAudioOutLocationNative( + byte[] address, int externalOutputId, int location); + private native boolean getExtAudioOutDescriptionNative(byte[] address, int externalOutputId); - private native boolean setExtAudioOutDescriptionNative(byte[] address, int externalOutputId, - String descr); + + private native boolean setExtAudioOutDescriptionNative( + byte[] address, int externalOutputId, String descr); } diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java index 4e4378ac0f5..172d3f094f8 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java @@ -97,10 +97,12 @@ public class VolumeControlService extends ProfileService { mLocation = 0; mDescription = null; } + int mValue; int mLocation; String mDescription; - }; + } + ; VolumeControlOffsetDescriptor() { mVolumeOffsets = new HashMap<>(); @@ -189,18 +191,16 @@ public class VolumeControlService extends ProfileService { } VolumeControlNativeInterface mVolumeControlNativeInterface; - @VisibleForTesting - AudioManager mAudioManager; + @VisibleForTesting AudioManager mAudioManager; private final Map mStateMachines = new HashMap<>(); private final Map mAudioOffsets = - new HashMap<>(); + new HashMap<>(); private final Map mGroupVolumeCache = new HashMap<>(); private final Map mGroupMuteCache = new HashMap<>(); private final Map mDeviceVolumeCache = new HashMap<>(); - @VisibleForTesting - ServiceFactory mFactory = new ServiceFactory(); + @VisibleForTesting ServiceFactory mFactory = new ServiceFactory(); public VolumeControlService(Context ctx) { super(ctx); @@ -224,16 +224,22 @@ public class VolumeControlService extends ProfileService { // Get AdapterService, VolumeControlNativeInterface, DatabaseManager, AudioManager. // None of them can be null. - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when VolumeControlService starts"); - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when VolumeControlService starts"); - mVolumeControlNativeInterface = Objects.requireNonNull( - VolumeControlNativeInterface.getInstance(), - "VolumeControlNativeInterface cannot be null when VolumeControlService starts"); - mAudioManager = getSystemService(AudioManager.class); - Objects.requireNonNull(mAudioManager, - "AudioManager cannot be null when VolumeControlService starts"); + mAdapterService = + Objects.requireNonNull( + AdapterService.getAdapterService(), + "AdapterService cannot be null when VolumeControlService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when VolumeControlService starts"); + mVolumeControlNativeInterface = + Objects.requireNonNull( + VolumeControlNativeInterface.getInstance(), + "VolumeControlNativeInterface cannot be null when VolumeControlService" + + " starts"); + mAudioManager = getSystemService(AudioManager.class); + Objects.requireNonNull( + mAudioManager, "AudioManager cannot be null when VolumeControlService starts"); // Start handler thread for state machines mHandler = new Handler(Looper.getMainLooper()); @@ -317,6 +323,7 @@ public class VolumeControlService extends ProfileService { /** * Get the VolumeControlService instance + * * @return VolumeControlService instance */ public static synchronized VolumeControlService getVolumeControlService() { @@ -340,8 +347,8 @@ public class VolumeControlService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "connect(): " + device); if (device == null) { return false; @@ -352,12 +359,12 @@ public class VolumeControlService extends ProfileService { } ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device); if (!Utils.arrayContains(featureUuids, BluetoothUuid.VOLUME_CONTROL)) { - Log.e(TAG, "Cannot connect to " + device - + " : Remote does not have Volume Control UUID"); + Log.e( + TAG, + "Cannot connect to " + device + " : Remote does not have Volume Control UUID"); return false; } - synchronized (mStateMachines) { VolumeControlStateMachine smConnect = getOrCreateStateMachine(device); if (smConnect == null) { @@ -371,8 +378,8 @@ public class VolumeControlService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); Log.d(TAG, "disconnect(): " + device); if (device == null) { return false; @@ -400,8 +407,8 @@ public class VolumeControlService extends ProfileService { } /** - * Check whether can connect to a peer device. - * The check considers a number of factors during the evaluation. + * Check whether can connect to a peer device. The check considers a number of factors during + * the evaluation. * * @param device the peer device to connect to * @return true if connection is allowed, otherwise false @@ -437,8 +444,8 @@ public class VolumeControlService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) List getDevicesMatchingConnectionStates(int[] states) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); ArrayList devices = new ArrayList<>(); if (states == null) { return devices; @@ -487,8 +494,7 @@ public class VolumeControlService extends ProfileService { @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, - "Need BLUETOOTH_CONNECT permission"); + enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission"); synchronized (mStateMachines) { VolumeControlStateMachine sm = mStateMachines.get(device); if (sm == null) { @@ -499,15 +505,14 @@ public class VolumeControlService extends ProfileService { } /** - * Set connection policy of the profile and connects it if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} + * Set connection policy of the profile and connects it if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN} * - *

The device should already be paired. - * Connection policy can be one of: - * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, - * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, - * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + *

The device should already be paired. Connection policy can be one of: {@link + * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link + * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link + * BluetoothProfile#CONNECTION_POLICY_UNKNOWN} * * @param device the remote device * @param connectionPolicy is the connection policy to set to for this profile @@ -515,8 +520,8 @@ public class VolumeControlService extends ProfileService { */ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); - mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.VOLUME_CONTROL, - connectionPolicy); + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.VOLUME_CONTROL, connectionPolicy); if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { connect(device); } else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { @@ -587,12 +592,7 @@ public class VolumeControlService extends ProfileService { } Log.d( TAG, - "setDeviceVolume: " - + device - + ", volume: " - + volume - + ", isGroupOp: " - + isGroupOp); + "setDeviceVolume: " + device + ", volume: " + volume + ", isGroupOp: " + isGroupOp); LeAudioService leAudioService = mFactory.getLeAudioService(); if (leAudioService == null) { @@ -636,9 +636,14 @@ public class VolumeControlService extends ProfileService { * have to explicitly unmute the remote device. */ if (!isGroupMute.equals(isStreamMute)) { - Log.w(TAG, "Mute state mismatch, stream mute: " + isStreamMute - + ", device group mute: " + isGroupMute - + ", new volume: " + volume); + Log.w( + TAG, + "Mute state mismatch, stream mute: " + + isStreamMute + + ", device group mute: " + + isGroupMute + + ", new volume: " + + volume); if (isStreamMute) { Log.i(TAG, "Mute the group " + groupId); muteGroup(groupId); @@ -651,8 +656,8 @@ public class VolumeControlService extends ProfileService { } public int getGroupVolume(int groupId) { - return mGroupVolumeCache.getOrDefault(groupId, - IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME); + return mGroupVolumeCache.getOrDefault( + groupId, IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME); } /** @@ -667,11 +672,10 @@ public class VolumeControlService extends ProfileService { } /** - * This should be called by LeAudioService when LE Audio group change it - * active state. + * This should be called by LeAudioService when LE Audio group change it active state. * - * @param groupId the group identifier - * @param active indicator if group is active or not + * @param groupId the group identifier + * @param active indicator if group is active or not */ public void setGroupActive(int groupId, boolean active) { Log.d(TAG, "setGroupActive: " + groupId + ", active: " + active); @@ -790,15 +794,15 @@ public class VolumeControlService extends ProfileService { synchronized (mStateMachines) { VolumeControlStateMachine sm = mStateMachines.get(device); if (sm != null) { - can_change_volume = - (sm.getConnectionState() == BluetoothProfile.STATE_CONNECTED); + can_change_volume = (sm.getConnectionState() == BluetoothProfile.STATE_CONNECTED); } } // If group volume has already changed, the new group member should set it if (can_change_volume) { - Integer groupVolume = mGroupVolumeCache.getOrDefault(groupId, - IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME); + Integer groupVolume = + mGroupVolumeCache.getOrDefault( + groupId, IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME); if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) { Log.i(TAG, "Setting value:" + groupVolume + " to " + device); mVolumeControlNativeInterface.setVolume(device, groupVolume); @@ -860,8 +864,8 @@ public class VolumeControlService extends ProfileService { } } - void handleVolumeControlChanged(BluetoothDevice device, int groupId, - int volume, boolean mute, boolean isAutonomous) { + void handleVolumeControlChanged( + BluetoothDevice device, int groupId, int volume, boolean mute, boolean isAutonomous) { if (isAutonomous && device != null) { Log.e(TAG, "We expect only group notification for autonomous updates"); @@ -950,8 +954,12 @@ public class VolumeControlService extends ProfileService { } } } else { - Log.e(TAG, "Volume changed did not succeed. Volume: " + volume - + " expected volume: " + groupVolume); + Log.e( + TAG, + "Volume changed did not succeed. Volume: " + + volume + + " expected volume: " + + groupVolume); } } else { /* Received group notification for autonomous change. Update cache and audio system. */ @@ -962,8 +970,11 @@ public class VolumeControlService extends ProfileService { public int getAudioDeviceGroupVolume(int groupId) { int volume = getGroupVolume(groupId); if (getGroupMute(groupId)) { - Log.w(TAG, "Volume level is " + volume - + ", but muted. Will report 0 for the audio device."); + Log.w( + TAG, + "Volume level is " + + volume + + ", but muted. Will report 0 for the audio device."); volume = 0; } @@ -994,7 +1005,7 @@ public class VolumeControlService extends ProfileService { Log.d(TAG, " Update during ringtone applied to voice call"); return AudioManager.STREAM_VOICE_CALL; } - // fall through + // fall through case AudioManager.MODE_NORMAL: default: // other conditions will influence the stream type choice, read on... @@ -1029,7 +1040,7 @@ public class VolumeControlService extends ProfileService { } void handleDeviceExtAudioOffsetChanged(BluetoothDevice device, int id, int value) { - Log.d(TAG, " device: " + device + " offset_id: " + id + " value: " + value); + Log.d(TAG, " device: " + device + " offset_id: " + id + " value: " + value); VolumeControlOffsetDescriptor offsets = mAudioOffsets.get(device); if (offsets == null) { Log.e(TAG, " Offsets not found for device: " + device); @@ -1053,8 +1064,7 @@ public class VolumeControlService extends ProfileService { } void handleDeviceExtAudioLocationChanged(BluetoothDevice device, int id, int location) { - Log.d(TAG, " device: " + device + " offset_id: " - + id + " location: " + location); + Log.d(TAG, " device: " + device + " offset_id: " + id + " location: " + location); VolumeControlOffsetDescriptor offsets = mAudioOffsets.get(device); if (offsets == null) { @@ -1084,8 +1094,7 @@ public class VolumeControlService extends ProfileService { void handleDeviceExtAudioDescriptionChanged( BluetoothDevice device, int id, String description) { - Log.d(TAG, " device: " + device + " offset_id: " - + id + " description: " + description); + Log.d(TAG, " device: " + device + " offset_id: " + id + " description: " + description); VolumeControlOffsetDescriptor offsets = mAudioOffsets.get(device); if (offsets == null) { @@ -1117,20 +1126,24 @@ public class VolumeControlService extends ProfileService { Log.d(TAG, "messageFromNative: " + stackEvent); if (stackEvent.type == VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED) { - handleVolumeControlChanged(stackEvent.device, stackEvent.valueInt1, - stackEvent.valueInt2, stackEvent.valueBool1, - stackEvent.valueBool2); - return; + handleVolumeControlChanged( + stackEvent.device, + stackEvent.valueInt1, + stackEvent.valueInt2, + stackEvent.valueBool1, + stackEvent.valueBool2); + return; } - Objects.requireNonNull(stackEvent.device, - "Device should never be null, event: " + stackEvent); + Objects.requireNonNull( + stackEvent.device, "Device should never be null, event: " + stackEvent); Intent intent = null; if (intent != null) { - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT); return; } @@ -1147,17 +1160,15 @@ public class VolumeControlService extends ProfileService { return; } - if (stackEvent.type - == VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED) { - handleDeviceExtAudioLocationChanged(device, stackEvent.valueInt1, - stackEvent.valueInt2); + if (stackEvent.type == VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED) { + handleDeviceExtAudioLocationChanged(device, stackEvent.valueInt1, stackEvent.valueInt2); return; } if (stackEvent.type == VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED) { - handleDeviceExtAudioDescriptionChanged(device, stackEvent.valueInt1, - stackEvent.valueString1); + handleDeviceExtAudioDescriptionChanged( + device, stackEvent.valueInt1, stackEvent.valueString1); return; } @@ -1196,13 +1207,19 @@ public class VolumeControlService extends ProfileService { } // Limit the maximum number of state machines to avoid DoS attack if (mStateMachines.size() >= MAX_VC_STATE_MACHINES) { - Log.e(TAG, "Maximum number of VolumeControl state machines reached: " - + MAX_VC_STATE_MACHINES); + Log.e( + TAG, + "Maximum number of VolumeControl state machines reached: " + + MAX_VC_STATE_MACHINES); return null; } Log.d(TAG, "Creating a new state machine for " + device); - sm = VolumeControlStateMachine.make(device, this, - mVolumeControlNativeInterface, mStateMachinesThread.getLooper()); + sm = + VolumeControlStateMachine.make( + device, + this, + mVolumeControlNativeInterface, + mStateMachinesThread.getLooper()); mStateMachines.put(device, sm); return sm; } @@ -1305,8 +1322,9 @@ public class VolumeControlService extends ProfileService { synchronized (mStateMachines) { VolumeControlStateMachine sm = mStateMachines.get(device); if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); + Log.w( + TAG, + "removeStateMachine: device " + device + " does not have a state machine"); return; } Log.i(TAG, "removeStateMachine: removing state machine for device: " + device); @@ -1321,16 +1339,21 @@ public class VolumeControlService extends ProfileService { } @VisibleForTesting - synchronized void connectionStateChanged(BluetoothDevice device, int fromState, - int toState) { + synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { if (!isAvailable()) { Log.w(TAG, "connectionStateChanged: service is not available"); return; } if ((device == null) || (fromState == toState)) { - Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device - + " fromState=" + fromState + " toState=" + toState); + Log.e( + TAG, + "connectionStateChanged: unexpected invocation. device=" + + device + + " fromState=" + + fromState + + " toState=" + + toState); return; } @@ -1372,14 +1395,11 @@ public class VolumeControlService extends ProfileService { BluetoothProfile.VOLUME_CONTROL, device, fromState, toState); } - /** - * Binder object: must be a static class or memory leak may occur - */ + /** Binder object: must be a static class or memory leak may occur */ @VisibleForTesting static class BluetoothVolumeControlBinder extends IBluetoothVolumeControl.Stub implements IProfileServiceBinder { - @VisibleForTesting - boolean mIsTesting = false; + @VisibleForTesting boolean mIsTesting = false; private VolumeControlService mService; @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) @@ -1713,7 +1733,7 @@ public class VolumeControlService extends ProfileService { } for (Map.Entry entry : - mAudioOffsets.entrySet()) { + mAudioOffsets.entrySet()) { VolumeControlOffsetDescriptor descriptor = entry.getValue(); BluetoothDevice device = entry.getKey(); ProfileService.println(sb, " Device: " + device); @@ -1722,8 +1742,14 @@ public class VolumeControlService extends ProfileService { } for (Map.Entry entry : mGroupVolumeCache.entrySet()) { Boolean isMute = mGroupMuteCache.getOrDefault(entry.getKey(), false); - ProfileService.println(sb, " GroupId: " + entry.getKey() + " volume: " - + entry.getValue() + ", mute: " + isMute); + ProfileService.println( + sb, + " GroupId: " + + entry.getKey() + + " volume: " + + entry.getValue() + + ", mute: " + + isMute); } } } diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java index 38674532f64..9fae08e3f5f 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java @@ -91,20 +91,20 @@ public class VolumeControlStackEvent { case EVENT_TYPE_CONNECTION_STATE_CHANGED: switch (value) { case CONNECTION_STATE_DISCONNECTED: - return "CONNECTION_STATE_DISCONNECTED"; + return "CONNECTION_STATE_DISCONNECTED"; case CONNECTION_STATE_CONNECTING: - return "CONNECTION_STATE_CONNECTING"; + return "CONNECTION_STATE_CONNECTING"; case CONNECTION_STATE_CONNECTED: - return "CONNECTION_STATE_CONNECTED"; + return "CONNECTION_STATE_CONNECTED"; case CONNECTION_STATE_DISCONNECTING: - return "CONNECTION_STATE_DISCONNECTING"; + return "CONNECTION_STATE_DISCONNECTING"; default: return "UNKNOWN"; } case EVENT_TYPE_VOLUME_STATE_CHANGED: return "{group_id:" + value + "}"; case EVENT_TYPE_DEVICE_AVAILABLE: - return "{num_ext_outputs:" + value + "}"; + return "{num_ext_outputs:" + value + "}"; case EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED: case EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED: case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED: @@ -120,13 +120,13 @@ public class VolumeControlStackEvent { case EVENT_TYPE_CONNECTION_STATE_CHANGED: switch (value) { case CONNECTION_STATE_DISCONNECTED: - return "CONNECTION_STATE_DISCONNECTED"; + return "CONNECTION_STATE_DISCONNECTED"; case CONNECTION_STATE_CONNECTING: - return "CONNECTION_STATE_CONNECTING"; + return "CONNECTION_STATE_CONNECTING"; case CONNECTION_STATE_CONNECTED: - return "CONNECTION_STATE_CONNECTED"; + return "CONNECTION_STATE_CONNECTED"; case CONNECTION_STATE_DISCONNECTING: - return "CONNECTION_STATE_DISCONNECTING"; + return "CONNECTION_STATE_DISCONNECTING"; default: return "UNKNOWN"; } diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java index 1fa26e85803..4a68e8f337f 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java @@ -43,14 +43,11 @@ public class VolumeControlStateMachine extends StateMachine { static final int CONNECT = 1; static final int DISCONNECT = 2; - @VisibleForTesting - static final int STACK_EVENT = 101; - @VisibleForTesting - static final int CONNECT_TIMEOUT = 201; + @VisibleForTesting static final int STACK_EVENT = 101; + @VisibleForTesting static final int CONNECT_TIMEOUT = 201; // NOTE: the value is not "final" - it is modified in the unit tests - @VisibleForTesting - static int sConnectTimeoutMs = 30000; // 30s + @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s private Disconnected mDisconnected; private Connecting mConnecting; @@ -63,8 +60,11 @@ public class VolumeControlStateMachine extends StateMachine { private final BluetoothDevice mDevice; - VolumeControlStateMachine(BluetoothDevice device, VolumeControlService svc, - VolumeControlNativeInterface nativeInterface, Looper looper) { + VolumeControlStateMachine( + BluetoothDevice device, + VolumeControlService svc, + VolumeControlNativeInterface nativeInterface, + Looper looper) { super(TAG, looper); mDevice = device; @@ -84,11 +84,14 @@ public class VolumeControlStateMachine extends StateMachine { setInitialState(mDisconnected); } - static VolumeControlStateMachine make(BluetoothDevice device, VolumeControlService svc, - VolumeControlNativeInterface nativeInterface, Looper looper) { + static VolumeControlStateMachine make( + BluetoothDevice device, + VolumeControlService svc, + VolumeControlNativeInterface nativeInterface, + Looper looper) { Log.i(TAG, "make for device " + device); - VolumeControlStateMachine VolumeControlSm = new VolumeControlStateMachine(device, svc, - nativeInterface, looper); + VolumeControlStateMachine VolumeControlSm = + new VolumeControlStateMachine(device, svc, nativeInterface, looper); VolumeControlSm.start(); return VolumeControlSm; } @@ -106,29 +109,38 @@ public class VolumeControlStateMachine extends StateMachine { class Disconnected extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(DISCONNECT); if (mLastConnectionState != -1) { // Don't broadcast during startup - broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, - mLastConnectionState); + broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, mLastConnectionState); } } @Override public void exit() { - log("Exit Disconnected(" + mDevice + "): " + messageWhatToString( - getCurrentMessage().what)); + log( + "Exit Disconnected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; } @Override public boolean processMessage(Message message) { - log("Disconnected process message(" + mDevice + "): " + messageWhatToString( - message.what)); + log( + "Disconnected process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -141,8 +153,9 @@ public class VolumeControlStateMachine extends StateMachine { transitionTo(mConnecting); } else { // Reject the request and stay in Disconnected state - Log.w(TAG, "Outgoing VolumeControl Connecting request rejected: " - + mDevice); + Log.w( + TAG, + "Outgoing VolumeControl Connecting request rejected: " + mDevice); } break; case DISCONNECT: @@ -177,26 +190,28 @@ public class VolumeControlStateMachine extends StateMachine { break; case VolumeControlStackEvent.CONNECTION_STATE_CONNECTING: if (mService.okToConnect(mDevice)) { - Log.i(TAG, "Incoming VolumeControl Connecting request accepted: " - + mDevice); + Log.i( + TAG, + "Incoming VolumeControl Connecting request accepted: " + mDevice); transitionTo(mConnecting); } else { // Reject the connection and stay in Disconnected state itself - Log.w(TAG, "Incoming Volume Control Connecting request rejected: " - + mDevice); + Log.w( + TAG, + "Incoming Volume Control Connecting request rejected: " + mDevice); mNativeInterface.disconnectVolumeControl(mDevice); } break; case VolumeControlStackEvent.CONNECTION_STATE_CONNECTED: Log.w(TAG, "VolumeControl Connected from Disconnected state: " + mDevice); if (mService.okToConnect(mDevice)) { - Log.i(TAG, "Incoming Volume Control Connected request accepted: " - + mDevice); + Log.i( + TAG, + "Incoming Volume Control Connected request accepted: " + mDevice); transitionTo(mConnected); } else { // Reject the connection and stay in Disconnected state itself - Log.w(TAG, "Incoming VolumeControl Connected request rejected: " - + mDevice); + Log.w(TAG, "Incoming VolumeControl Connected request rejected: " + mDevice); mNativeInterface.disconnectVolumeControl(mDevice); } break; @@ -210,29 +225,38 @@ public class VolumeControlStateMachine extends StateMachine { } } - @VisibleForTesting class Connecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState); } @Override public void exit() { - log("Exit Connecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Connecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Connecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -319,41 +343,53 @@ public class VolumeControlStateMachine extends StateMachine { class Disconnecting extends State { @Override public void enter() { - Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState); } @Override public void exit() { - log("Exit Disconnecting(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Disconnecting(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; removeMessages(CONNECT_TIMEOUT); } @Override public boolean processMessage(Message message) { - log("Disconnecting process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log( + "Disconnecting process message(" + + mDevice + + "): " + + messageWhatToString(message.what)); switch (message.what) { case CONNECT: deferMessage(message); break; - case CONNECT_TIMEOUT: { - Log.w(TAG, "Disconnecting connection timeout: " + mDevice); - mNativeInterface.disconnectVolumeControl(mDevice); - VolumeControlStackEvent disconnectEvent = - new VolumeControlStackEvent( - VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - disconnectEvent.device = mDevice; - disconnectEvent.valueInt1 = - VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED; - sendMessage(STACK_EVENT, disconnectEvent); - break; - } + case CONNECT_TIMEOUT: + { + Log.w(TAG, "Disconnecting connection timeout: " + mDevice); + mNativeInterface.disconnectVolumeControl(mDevice); + VolumeControlStackEvent disconnectEvent = + new VolumeControlStackEvent( + VolumeControlStackEvent + .EVENT_TYPE_CONNECTION_STATE_CHANGED); + disconnectEvent.device = mDevice; + disconnectEvent.valueInt1 = + VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED; + sendMessage(STACK_EVENT, disconnectEvent); + break; + } case DISCONNECT: deferMessage(message); break; @@ -391,8 +427,7 @@ public class VolumeControlStateMachine extends StateMachine { transitionTo(mConnected); } else { // Reject the connection and stay in Disconnecting state - Log.w(TAG, "Incoming VolumeControl Connected request rejected: " - + mDevice); + Log.w(TAG, "Incoming VolumeControl Connected request rejected: " + mDevice); mNativeInterface.disconnectVolumeControl(mDevice); } break; @@ -402,8 +437,9 @@ public class VolumeControlStateMachine extends StateMachine { transitionTo(mConnecting); } else { // Reject the connection and stay in Disconnecting state - Log.w(TAG, "Incoming VolumeControl Connecting request rejected: " - + mDevice); + Log.w( + TAG, + "Incoming VolumeControl Connecting request rejected: " + mDevice); mNativeInterface.disconnectVolumeControl(mDevice); } break; @@ -420,23 +456,29 @@ public class VolumeControlStateMachine extends StateMachine { class Connected extends State { @Override public void enter() { - Log.i(TAG, "Enter Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + Log.i( + TAG, + "Enter Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(CONNECT); broadcastConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState); } @Override public void exit() { - log("Exit Connected(" + mDevice + "): " - + messageWhatToString(getCurrentMessage().what)); + log( + "Exit Connected(" + + mDevice + + "): " + + messageWhatToString(getCurrentMessage().what)); mLastConnectionState = BluetoothProfile.STATE_CONNECTED; } @Override public boolean processMessage(Message message) { - log("Connected process message(" + mDevice + "): " - + messageWhatToString(message.what)); + log("Connected process message(" + mDevice + "): " + messageWhatToString(message.what)); switch (message.what) { case CONNECT: @@ -490,6 +532,7 @@ public class VolumeControlStateMachine extends StateMachine { } } } + BluetoothDevice getDevice() { return mDevice; } @@ -500,16 +543,22 @@ public class VolumeControlStateMachine extends StateMachine { // This method does not check for error condition (newState == prevState) private void broadcastConnectionState(int newState, int prevState) { - log("Connection state " + mDevice + ": " + profileStateToString(prevState) - + "->" + profileStateToString(newState)); + log( + "Connection state " + + mDevice + + ": " + + profileStateToString(prevState) + + "->" + + profileStateToString(newState)); mService.handleConnectionStateChanged(mDevice, prevState, newState); Intent intent = new Intent(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + intent.addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mService.sendBroadcast(intent, BLUETOOTH_CONNECT); } @@ -551,7 +600,7 @@ public class VolumeControlStateMachine extends StateMachine { // Dump the state machine logs StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.dump(new FileDescriptor(), printWriter, new String[]{}); + super.dump(new FileDescriptor(), printWriter, new String[] {}); printWriter.flush(); stringWriter.flush(); ProfileService.println(sb, " StateMachineLog:"); -- GitLab