diff options
85 files changed, 1055 insertions, 826 deletions
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java index 463d9192f4..bd2ea36a25 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java @@ -42,6 +42,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.media.AudioDeviceCallback; +import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; import android.os.Binder; @@ -99,6 +101,8 @@ public class A2dpService extends ProfileService { @GuardedBy("mStateMachines") private BluetoothDevice mActiveDevice; + + private BluetoothDevice mExposedActiveDevice; private final ConcurrentMap<BluetoothDevice, A2dpStateMachine> mStateMachines = new ConcurrentHashMap<>(); @@ -116,6 +120,8 @@ public class A2dpService extends ProfileService { boolean mA2dpOffloadEnabled = false; private BroadcastReceiver mBondStateChangedReceiver; + private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback = + new AudioManagerAudioDeviceCallback(); A2dpService() { mNativeInterface = requireNonNull(A2dpNativeInterface.getInstance()); @@ -196,10 +202,13 @@ public class A2dpService extends ProfileService { mBondStateChangedReceiver = new BondStateChangedReceiver(); registerReceiver(mBondStateChangedReceiver, filter); - // Step 8: Mark service as started + // Step 8: Register Audio Device callback + mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler); + + // Step 9: Mark service as started setA2dpService(this); - // Step 9: Clear active device + // Step 10: Clear active device removeActiveDevice(false); return true; @@ -213,12 +222,15 @@ public class A2dpService extends ProfileService { return true; } - // Step 9: Clear active device and stop playing audio + // Step 10: Clear active device and stop playing audio removeActiveDevice(true); - // Step 8: Mark service as stopped + // Step 9: Mark service as stopped setA2dpService(null); + // Step 8: Unregister Audio Device Callback + mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback); + // Step 7: Unregister broadcast receivers unregisterReceiver(mBondStateChangedReceiver); mBondStateChangedReceiver = null; @@ -506,10 +518,8 @@ public class A2dpService extends ProfileService { synchronized (mStateMachines) { if (mActiveDevice == null) return true; previousActiveDevice = mActiveDevice; + mActiveDevice = null; } - - // This needs to happen before we inform the audio manager that the device - // disconnected. Please see comment in updateAndBroadcastActiveDevice() for why. updateAndBroadcastActiveDevice(null); // Make sure the Audio Manager knows the previous active device is no longer active. @@ -590,15 +600,14 @@ public class A2dpService extends ProfileService { return false; } previousActiveDevice = mActiveDevice; + mActiveDevice = device; } // Switch from one A2DP to another A2DP device if (DBG) { Log.d(TAG, "Switch A2DP devices to " + device + " from " + previousActiveDevice); } - // This needs to happen before we inform the audio manager that the device - // disconnected. Please see comment in updateAndBroadcastActiveDevice() for why. - updateAndBroadcastActiveDevice(device); + updateLowLatencyAudioSupport(device); BluetoothDevice newActiveDevice = null; @@ -1052,10 +1061,89 @@ public class A2dpService extends ProfileService { } } - // This needs to run before any of the Audio Manager connection functions since - // AVRCP needs to be aware that the audio device is changed before the Audio Manager - // changes the volume of the output devices. - private void updateAndBroadcastActiveDevice(BluetoothDevice device) { + /* Notifications of audio device connection/disconn events. */ + private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback { + @Override + public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { + if (mAudioManager == null || mAdapterService == null) { + Log.e(TAG, "Callback called when A2dpService is stopped"); + return; + } + + synchronized (mStateMachines) { + for (AudioDeviceInfo deviceInfo : addedDevices) { + if (deviceInfo.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) { + continue; + } + + String address = deviceInfo.getAddress(); + if (address.equals("00:00:00:00:00:00")) { + continue; + } + + byte[] addressBytes = Utils.getBytesFromAddress(address); + BluetoothDevice device = mAdapterService.getDeviceFromByte(addressBytes); + + if (DBG) { + Log.d(TAG, " onAudioDevicesAdded: " + device + ", device type: " + + deviceInfo.getType()); + } + + /* Don't expose already exposed active device */ + if (device.equals(mExposedActiveDevice)) { + if (DBG) { + Log.d(TAG, " onAudioDevicesAdded: " + device + " is already exposed"); + } + return; + } + + + if (!device.equals(mActiveDevice)) { + Log.e(TAG, "Added device does not match to the one activated here. (" + + device + " != " + mActiveDevice + + " / " + mActiveDevice+ ")"); + continue; + } + + mExposedActiveDevice = device; + updateAndBroadcastActiveDevice(device); + return; + } + } + } + + @Override + public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) { + if (mAudioManager == null || mAdapterService == null) { + Log.e(TAG, "Callback called when LeAudioService is stopped"); + return; + } + + synchronized (mStateMachines) { + for (AudioDeviceInfo deviceInfo : removedDevices) { + if (deviceInfo.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) { + continue; + } + + String address = deviceInfo.getAddress(); + if (address.equals("00:00:00:00:00:00")) { + continue; + } + + mExposedActiveDevice = null; + + if (DBG) { + Log.d(TAG, " onAudioDevicesRemoved: " + address + ", device type: " + + deviceInfo.getType() + + ", mActiveDevice: " + mActiveDevice); + } + } + } + } + } + + @VisibleForTesting + void updateAndBroadcastActiveDevice(BluetoothDevice device) { if (DBG) { Log.d(TAG, "updateAndBroadcastActiveDevice(" + device + ")"); } @@ -1064,14 +1152,8 @@ public class A2dpService extends ProfileService { if (mFactory.getAvrcpTargetService() != null) { mFactory.getAvrcpTargetService().handleA2dpActiveDeviceChanged(device); } - synchronized (mStateMachines) { - mActiveDevice = device; - } - mAdapterService - .getActiveDeviceManager() - .profileActiveDeviceChanged(BluetoothProfile.A2DP, device); - mAdapterService.getSilenceDeviceManager().a2dpActiveDeviceChanged(device); + mAdapterService.handleActiveDeviceChange(BluetoothProfile.A2DP, device); BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, BluetoothProfile.A2DP, mAdapterService.obfuscateAddress(device), @@ -1282,12 +1364,16 @@ public class A2dpService extends ProfileService { } mAdapterService.notifyProfileConnectionStateChangeToGatt( BluetoothProfile.A2DP, fromState, toState); + mAdapterService.handleProfileConnectionStateChange( + BluetoothProfile.A2DP, device, fromState, toState); mAdapterService .getActiveDeviceManager() .profileConnectionStateChanged(BluetoothProfile.A2DP, device, fromState, toState); mAdapterService .getSilenceDeviceManager() .a2dpConnectionStateChanged(device, fromState, toState); + mAdapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.A2DP, toState, fromState); } /** diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java index 0b7bf6288e..ffeefd95de 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java @@ -644,5 +644,7 @@ public class A2dpSinkService extends ProfileService { void connectionStateChanged(BluetoothDevice device, int fromState, int toState) { mAdapterService.notifyProfileConnectionStateChangeToGatt( BluetoothProfile.A2DP_SINK, fromState, toState); + mAdapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.A2DP_SINK, toState, fromState); } } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java index a6140aea8c..0fd01dbaaa 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java @@ -38,6 +38,7 @@ import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dpsink.A2dpSinkService; +import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.internal.annotations.VisibleForTesting; @@ -1341,6 +1342,12 @@ class AvrcpControllerStateMachine extends StateMachine { MetricsLogger.logProfileConnectionEvent( BluetoothMetricsProto.ProfileId.AVRCP_CONTROLLER); } + AdapterService adapterService = AdapterService.getAdapterService(); + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + mDevice, BluetoothProfile.AVRCP_CONTROLLER, currentState, mMostRecentState); + } + logD("Connection state " + mDevice + ": " + mMostRecentState + "->" + currentState); Intent intent = new Intent(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, mMostRecentState); diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java index 854da1de52..b39e13c177 100644 --- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java @@ -198,7 +198,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac * Called when active state of audio profiles changed * * @param profile The Bluetooth profile of which active state changed - * @param device The device currently activated. {@code null} if no A2DP device activated + * @param device The device currently activated. {@code null} if no device is active */ public void profileActiveDeviceChanged(int profile, BluetoothDevice device) { switch (profile) { diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java index 573057f9fa..53ec382d48 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java @@ -20,7 +20,9 @@ package com.android.bluetooth.btservice; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_SCAN; +import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.app.BroadcastOptions; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothA2dpSink; import android.bluetooth.BluetoothAdapter; @@ -46,6 +48,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.os.ParcelUuid; import android.os.SystemProperties; import android.os.UserHandle; @@ -57,6 +62,7 @@ import androidx.annotation.VisibleForTesting; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; +import com.android.modules.utils.build.SdkLevel; import com.google.common.collect.EvictingQueue; @@ -145,6 +151,8 @@ class AdapterProperties { private List<BufferConstraint> mBufferConstraintList; private boolean mReceiverRegistered; + private Handler mHandler; + private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -155,49 +163,49 @@ class AdapterProperties { } switch (action) { case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.HEADSET, intent); + logConnectionStateChanges(BluetoothProfile.HEADSET, intent); break; case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.A2DP, intent); + logConnectionStateChanges(BluetoothProfile.A2DP, intent); break; case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.HEADSET_CLIENT, intent); + logConnectionStateChanges(BluetoothProfile.HEADSET_CLIENT, intent); break; case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.HEARING_AID, intent); + logConnectionStateChanges(BluetoothProfile.HEARING_AID, intent); break; case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.A2DP_SINK, intent); + logConnectionStateChanges(BluetoothProfile.A2DP_SINK, intent); break; case BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.HID_DEVICE, intent); + logConnectionStateChanges(BluetoothProfile.HID_DEVICE, intent); break; case BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.HID_HOST, intent); + logConnectionStateChanges(BluetoothProfile.HID_HOST, intent); break; case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.AVRCP_CONTROLLER, intent); + logConnectionStateChanges(BluetoothProfile.AVRCP_CONTROLLER, intent); break; case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.PAN, intent); + logConnectionStateChanges(BluetoothProfile.PAN, intent); break; case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.MAP, intent); + logConnectionStateChanges(BluetoothProfile.MAP, intent); break; case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.MAP_CLIENT, intent); + logConnectionStateChanges(BluetoothProfile.MAP_CLIENT, intent); break; case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.SAP, intent); + logConnectionStateChanges(BluetoothProfile.SAP, intent); break; case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.PBAP_CLIENT, intent); + logConnectionStateChanges(BluetoothProfile.PBAP_CLIENT, intent); break; case BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.PBAP, intent); + logConnectionStateChanges(BluetoothProfile.PBAP, intent); break; case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED: - sendConnectionStateChange(BluetoothProfile.LE_AUDIO, intent); + logConnectionStateChanges(BluetoothProfile.LE_AUDIO, intent); break; default: Log.w(TAG, "Received unknown intent " + intent); @@ -241,6 +249,8 @@ class AdapterProperties { SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false) && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); + mHandler = new Handler(Looper.getMainLooper()); + IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); @@ -731,7 +741,7 @@ class AdapterProperties { } @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) - private void sendConnectionStateChange(int profile, Intent connIntent) { + private void logConnectionStateChanges(int profile, Intent connIntent) { BluetoothDevice device = connIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); int prevState = connIntent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1); int state = connIntent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); @@ -741,23 +751,27 @@ class AdapterProperties { metricId, device.getName()); MetricsLogger.getInstance().logSanitizedBluetoothDeviceName(metricId, device.getName()); } - Log.d(TAG, "PROFILE_CONNECTION_STATE_CHANGE: profile=" - + BluetoothProfile.getProfileName(profile) + ", device=" + device + ", " - + prevState + " -> " + state); BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, state, 0 /* deprecated */, profile, mService.obfuscateAddress(device), metricId, 0, -1); + } + @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) + void updateOnProfileConnectionChanged( + BluetoothDevice device, int profile, int state, int prevState) { + mHandler.post(() -> sendConnectionStateChange(device, profile, state, prevState)); + } + + @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); if (!isNormalStateTransition(prevState, state)) { Log.w(TAG, "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + BluetoothProfile.getProfileName(profile) + ", device=" + device + ", " + prevState + " -> " + state); } - sendConnectionStateChange(device, profile, state, prevState); - } - - @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) - void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) { if (!validateProfileConnectionState(state) || !validateProfileConnectionState(prevState)) { // Previously, an invalid state was broadcast anyway, // with the invalid state converted to -1 in the intent. @@ -1168,7 +1182,7 @@ class AdapterProperties { mDiscoveryEndMs = System.currentTimeMillis(); intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); Utils.sendBroadcast(mService, intent, BLUETOOTH_SCAN, - Utils.getTempAllowlistBroadcastOptions()); + getBroadcastOptionsForDiscoveryFinished()); } else if (state == AbstractionLayer.BT_DISCOVERY_STARTED) { mDiscovering = true; mDiscoveryEndMs = System.currentTimeMillis() + DEFAULT_DISCOVERY_TIMEOUT_MS; @@ -1179,6 +1193,18 @@ class AdapterProperties { } } + /** + * @return broadcast options for ACTION_DISCOVERY_FINISHED broadcast + */ + private static @NonNull Bundle getBroadcastOptionsForDiscoveryFinished() { + final BroadcastOptions options = Utils.getTempBroadcastOptions(); + if (SdkLevel.isAtLeastU()) { + options.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT); + options.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); + } + return options.toBundle(); + } + @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { writer.println(TAG); diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index f7f79bfbc8..d18423aae0 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -2043,6 +2043,12 @@ public class AdapterService extends Service { return mDatabaseManager.getCustomMeta(device, key); } + /** Update Adapter Properties when BT profiles connection state changes. */ + public void updateProfileConnectionAdapterProperties( + BluetoothDevice device, int profile, int state, int prevState) { + mAdapterProperties.updateOnProfileConnectionChanged(device, profile, state, prevState); + } + /** Handlers for incoming service calls */ private AdapterServiceBinder mBinder; @@ -5170,6 +5176,33 @@ public class AdapterService extends Service { } @Override + public void isMediaProfileConnected( + AttributionSource source, SynchronousResultReceiver receiver) { + try { + receiver.send(isMediaProfileConnected(source)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + private boolean isMediaProfileConnected(AttributionSource source) { + AdapterService service = getService(); + if (service == null + || !Utils.checkConnectPermissionForDataDelivery( + service, source, "AdapterService.isMediaProfileConnected")) { + return false; + } + enforceBluetoothPrivilegedPermission(service); + + return service.isMediaProfileConnected(); + } + + @Override public IBluetoothGatt getBluetoothGatt() { AdapterService service = getService(); if (service == null) { @@ -6845,6 +6878,27 @@ public class AdapterService extends Service { } } + boolean isMediaProfileConnected() { + if (mA2dpService != null && mA2dpService.getConnectedDevices().size() > 0) { + debugLog("isMediaProfileConnected. A2dp is connected"); + return true; + } else if (mHearingAidService != null + && mHearingAidService.getConnectedDevices().size() > 0) { + debugLog("isMediaProfileConnected. HearingAid is connected"); + return true; + } else if (mLeAudioService != null && mLeAudioService.getConnectedDevices().size() > 0) { + debugLog("isMediaProfileConnected. LeAudio is connected"); + return true; + } else { + debugLog( + "isMediaProfileConnected: no Media connected." + + (" A2dp=" + mA2dpService) + + (" HearingAid=" + mHearingAidService) + + (" LeAudio=" + mLeAudioService)); + return false; + } + } + /** * Notify GATT of a Bluetooth profile's connection state change for a given {@link * BluetoothProfile}. @@ -6857,6 +6911,24 @@ public class AdapterService extends Service { mGattService.notifyProfileConnectionStateChange(profile, fromState, toState); } + /** + * Handle Bluetooth app state when connection state changes for a given {@code profile}. + * + * <p>Currently this function is limited to handling Phone policy but the eventual goal is to + * move all connection logic here. + */ + public void handleProfileConnectionStateChange( + int profile, BluetoothDevice device, int fromState, int toState) { + mPhonePolicy.profileConnectionStateChanged(profile, device, fromState, toState); + } + + /** Handle Bluetooth app state when active device changes for a given {@code profile}. */ + public void handleActiveDeviceChange(int profile, BluetoothDevice device) { + mActiveDeviceManager.profileActiveDeviceChanged(profile, device); + mSilenceDeviceManager.profileActiveDeviceChanged(profile, device); + mPhonePolicy.profileActiveDeviceChanged(profile, device); + } + static int convertScanModeToHal(int mode) { switch (mode) { case BluetoothAdapter.SCAN_MODE_NONE: diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java index 7f92b5caf0..a6a9ca2c2e 100644 --- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java @@ -19,16 +19,10 @@ package com.android.bluetooth.btservice; import static com.android.bluetooth.Utils.isDualModeAudioEnabled; import android.annotation.RequiresPermission; -import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothHeadset; -import android.bluetooth.BluetoothHearingAid; -import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; -import android.bluetooth.BluetoothVolumeControl; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -63,20 +57,6 @@ import java.util.Objects; // Describes the phone policy // -// The policy should be as decoupled from the stack as possible. In an ideal world we should not -// need to have this policy talk with any non-public APIs and one way to enforce that would be to -// keep this file outside the Bluetooth process. Unfortunately, keeping a separate process alive is -// an expensive and a tedious task. -// -// Best practices: -// a) PhonePolicy should be ALL private methods -// -- Use broadcasts which can be listened in on the BroadcastReceiver -// b) NEVER call from the PhonePolicy into the Java stack, unless public APIs. It is OK to call into -// the non public versions as long as public versions exist (so that a 3rd party policy can mimick) -// us. -// -// Policy description: -// // Policies are usually governed by outside events that may warrant an action. We talk about various // events and the resulting outcome from this policy: // @@ -86,15 +66,12 @@ import java.util.Objects; // 2. When the profile connection-state changes: At this point if a new profile gets CONNECTED we // will try to connect other profiles on the same device. This is to avoid collision if devices // somehow end up trying to connect at same time or general connection issues. -class PhonePolicy { +class PhonePolicy implements AdapterService.BluetoothStateCallback { private static final boolean DBG = true; private static final String TAG = "BluetoothPhonePolicy"; // Message types for the handler (internal messages generated by intents or timeouts) - private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED = 1; private static final int MESSAGE_CONNECT_OTHER_PROFILES = 3; - private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; - private static final int MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED = 5; private static final int MESSAGE_DEVICE_CONNECTED = 6; @VisibleForTesting static final String AUTO_CONNECT_PROFILES_PROPERTY = @@ -116,6 +93,42 @@ class PhonePolicy { private final HashSet<BluetoothDevice> mConnectOtherProfilesDeviceSet = new HashSet<>(); @VisibleForTesting boolean mAutoConnectProfilesSupported; + @Override + public void onBluetoothStateChange(int prevState, int newState) { + // Only act if the adapter has actually changed state from non-ON to ON. + // NOTE: ON is the state depicting BREDR ON and not just BLE ON. + if (newState == BluetoothAdapter.STATE_ON) { + resetStates(); + autoConnect(); + } + } + + public void profileConnectionStateChanged( + int profile, BluetoothDevice device, int fromState, int toState) { + switch (profile) { + case BluetoothProfile.A2DP: + case BluetoothProfile.HEADSET: + case BluetoothProfile.LE_AUDIO: + case BluetoothProfile.CSIP_SET_COORDINATOR: + case BluetoothProfile.VOLUME_CONTROL: + mHandler.post( + () -> processProfileStateChanged(device, profile, toState, fromState)); + break; + default: + break; + } + } + + /** + * Called when active state of audio profiles changed + * + * @param profile The Bluetooth profile of which active state changed + * @param device The device currently activated. {@code null} if no A2DP device activated + */ + public void profileActiveDeviceChanged(int profile, BluetoothDevice device) { + mHandler.post(() -> processActiveDeviceChanged(device, profile)); + } + // Broadcast receiver for all changes to states of various profiles private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -126,59 +139,6 @@ class PhonePolicy { return; } switch (action) { - case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, - BluetoothProfile.HEADSET, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, - BluetoothProfile.A2DP, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothCsipSetCoordinator.ACTION_CSIS_CONNECTION_STATE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, - BluetoothProfile.CSIP_SET_COORDINATOR, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, - BluetoothProfile.LE_AUDIO, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, - BluetoothProfile.VOLUME_CONTROL, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED, - BluetoothProfile.A2DP, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED, - BluetoothProfile.HEADSET, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED, - BluetoothProfile.HEARING_AID, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED: - mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED, - BluetoothProfile.LE_AUDIO, -1, // No-op argument - intent).sendToTarget(); - break; - case BluetoothAdapter.ACTION_STATE_CHANGED: - // Only pass the message on if the adapter has actually changed state from - // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON. - int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); - if (newState == BluetoothAdapter.STATE_ON) { - mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget(); - } - break; case BluetoothDevice.ACTION_ACL_CONNECTED: mHandler.obtainMessage(MESSAGE_DEVICE_CONNECTED, intent).sendToTarget(); break; @@ -203,24 +163,6 @@ class PhonePolicy { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: { - Intent intent = (Intent) msg.obj; - BluetoothDevice device = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - int prevState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1); - int nextState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); - processProfileStateChanged(device, msg.arg1, nextState, prevState); - } - break; - - case MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED: { - Intent intent = (Intent) msg.obj; - BluetoothDevice activeDevice = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - processActiveDeviceChanged(activeDevice, msg.arg1); - } - 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 @@ -229,16 +171,12 @@ class PhonePolicy { mConnectOtherProfilesDeviceSet.remove(device); break; } - case MESSAGE_ADAPTER_STATE_TURNED_ON: - // Call auto connect when adapter switches state to ON - resetStates(); - autoConnect(); - break; case MESSAGE_DEVICE_CONNECTED: Intent intent = (Intent) msg.obj; BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); processDeviceConnected(device); + break; } } } @@ -247,23 +185,16 @@ class PhonePolicy { // Policy API functions for lifecycle management (protected) protected void start() { + mAdapterService.registerBluetoothStateCallback((command) -> mHandler.post(command), this); + IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothCsipSetCoordinator.ACTION_CSIS_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); - filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); - filter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); - filter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED); - filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); mAdapterService.registerReceiver(mReceiver, filter); } protected void cleanup() { + mAdapterService.unregisterBluetoothStateCallback(this); mAdapterService.unregisterReceiver(mReceiver); resetStates(); } diff --git a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java index 7c2f7aa55d..4069a74110 100644 --- a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java @@ -77,6 +77,25 @@ public class SilenceDeviceManager { private static final int DISABLE_SILENCE = 1; /** + * Called when active state of audio profiles changed + * + * @param profile The Bluetooth profile of which active state changed + * @param device The device currently activated. {@code null} if no device is active + */ + public void profileActiveDeviceChanged(int profile, BluetoothDevice device) { + switch (profile) { + case BluetoothProfile.A2DP: + mHandler.obtainMessage(MSG_A2DP_ACTIVE_DEVICE_CHANGED, device).sendToTarget(); + break; + case BluetoothProfile.HEADSET: + mHandler.obtainMessage(MSG_HFP_ACTIVE_DEVICE_CHANGED, device).sendToTarget(); + break; + default: + break; + } + } + + /** * Called when A2DP connection state changed by A2dpService * * @param device The device of which connection state was changed @@ -89,15 +108,6 @@ public class SilenceDeviceManager { } /** - * Called when A2DP active device changed by A2dpService - * - * @param device The device currently activated. {@code null} if no A2DP device activated - */ - public void a2dpActiveDeviceChanged(BluetoothDevice device) { - mHandler.obtainMessage(MSG_A2DP_ACTIVE_DEVICE_CHANGED, device).sendToTarget(); - } - - /** * Called when HFP connection state changed by HeadsetService * * @param device The device of which connection state was changed @@ -109,15 +119,6 @@ public class SilenceDeviceManager { .sendToTarget(); } - /** - * Called when HFP active device is changed by HeadsetService - * - * @param device The device currently activated. {@code null} if no HFP device activated - */ - public void hfpActiveDeviceChanged(BluetoothDevice device) { - mHandler.obtainMessage(MSG_HFP_ACTIVE_DEVICE_CHANGED, device).sendToTarget(); - } - class SilenceDeviceManagerHandler extends Handler { SilenceDeviceManagerHandler(Looper looper) { super(looper); diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java index 97a582e6d3..35d6b48af9 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java @@ -1056,6 +1056,8 @@ public class CsipSetCoordinatorService extends ProfileService { mGroupIdToConnectedDevices.get(groupId).add(device); disableCsipIfNeeded(groupId); } + mAdapterService.handleProfileConnectionStateChange( + BluetoothProfile.CSIP_SET_COORDINATOR, device, fromState, toState); } /** diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java index 62691fd8f4..dfefd10550 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java @@ -359,7 +359,7 @@ public class HearingAidService extends ProfileService { return true; } - List<BluetoothDevice> getConnectedDevices() { + public List<BluetoothDevice> getConnectedDevices() { synchronized (mStateMachines) { List<BluetoothDevice> devices = new ArrayList<>(); for (HearingAidStateMachine sm : mStateMachines.values()) { @@ -724,9 +724,7 @@ public class HearingAidService extends ProfileService { } private void notifyActiveDeviceChanged() { - mAdapterService - .getActiveDeviceManager() - .profileActiveDeviceChanged(BluetoothProfile.HEARING_AID, mActiveDevice); + 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 @@ -964,6 +962,8 @@ public class HearingAidService extends ProfileService { .getActiveDeviceManager() .profileConnectionStateChanged( BluetoothProfile.HEARING_AID, device, fromState, toState); + mAdapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.HEARING_AID, toState, fromState); } /** diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java index 5244987772..468ac42b57 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java @@ -2007,6 +2007,10 @@ public class HeadsetService extends ProfileService { .handleHeadsetConnectionStateChanged(device, fromState, toState); mAdapterService.notifyProfileConnectionStateChangeToGatt( BluetoothProfile.HEADSET, fromState, toState); + mAdapterService.handleProfileConnectionStateChange( + BluetoothProfile.HEADSET, device, fromState, toState); + mAdapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.HEADSET, toState, fromState); } /** @@ -2133,10 +2137,7 @@ public class HeadsetService extends ProfileService { private void broadcastActiveDevice(BluetoothDevice device) { logD("broadcastActiveDevice: " + device); - mAdapterService - .getActiveDeviceManager() - .profileActiveDeviceChanged(BluetoothProfile.HEADSET, device); - mAdapterService.getSilenceDeviceManager().hfpActiveDeviceChanged(device); + mAdapterService.handleActiveDeviceChange(BluetoothProfile.HEADSET, device); BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED, diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java index e6256389cc..519ba33f9c 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java @@ -17,7 +17,6 @@ package com.android.bluetooth.hfp; import static android.Manifest.permission.BLUETOOTH_CONNECT; - import static com.android.modules.utils.build.SdkLevel.isAtLeastU; import android.annotation.RequiresPermission; @@ -514,6 +513,13 @@ public class HeadsetStateMachine extends StateMachine { device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED, + BluetoothProfile.HEADSET, + BluetoothProtoEnums.RESULT_FAILURE, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProtoEnums.REASON_NATIVE_LAYER_REJECTED); break; } transitionTo(mConnecting); @@ -575,6 +581,13 @@ public class HeadsetStateMachine extends StateMachine { // Indicate rejection to other components. broadcastConnectionState(mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED, + BluetoothProfile.HEADSET, + BluetoothProtoEnums.RESULT_FAILURE, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProtoEnums.REASON_INCOMING_CONN_REJECTED); } break; case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING: diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java index 99734c30aa..0757c1fd1b 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnectionService.java @@ -163,6 +163,10 @@ public class HfpClientConnectionService extends ConnectionService { PbapClientService.getPbapClientService() .handleHeadsetClientConnectionStateChanged(device, oldState, newState); } + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.HEADSET_CLIENT, newState, oldState); + } } private void onCallChangedInternal(BluetoothDevice device, HfpClientCall call) { diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java index ffc9f0222d..fbe5f9f4f5 100644 --- a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java +++ b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java @@ -962,6 +962,12 @@ public class HidDeviceService extends ProfileService { return; } + AdapterService adapterService = AdapterService.getAdapterService(); + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.HID_DEVICE, newState, prevState); + } + if (newState == BluetoothProfile.STATE_CONNECTED) { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.HID_DEVICE); } diff --git a/android/app/src/com/android/bluetooth/hid/HidHostService.java b/android/app/src/com/android/bluetooth/hid/HidHostService.java index f98bf46af0..66a63807a6 100644 --- a/android/app/src/com/android/bluetooth/hid/HidHostService.java +++ b/android/app/src/com/android/bluetooth/hid/HidHostService.java @@ -910,6 +910,12 @@ public class HidHostService extends ProfileService { } mInputDevices.put(device, newState); + AdapterService adapterService = AdapterService.getAdapterService(); + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.HID_HOST, newState, 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. */ 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 0a5d6f6878..fca836cb0f 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -1192,10 +1192,15 @@ public class LeAudioService extends ProfileService { mAdapterService.notifyProfileConnectionStateChangeToGatt( BluetoothProfile.LE_AUDIO, prevState, newState); + mAdapterService.handleProfileConnectionStateChange( + BluetoothProfile.LE_AUDIO, device, prevState, newState); mAdapterService .getActiveDeviceManager() .profileConnectionStateChanged( BluetoothProfile.LE_AUDIO, device, prevState, newState); + mAdapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.LE_AUDIO, newState, prevState); + Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); @@ -1219,9 +1224,7 @@ public class LeAudioService extends ProfileService { + ". Currently active device is " + mActiveAudioOutDevice); } - mAdapterService - .getActiveDeviceManager() - .profileActiveDeviceChanged(BluetoothProfile.LE_AUDIO, device); + mAdapterService.handleActiveDeviceChange(BluetoothProfile.LE_AUDIO, device); Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java index 5fe2dc497b..b600296355 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java @@ -527,6 +527,9 @@ public class BluetoothMapService extends ProfileService { } int prevState = mState; mState = state; + mAdapterService.updateProfileConnectionAdapterProperties( + sRemoteDevice, BluetoothProfile.MAP, mState, prevState); + BluetoothMap.invalidateBluetoothGetConnectionStateCache(); Intent intent = new Intent(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); diff --git a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java index d1bbd25286..af640c1335 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +++ b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java @@ -62,6 +62,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.Utils; +import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.map.BluetoothMapbMessageMime; @@ -267,6 +268,13 @@ class MceStateMachine extends StateMachine { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.MAP_CLIENT); } setState(state); + + AdapterService adapterService = AdapterService.getAdapterService(); + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + mDevice, BluetoothProfile.MAP_CLIENT, state, prevState); + } + Intent intent = new Intent(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, state); diff --git a/android/app/src/com/android/bluetooth/pan/PanService.java b/android/app/src/com/android/bluetooth/pan/PanService.java index c1bb060961..0681b3987d 100644 --- a/android/app/src/com/android/bluetooth/pan/PanService.java +++ b/android/app/src/com/android/bluetooth/pan/PanService.java @@ -737,6 +737,9 @@ public class PanService extends ProfileService { if (state == BluetoothProfile.STATE_CONNECTED) { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PAN); } + mAdapterService.updateProfileConnectionAdapterProperties( + 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. */ diff --git a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java index 3767877112..9363b2dfa8 100644 --- a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java +++ b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java @@ -40,6 +40,7 @@ import com.android.bluetooth.IObexConnectionHandler; import com.android.bluetooth.ObexRejectServer; import com.android.bluetooth.R; import com.android.bluetooth.Utils; +import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; @@ -159,6 +160,12 @@ public class PbapStateMachine extends StateMachine { // Should not be called from enter() method private void broadcastConnectionState(BluetoothDevice device, int fromState, int toState) { stateLogD("broadcastConnectionState " + device + ": " + fromState + "->" + toState); + AdapterService adapterService = AdapterService.getAdapterService(); + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.PBAP, toState, fromState); + } + Intent intent = new Intent(BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, fromState); intent.putExtra(BluetoothProfile.EXTRA_STATE, toState); diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java index 984cdc8ce8..d74da11f18 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java @@ -62,6 +62,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.Utils; +import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.internal.annotations.VisibleForTesting; @@ -395,6 +396,11 @@ class PbapClientStateMachine extends StateMachine { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PBAP_CLIENT); } Log.d(TAG, "Connection state " + device + ": " + prevState + "->" + state); + AdapterService adapterService = AdapterService.getAdapterService(); + if (adapterService != null) { + adapterService.updateProfileConnectionAdapterProperties( + device, BluetoothProfile.PBAP_CLIENT, state, prevState); + } Intent intent = new Intent(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, state); diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java index 7915083b2c..149552da1b 100644 --- a/android/app/src/com/android/bluetooth/sap/SapService.java +++ b/android/app/src/com/android/bluetooth/sap/SapService.java @@ -540,6 +540,9 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } int prevState = mState; mState = state; + mAdapterService.updateProfileConnectionAdapterProperties( + mRemoteDevice, BluetoothProfile.SAP, mState, prevState); + BluetoothSap.invalidateBluetoothGetConnectionStateCache(); Intent intent = new Intent(BluetoothSap.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java index e8b10a15d5..10f7ac77dc 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java @@ -1138,6 +1138,8 @@ public class VolumeControlService extends ProfileService { } } } + mAdapterService.handleProfileConnectionStateChange( + BluetoothProfile.VOLUME_CONTROL, device, fromState, toState); } /** diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java index 8114dbaefd..a6d9109c2a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java @@ -75,6 +75,7 @@ public class A2dpServiceTest { private final BlockingQueue<Intent> mConnectionStateChangedQueue = new LinkedBlockingQueue<>(); private final BlockingQueue<Intent> mAudioStateChangedQueue = new LinkedBlockingQueue<>(); private final BlockingQueue<Intent> mCodecConfigChangedQueue = new LinkedBlockingQueue<>(); + private final BlockingQueue<Intent> mActiveDeviceQueue = new LinkedBlockingQueue<>(); @Mock private AdapterService mAdapterService; @Mock private ActiveDeviceManager mActiveDeviceManager; @@ -117,6 +118,7 @@ public class A2dpServiceTest { filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED); + filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); mA2dpIntentReceiver = new A2dpIntentReceiver(); mTargetContext.registerReceiver(mA2dpIntentReceiver, filter); @@ -135,6 +137,7 @@ public class A2dpServiceTest { mConnectionStateChangedQueue.clear(); mAudioStateChangedQueue.clear(); mCodecConfigChangedQueue.clear(); + mActiveDeviceQueue.clear(); TestUtils.clearAdapterService(mAdapterService); } @@ -163,6 +166,13 @@ public class A2dpServiceTest { Assert.fail("Cannot add Intent to the Codec Config queue: " + e.getMessage()); } } + if (BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED.equals(intent.getAction())) { + try { + mActiveDeviceQueue.put(intent); + } catch (InterruptedException e) { + Assert.fail("Cannot add Intent to the device queue: " + e.getMessage()); + } + } } } @@ -214,6 +224,13 @@ public class A2dpServiceTest { Assert.assertNull(intent); } + private void veifyActiveDeviceIntent(int timeoutMs, BluetoothDevice device) { + Intent intent = TestUtils.waitForIntent(timeoutMs, mActiveDeviceQueue); + Assert.assertNotNull(intent); + Assert.assertEquals(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, intent.getAction()); + Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); + } + @Test public void testGetA2dpService() { Assert.assertEquals(mA2dpService, A2dpService.getA2dpService()); @@ -940,6 +957,25 @@ public class A2dpServiceTest { connectDeviceWithCodecStatus(device, null); } + @Test + public void testActiveDevice() { + connectDevice(mTestDevice); + + /* Trigger setting active device */ + doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); + Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); + + /* Check if setting active devices sets right device */ + Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + + /* Since A2dpService called AudioManager - assume Audio manager calles properly callback + * mAudioManager.onAudioDeviceAdded + */ + mA2dpService.updateAndBroadcastActiveDevice(mTestDevice); + + veifyActiveDeviceIntent(TIMEOUT_MS, mTestDevice); + } + private void connectDeviceWithCodecStatus(BluetoothDevice device, BluetoothCodecStatus codecStatus) { A2dpStackEvent connCompletedEvent; 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 481c0cac14..431af5ec89 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 @@ -21,7 +21,6 @@ import static com.android.bluetooth.TestUtils.waitForLooperToFinishScheduledTask import static org.mockito.Mockito.*; -import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; @@ -324,13 +323,11 @@ public class PhonePolicyTest { BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Inject an event that the adapter is turned on. - Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); - intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON); - mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); + mPhonePolicy.onBluetoothStateChange(BluetoothAdapter.STATE_OFF, BluetoothAdapter.STATE_ON); // Check that we got a request to connect over HFP and A2DP - verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(bondedDevice)); - verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(bondedDevice)); + verify(mA2dpService).connect(eq(bondedDevice)); + verify(mHeadsetService).connect(eq(bondedDevice)); } /** @@ -363,10 +360,7 @@ public class PhonePolicyTest { BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Make one of the device active - Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, connectionOrder.get(0)); - intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); - mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); + mPhonePolicy.profileActiveDeviceChanged(BluetoothProfile.A2DP, connectionOrder.get(0)); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // Only calls setConnection on device connectionOrder.get(0) with STATE_CONNECTED @@ -379,10 +373,7 @@ public class PhonePolicyTest { // Make another device active when(mHeadsetService.getConnectionState(connectionOrder.get(1))).thenReturn( BluetoothProfile.STATE_CONNECTED); - intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, connectionOrder.get(1)); - intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); - mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); + mPhonePolicy.profileActiveDeviceChanged(BluetoothProfile.A2DP, connectionOrder.get(1)); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // Only calls setConnection on device connectionOrder.get(1) with STATE_CONNECTED @@ -396,12 +387,11 @@ public class PhonePolicyTest { // Disconnect a2dp for the device from previous STATE_CONNECTED when(mHeadsetService.getConnectionState(connectionOrder.get(1))).thenReturn( BluetoothProfile.STATE_DISCONNECTED); - intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, connectionOrder.get(1)); - intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED); - intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); - intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); - mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); + mPhonePolicy.profileConnectionStateChanged( + BluetoothProfile.A2DP, + connectionOrder.get(1), + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // Verify that we do not call setConnection, nor setDisconnection on disconnect @@ -411,9 +401,11 @@ public class PhonePolicyTest { verify(mDatabaseManager, never()).setDisconnection(connectionOrder.get(1)); // Disconnect a2dp for the device from previous STATE_DISCONNECTING - intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - BluetoothProfile.STATE_DISCONNECTING); - mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); + mPhonePolicy.profileConnectionStateChanged( + BluetoothProfile.A2DP, + connectionOrder.get(1), + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_DISCONNECTED); waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); // Verify that we do not call setConnection, but instead setDisconnection on disconnect @@ -1020,24 +1012,16 @@ public class PhonePolicyTest { private void updateProfileConnectionStateHelper(BluetoothDevice device, int profileId, int nextState, int prevState) { - Intent intent; switch (profileId) { case BluetoothProfile.A2DP: when(mA2dpService.getConnectionState(device)).thenReturn(nextState); - intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); break; case BluetoothProfile.HEADSET: when(mHeadsetService.getConnectionState(device)).thenReturn(nextState); - intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); break; default: - intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); break; } - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); - intent.putExtra(BluetoothProfile.EXTRA_STATE, nextState); - intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); - mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); + mPhonePolicy.profileConnectionStateChanged(profileId, device, prevState, nextState); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java index d9a5c98b4c..fd46f1a0cf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java @@ -476,9 +476,7 @@ public class HeadsetServiceAndStateMachineTest { BluetoothDevice activeDevice = connectedDevices.get(MAX_HEADSET_CONNECTIONS / 2); Assert.assertTrue(mHeadsetService.setActiveDevice(activeDevice)); verify(mNativeInterface).setActiveDevice(activeDevice); - verify(mActiveDeviceManager) - .profileActiveDeviceChanged(BluetoothProfile.HEADSET, activeDevice); - verify(mSilenceDeviceManager).hfpActiveDeviceChanged(activeDevice); + verify(mAdapterService).handleActiveDeviceChange(BluetoothProfile.HEADSET, activeDevice); Assert.assertEquals(activeDevice, mHeadsetService.getActiveDevice()); // Start virtual call Assert.assertTrue(mHeadsetService.startScoUsingVirtualVoiceCall()); 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 63248a5130..2547a5b63c 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 @@ -27,6 +27,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; import android.os.Looper; +import android.os.ParcelUuid; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; @@ -34,6 +35,7 @@ import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.storage.DatabaseManager; @@ -63,6 +65,7 @@ public class LeAudioBroadcastServiceTest { private LeAudioService mService; private LeAudioIntentReceiver mLeAudioIntentReceiver; private LinkedBlockingQueue<Intent> mIntentQueue; + @Mock private ActiveDeviceManager mActiveDeviceManager; @Mock private AdapterService mAdapterService; @Mock @@ -175,6 +178,7 @@ public class LeAudioBroadcastServiceTest { doReturn(true).when(mAdapterService).isLeAudioBroadcastSourceSupported(); doReturn((long)(1 << BluetoothProfile.LE_AUDIO_BROADCAST) | (1 << BluetoothProfile.LE_AUDIO)) .when(mAdapterService).getSupportedProfilesBitMask(); + doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -188,6 +192,7 @@ public class LeAudioBroadcastServiceTest { filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mLeAudioIntentReceiver = new LeAudioIntentReceiver(); + filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); mTargetContext.registerReceiver(mLeAudioIntentReceiver, filter); mDevice = TestUtils.getTestDevice(mAdapter, 0); @@ -505,6 +510,130 @@ public class LeAudioBroadcastServiceTest { Assert.assertEquals(meta_list.get(0), state_event.broadcastMetadata); } + private void verifyConnectionStateIntent( + int timeoutMs, BluetoothDevice device, int newState, int prevState) { + Intent intent = TestUtils.waitForIntent(timeoutMs, mIntentQueue); + Assert.assertNotNull(intent); + Assert.assertEquals( + BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED, intent.getAction()); + Assert.assertEquals( + (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE), device); + Assert.assertEquals(intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1), newState); + Assert.assertEquals( + intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1), prevState); + + if (newState == BluetoothProfile.STATE_CONNECTED) { + // ActiveDeviceManager calls deviceConnected when connected. + mService.deviceConnected(device); + } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + // ActiveDeviceManager calls deviceDisconnected when connected. + mService.deviceDisconnected(device, false); + } + } + + @Test + public void testCreatePendingBroadcast() { + int groupId = 1; + int direction = 3; + int snkAudioLocation = 3; + int srcAudioLocation = 4; + int availableContexts = 5; + byte[] code = {0x00, 0x01, 0x00, 0x02}; + + BluetoothLeAudioContentMetadata.Builder meta_builder = + new BluetoothLeAudioContentMetadata.Builder(); + meta_builder.setLanguage("ENG"); + meta_builder.setProgramInfo("Public broadcast info"); + BluetoothLeAudioContentMetadata meta = meta_builder.build(); + + /* Prepare active group to cause pending broadcast */ + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) + .getBondState(any(BluetoothDevice.class)); + doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.LE_AUDIO)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO}) + .when(mAdapterService) + .getRemoteUuids(any(BluetoothDevice.class)); + Assert.assertTrue(mService.connect(mDevice)); + + // Verify the connection state broadcast, and that we are in Connected state + verifyConnectionStateIntent( + TIMEOUT_MS, + mDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); + + LeAudioStackEvent create_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + create_event.device = mDevice; + create_event.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; + mService.messageFromNative(create_event); + + verifyConnectionStateIntent( + TIMEOUT_MS, + mDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); + + create_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); + create_event.device = mDevice; + create_event.valueInt1 = groupId; + create_event.valueInt2 = LeAudioStackEvent.GROUP_NODE_ADDED; + mService.messageFromNative(create_event); + + create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); + create_event.device = mDevice; + create_event.valueInt1 = direction; + create_event.valueInt2 = groupId; + create_event.valueInt3 = snkAudioLocation; + create_event.valueInt4 = srcAudioLocation; + create_event.valueInt5 = availableContexts; + mService.messageFromNative(create_event); + + create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); + create_event.valueInt1 = groupId; + create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; + mService.messageFromNative(create_event); + + BluetoothLeBroadcastSettings settings = buildBroadcastSettingsFromMetadata(meta, code, 1); + mService.createBroadcast(settings); + + /* Check if broadcast is queued, active group should not change */ + int activeGroup = mService.getActiveGroupId(); + Assert.assertEquals(activeGroup, groupId); + + /* Imitate group inactivity to cause create broadcast */ + create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; + mService.messageFromNative(create_event); + + List<BluetoothLeBroadcastSubgroupSettings> settingsList = settings.getSubgroupSettings(); + + int[] expectedQualityArray = + settingsList.stream().mapToInt(setting -> setting.getPreferredQuality()).toArray(); + byte[][] expectedDataArray = + settingsList.stream() + .map(setting -> setting.getContentMetadata().getRawMetadata()) + .toArray(byte[][]::new); + + verify(mLeAudioBroadcasterNativeInterface, times(1)) + .createBroadcast( + eq(true), + eq(TEST_BROADCAST_NAME), + eq(settings.getBroadcastCode()), + eq(settings.getPublicBroadcastMetadata().getRawMetadata()), + eq(expectedQualityArray), + eq(expectedDataArray)); + + activeGroup = mService.getActiveGroupId(); + Assert.assertEquals(-1, activeGroup); + } + private class LeAudioIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { 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 c9bccb8d1c..f8bed9641c 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 @@ -146,15 +146,8 @@ public class BluetoothMapSmsPduTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - BluetoothMapbMessage messageParsed; - try { - messageParsed = BluetoothMapbMessage.parse(inputStream, + BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_NATIVE); - } catch (IllegalArgumentException e) { - android.util.Log.e("getSubmitPdus_withTypeCDMA", "Failure: " + e); - // TODO b/257375445 remove try catch that prevent failure - return; - } assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageSms.class); } 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 a6e70b2373..230d455c22 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 @@ -84,15 +84,8 @@ public class BluetoothMapbMessageSmsTest { byte[] encodedMessageSms = messageSmsToEncode.encode(); InputStream inputStream = new ByteArrayInputStream(encodedMessageSms); - BluetoothMapbMessage messageParsed; - try { - messageParsed = BluetoothMapbMessage.parse(inputStream, + BluetoothMapbMessage messageParsed = BluetoothMapbMessage.parse(inputStream, BluetoothMapAppParams.CHARSET_NATIVE); - } catch (IllegalArgumentException e) { - android.util.Log.e("encodeToByteArray_thenAddByParsing", "Failure: " + e); - // TODO b/257375445 remove try catch that prevent failure - return; - } assertThat(messageParsed).isInstanceOf(BluetoothMapbMessageSms.class); BluetoothMapbMessageSms messageSmsParsed = (BluetoothMapbMessageSms) messageParsed; assertThat(messageSmsParsed.getSmsBody()).isEqualTo(TEST_MESSAGE); 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 d1718479a1..9b748947d8 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 @@ -44,6 +44,7 @@ import android.view.KeyEvent; import androidx.lifecycle.Lifecycle; import androidx.test.core.app.ActivityScenario; +import androidx.test.espresso.action.ViewActions; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -161,6 +162,9 @@ public class IncomingFileConfirmActivityTest { // It works normally if sleep for a few seconds Thread.sleep(TIMEOUT_MS); onView(withText(mTargetContext.getText(R.string.incoming_file_confirm_cancel).toString())) + .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( @@ -182,6 +186,9 @@ public class IncomingFileConfirmActivityTest { // It works normally if sleep for a few seconds Thread.sleep(TIMEOUT_MS); onView(withText(mTargetContext.getText(R.string.incoming_file_confirm_ok).toString())) + .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( diff --git a/android/pandora/mmi2grpc/mmi2grpc/__init__.py b/android/pandora/mmi2grpc/mmi2grpc/__init__.py index 309cc88eb3..4c25fc9f38 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/__init__.py +++ b/android/pandora/mmi2grpc/mmi2grpc/__init__.py @@ -93,7 +93,7 @@ class IUT: def __enter__(self): """Resets the IUT when starting a PTS test.""" self.rootcanal = RootCanal(port=self.rootcanal_control_port) - self.rootcanal.reconnect_phone() + self.rootcanal.move_in_range() self.modem = Modem(port=self.modem_simulator_port) diff --git a/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py b/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py index c7e6b9ab2c..493797960e 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py +++ b/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py @@ -86,86 +86,55 @@ class RootCanal: def close(self): self.channel.close() - @staticmethod - def _parse_device_list(raw): - # time for some cursed parsing! - categories = {} - curr_category = None - for line in raw.split("\n"): + def move_out_of_range(self): + """Space out the connected devices to generate a supervision + timeout for all existing connections.""" + # Disconnect all devices from all phys. + (devices, phys) = self._read_device_list() + for (device_id, _) in devices: + for (phy_id, _, phy_devices) in phys: + if device_id in phy_devices: + self.channel.send_command("del_device_from_phy", [device_id, phy_id]) + + def move_in_range(self): + """Move the connected devices to the same point to ensure + the reconnection of previous links.""" + # Reconnect all devices to all phys. + # Beacons are only added back to LE phys. + (devices, phys) = self._read_device_list() + for (device_id, device_name) in devices: + target_phys = ["LOW_ENERGY"] + if device_name.startswith("hci_device"): + target_phys.append("BR_EDR") + + for (phy_id, phy_name, phy_devices) in phys: + if phy_name in target_phys and not device_id in phy_devices: + self.channel.send_command("add_device_to_phy", [device_id, phy_id]) + + def _read_device_list(self): + """Query the list of connected devices.""" + response = self.channel.send_command("list", []) + + devices = [] + phys = [] + category = None + + for line in response.split("\n"): line = line.strip() if not line: continue - if line[0].isdigit(): - # list entry - if curr_category is None or ":" not in line: - raise Exception("Failed to parse rootcanal device list output") - curr_category.append(line.split(":", 1)[1]) - else: - if line.endswith(":"): - line = line[:-1] - curr_category = [] - categories[line] = curr_category - return categories - - @staticmethod - def _parse_phy(raw): - transport, idxs = raw.split(":") - idxs = [int(x) for x in idxs.split(",") if x.strip()] - return transport, idxs - - def reconnect_phone(self): - raw_devices = None - try: - raw_devices = self.channel.send_command("list", []) - devices = self._parse_device_list(raw_devices) - - for dev_i, name in enumerate(devices["Devices"]): - # the default transports are always 0 and 1 - classic_phy = 0 - le_phy = 1 - if "beacon" in name: - target_phys = [le_phy] - elif "hci_device" in name: - target_phys = [classic_phy, le_phy] - else: - target_phys = [] - - for phy in target_phys: - if dev_i not in self._parse_phy(devices["Phys"][phy])[1]: - self.channel.send_command("add_device_to_phy", [dev_i, phy]) - except Exception as e: - print(raw_devices, e) - - def disconnect_phy(self): - # first, list all devices - devices = self.channel.send_command("list", []) - devices = self._parse_device_list(devices) - dev_phys = [] - - for phy_i, phy in enumerate(devices["Phys"]): - _, idxs = self._parse_phy(phy) - - for dev_i in idxs: - dev_phys.append((dev_i, phy_i)) - - # now, disconnect all pairs - for dev_i, phy_i in dev_phys: - self.channel.send_command("del_device_from_phy", [dev_i, phy_i]) - - devices = self.channel.send_command("list", []) - devices = self._parse_device_list(devices) - - self.disconnected_dev_phys = dev_phys - - def reconnect_phy_if_needed(self): - if self.disconnected_dev_phys is not None: - for dev_i, phy_i in self.disconnected_dev_phys: - self.channel.send_command("add_device_to_phy", [dev_i, phy_i]) - - self.disconnected_dev_phys = None - - def reconnect_phy(self): - if self.disconnected_dev_phys is None: - raise Exception("cannot reconnect_phy before disconnect_phy") - - self.reconnect_phy_if_needed() + if line.startswith("Devices") or line.startswith("Phys"): + category = line.split(":")[0] + elif category == "Devices": + parts = line.split(":") + device_id = int(parts[0]) + device_name = parts[1] + devices.append((device_id, device_name)) + elif category == "Phys": + parts = line.split(":") + phy_id = int(parts[0]) + phy_name = parts[1] + phy_devices = [int(id.strip()) for id in parts[2].split(",") if id.strip()] + phys.append((phy_id, phy_name, phy_devices)) + + return (devices, phys) diff --git a/android/pandora/mmi2grpc/mmi2grpc/a2dp.py b/android/pandora/mmi2grpc/mmi2grpc/a2dp.py index 5703f95504..a17e1035b7 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/a2dp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/a2dp.py @@ -21,7 +21,6 @@ from grpc import RpcError from mmi2grpc._audio import AudioSignal from mmi2grpc._helpers import assert_description, match_description from mmi2grpc._proxy import ProfileProxy -from mmi2grpc._rootcanal import RootCanal from pandora.a2dp_grpc import A2DP from pandora.a2dp_pb2 import Sink, Source, PlaybackAudioRequest from pandora.host_grpc import Host @@ -164,7 +163,8 @@ class A2DPProxy(ProfileProxy): Action: This can be also be done by placing the IUT or PTS in an RF shielded box. """ - self.rootcanal.disconnect_phy() + + self.rootcanal.move_out_of_range() return "OK" @@ -396,7 +396,8 @@ class A2DPProxy(ProfileProxy): Action: Press OK when the IUT is ready to accept Bluetooth connections again. """ - self.rootcanal.reconnect_phy_if_needed() + + self.rootcanal.move_in_range() return "OK" diff --git a/android/pandora/mmi2grpc/mmi2grpc/hfp.py b/android/pandora/mmi2grpc/mmi2grpc/hfp.py index f0c10fe038..d420097e5d 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/hfp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/hfp.py @@ -868,7 +868,7 @@ class HFPProxy(ProfileProxy): def shield_iut_or_pts(): time.sleep(2) - self.rootcanal.disconnect_phy() + self.rootcanal.move_out_of_range() threading.Thread(target=shield_iut_or_pts).start() @@ -884,7 +884,7 @@ class HFPProxy(ProfileProxy): def shield_open(): time.sleep(2) - self.rootcanal.reconnect_phy_if_needed() + self.rootcanal.move_in_range() threading.Thread(target=shield_open).start() diff --git a/android/pandora/mmi2grpc/mmi2grpc/hid.py b/android/pandora/mmi2grpc/mmi2grpc/hid.py index 67a98a2198..886e1267ec 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/hid.py +++ b/android/pandora/mmi2grpc/mmi2grpc/hid.py @@ -6,7 +6,6 @@ from mmi2grpc._proxy import ProfileProxy from pandora_experimental.hid_grpc import HID from pandora.host_grpc import Host from pandora_experimental.hid_pb2 import HID_REPORT_TYPE_OUTPUT -from mmi2grpc._rootcanal import RootCanal class HIDProxy(ProfileProxy): @@ -25,7 +24,7 @@ class HIDProxy(ProfileProxy): PTS. """ - self.rootcanal.reconnect_phy_if_needed() + self.rootcanal.move_in_range() self.connection = self.host.Connect(address=pts_addr).connection return "OK" @@ -46,7 +45,7 @@ class HIDProxy(ProfileProxy): # Performing out of range action def disconnect(): sleep(2) - self.rootcanal.disconnect_phy() + self.rootcanal.move_out_of_range() Thread(target=disconnect).start() @@ -74,7 +73,7 @@ class HIDProxy(ProfileProxy): Please prepare the IUT to accept connection from PTS and then click OK. """ - self.rootcanal.reconnect_phy_if_needed() + self.rootcanal.move_in_range() return "OK" @@ -84,7 +83,7 @@ class HIDProxy(ProfileProxy): Make the Implementation Under Test (IUT) connectable, then click Ok. """ - self.rootcanal.reconnect_phy_if_needed() + self.rootcanal.move_in_range() return "OK" @@ -167,7 +166,7 @@ class HIDProxy(ProfileProxy): def disconnect(): sleep(2) - self.rootcanal.disconnect_phy() + self.rootcanal.move_out_of_range() Thread(target=disconnect).start() @@ -182,7 +181,7 @@ class HIDProxy(ProfileProxy): def connect(): sleep(1) - self.rootcanal.reconnect_phy_if_needed() + self.rootcanal.move_in_range() self.connection = self.host.Connect(address=pts_addr).connection Thread(target=connect).start() diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java index 2ebaf208d0..7abd2a1187 100644 --- a/framework/java/android/bluetooth/BluetoothAdapter.java +++ b/framework/java/android/bluetooth/BluetoothAdapter.java @@ -1902,7 +1902,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -1952,7 +1952,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -1981,7 +1981,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -2028,7 +2028,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -2620,7 +2620,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -2654,7 +2654,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -2689,7 +2689,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -2727,7 +2727,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -4252,14 +4252,14 @@ public final class BluetoothAdapter { try { sService = mManagerService.registerAdapter(sManagerCallback); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } else { try { mManagerService.unregisterAdapter(sManagerCallback); sService = null; } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } sServiceRegistered = wantRegistered; @@ -5058,7 +5058,7 @@ public final class BluetoothAdapter { } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { @@ -5123,7 +5123,7 @@ public final class BluetoothAdapter { } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { @@ -5186,7 +5186,7 @@ public final class BluetoothAdapter { } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { @@ -5271,7 +5271,7 @@ public final class BluetoothAdapter { .getValue(defaultValue); } } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { @@ -5352,7 +5352,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } @@ -5470,7 +5470,7 @@ public final class BluetoothAdapter { .getValue(defaultValue); } } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { @@ -5550,7 +5550,7 @@ public final class BluetoothAdapter { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } finally { mServiceLock.readLock().unlock(); } diff --git a/framework/java/android/bluetooth/BluetoothCsipSetCoordinator.java b/framework/java/android/bluetooth/BluetoothCsipSetCoordinator.java index b9e3bf70e9..112ba204e5 100644 --- a/framework/java/android/bluetooth/BluetoothCsipSetCoordinator.java +++ b/framework/java/android/bluetooth/BluetoothCsipSetCoordinator.java @@ -285,7 +285,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -318,7 +318,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -349,7 +349,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -380,7 +380,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -406,7 +406,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -433,7 +433,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -459,7 +459,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -498,7 +498,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -533,7 +533,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index 4bcd959c6e..514d510047 100644 --- a/framework/java/android/bluetooth/BluetoothDevice.java +++ b/framework/java/android/bluetooth/BluetoothDevice.java @@ -1765,7 +1765,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { Log.e(TAG, "", e); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -2202,7 +2202,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { Log.e(TAG, "", e); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -2249,7 +2249,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { Log.e(TAG, "", e); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -3497,7 +3497,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { Log.e(TAG, "", e); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; diff --git a/framework/java/android/bluetooth/BluetoothGatt.java b/framework/java/android/bluetooth/BluetoothGatt.java index 90922a802b..d602f7d281 100644 --- a/framework/java/android/bluetooth/BluetoothGatt.java +++ b/framework/java/android/bluetooth/BluetoothGatt.java @@ -1498,7 +1498,7 @@ public final class BluetoothGatt implements BluetoothProfile { synchronized (mDeviceBusyLock) { mDeviceBusy = false; } - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } return requestStatus; @@ -1641,7 +1641,7 @@ public final class BluetoothGatt implements BluetoothProfile { synchronized (mDeviceBusyLock) { mDeviceBusy = false; } - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } return BluetoothStatusCodes.ERROR_UNKNOWN; } diff --git a/framework/java/android/bluetooth/BluetoothGattServer.java b/framework/java/android/bluetooth/BluetoothGattServer.java index 386165d3ee..5f2f5d29f3 100644 --- a/framework/java/android/bluetooth/BluetoothGattServer.java +++ b/framework/java/android/bluetooth/BluetoothGattServer.java @@ -855,7 +855,7 @@ public final class BluetoothGattServer implements BluetoothProfile { return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND; } catch (RemoteException e) { Log.e(TAG, "", e); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } diff --git a/framework/java/android/bluetooth/BluetoothHapClient.java b/framework/java/android/bluetooth/BluetoothHapClient.java index f9ff30807a..f17cbf57df 100644 --- a/framework/java/android/bluetooth/BluetoothHapClient.java +++ b/framework/java/android/bluetooth/BluetoothHapClient.java @@ -591,7 +591,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -644,7 +644,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -686,7 +686,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -725,7 +725,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -759,7 +759,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -794,7 +794,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -827,7 +827,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -869,7 +869,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -901,7 +901,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -936,7 +936,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -969,7 +969,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.selectPreset(device, presetIndex, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1005,7 +1005,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.selectPresetForGroup(groupId, presetIndex, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1033,7 +1033,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.switchToNextPreset(device, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1063,7 +1063,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.switchToNextPresetForGroup(groupId, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1091,7 +1091,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.switchToPreviousPreset(device, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1121,7 +1121,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.switchToPreviousPresetForGroup(groupId, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1155,7 +1155,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -1189,7 +1189,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -1221,7 +1221,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -1348,7 +1348,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.setPresetName(device, presetIndex, name, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1383,7 +1383,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable try { service.setPresetNameForGroup(groupId, presetIndex, name, mAttributionSource); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } diff --git a/framework/java/android/bluetooth/BluetoothHeadset.java b/framework/java/android/bluetooth/BluetoothHeadset.java index 4241fff489..6a130fb506 100644 --- a/framework/java/android/bluetooth/BluetoothHeadset.java +++ b/framework/java/android/bluetooth/BluetoothHeadset.java @@ -852,7 +852,7 @@ public final class BluetoothHeadset implements BluetoothProfile { return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); return BluetoothStatusCodes.ERROR_TIMEOUT; @@ -919,7 +919,7 @@ public final class BluetoothHeadset implements BluetoothProfile { return BluetoothStatusCodes.ERROR_TIMEOUT; } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -959,7 +959,7 @@ public final class BluetoothHeadset implements BluetoothProfile { return BluetoothStatusCodes.ERROR_TIMEOUT; } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -1044,7 +1044,7 @@ public final class BluetoothHeadset implements BluetoothProfile { return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); return BluetoothStatusCodes.ERROR_TIMEOUT; @@ -1099,7 +1099,7 @@ public final class BluetoothHeadset implements BluetoothProfile { return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); return BluetoothStatusCodes.ERROR_TIMEOUT; diff --git a/framework/java/android/bluetooth/BluetoothHeadsetClient.java b/framework/java/android/bluetooth/BluetoothHeadsetClient.java index 2f11cbf04d..303b1fa684 100644 --- a/framework/java/android/bluetooth/BluetoothHeadsetClient.java +++ b/framework/java/android/bluetooth/BluetoothHeadsetClient.java @@ -873,7 +873,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile, AutoClose mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -910,7 +910,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile, AutoClose mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -943,7 +943,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile, AutoClose return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -1004,7 +1004,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile, AutoClose return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -1062,7 +1062,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile, AutoClose return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java index 1f749be4eb..ce0cd1023d 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudio.java +++ b/framework/java/android/bluetooth/BluetoothLeAudio.java @@ -961,7 +961,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -1013,7 +1013,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -1281,7 +1281,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -1432,7 +1432,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -1474,7 +1474,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcast.java b/framework/java/android/bluetooth/BluetoothLeBroadcast.java index d724335d3b..6fae30750b 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcast.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcast.java @@ -449,7 +449,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -502,7 +502,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException | IllegalStateException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } @@ -574,7 +574,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (SecurityException e) { throw e; } @@ -614,7 +614,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (SecurityException e) { throw e; } @@ -663,7 +663,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (SecurityException e) { throw e; } @@ -709,7 +709,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (SecurityException e) { throw e; } @@ -751,7 +751,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (SecurityException e) { throw e; } @@ -786,7 +786,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -820,7 +820,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -848,7 +848,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -877,7 +877,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; @@ -909,7 +909,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } return defaultValue; diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java index 2fe4b6194a..20166e8937 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java @@ -732,7 +732,7 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, Au service.registerCallback(mCallback); } } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } @@ -780,7 +780,7 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, Au service.unregisterCallback(mCallback); } } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } } diff --git a/framework/java/android/bluetooth/BluetoothMapClient.java b/framework/java/android/bluetooth/BluetoothMapClient.java index f4f1301e76..bf9fd7e4f3 100644 --- a/framework/java/android/bluetooth/BluetoothMapClient.java +++ b/framework/java/android/bluetooth/BluetoothMapClient.java @@ -369,7 +369,7 @@ public final class BluetoothMapClient implements BluetoothProfile, AutoCloseable mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -406,7 +406,7 @@ public final class BluetoothMapClient implements BluetoothProfile, AutoCloseable mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -439,7 +439,7 @@ public final class BluetoothMapClient implements BluetoothProfile, AutoCloseable return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -503,7 +503,7 @@ public final class BluetoothMapClient implements BluetoothProfile, AutoCloseable return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -562,7 +562,7 @@ public final class BluetoothMapClient implements BluetoothProfile, AutoCloseable return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } diff --git a/framework/java/android/bluetooth/BluetoothPbapClient.java b/framework/java/android/bluetooth/BluetoothPbapClient.java index cdec02fb18..139c6ddf0e 100644 --- a/framework/java/android/bluetooth/BluetoothPbapClient.java +++ b/framework/java/android/bluetooth/BluetoothPbapClient.java @@ -247,7 +247,7 @@ public final class BluetoothPbapClient implements BluetoothProfile, AutoCloseabl mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -286,7 +286,7 @@ public final class BluetoothPbapClient implements BluetoothProfile, AutoCloseabl mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -321,7 +321,7 @@ public final class BluetoothPbapClient implements BluetoothProfile, AutoCloseabl return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -399,7 +399,7 @@ public final class BluetoothPbapClient implements BluetoothProfile, AutoCloseabl return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -460,7 +460,7 @@ public final class BluetoothPbapClient implements BluetoothProfile, AutoCloseabl return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } diff --git a/framework/java/android/bluetooth/BluetoothVolumeControl.java b/framework/java/android/bluetooth/BluetoothVolumeControl.java index 8f16ae3b40..f119dc0ba0 100644 --- a/framework/java/android/bluetooth/BluetoothVolumeControl.java +++ b/framework/java/android/bluetooth/BluetoothVolumeControl.java @@ -189,6 +189,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + // IBluetoothManager run in the system server throw e.rethrowFromSystemServer(); } } @@ -370,7 +371,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -421,7 +422,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } catch (IllegalStateException | TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java index 5212360c32..9be1a881cc 100644 --- a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java +++ b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java @@ -167,7 +167,7 @@ public final class DistanceMeasurementManager { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); return null; } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } } diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementSession.java b/framework/java/android/bluetooth/le/DistanceMeasurementSession.java index d88dba4c8c..538a047b78 100644 --- a/framework/java/android/bluetooth/le/DistanceMeasurementSession.java +++ b/framework/java/android/bluetooth/le/DistanceMeasurementSession.java @@ -115,7 +115,7 @@ public final class DistanceMeasurementSession { } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw e.rethrowAsRuntimeException(); } return defaultValue; } diff --git a/service/src/com/android/server/bluetooth/AdapterBinder.kt b/service/src/com/android/server/bluetooth/AdapterBinder.kt index 0034a4f29e..eaef038cc6 100644 --- a/service/src/com/android/server/bluetooth/AdapterBinder.kt +++ b/service/src/com/android/server/bluetooth/AdapterBinder.kt @@ -21,6 +21,7 @@ import android.bluetooth.IBluetoothCallback import android.content.AttributionSource import android.os.IBinder import android.os.RemoteException +import android.util.Log import com.android.modules.utils.SynchronousResultReceiver import com.android.server.bluetooth.BluetoothManagerService.timeToLog import java.time.Duration @@ -29,6 +30,7 @@ import java.util.concurrent.TimeoutException val SYNC_TIMEOUT = Duration.ofSeconds(3) class AdapterBinder(rawBinder: IBinder) { + private val TAG = "AdapterBinder" val adapterBinder: IBluetooth = IBluetooth.Stub.asInterface(rawBinder) val createdAt = System.currentTimeMillis() @@ -116,4 +118,21 @@ class AdapterBinder(rawBinder: IBinder) { adapterBinder.unregAllGattClient(source, recv) recv.awaitResultNoInterrupt(SYNC_TIMEOUT).getValue(null) } + + fun isMediaProfileConnected(source: AttributionSource): Boolean { + try { + val recv: SynchronousResultReceiver<Boolean> = SynchronousResultReceiver.get() + adapterBinder.isMediaProfileConnected(source, recv) + return recv.awaitResultNoInterrupt(SYNC_TIMEOUT).getValue(false) + } catch (ex: Exception) { + when (ex) { + is RemoteException, + is TimeoutException -> { + Log.e(TAG, "Error when calling isMediaProfileConnected", ex) + } + else -> throw ex + } + return false + } + } } diff --git a/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java b/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java index 4dbfabc792..a9f71fe9e2 100644 --- a/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java +++ b/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java @@ -184,8 +184,9 @@ class BluetoothAirplaneModeListener extends Handler { if (isAirplaneModeOn) { mApmEnabledTime = SystemClock.elapsedRealtime(); mIsBluetoothOnBeforeApmToggle = mAirplaneHelper.isBluetoothOn(); - mIsBluetoothOnAfterApmToggle = shouldSkipAirplaneModeChange(); - mIsMediaProfileConnectedBeforeApmToggle = mAirplaneHelper.isMediaProfileConnected(); + mIsMediaProfileConnectedBeforeApmToggle = mBluetoothManager.isMediaProfileConnected(); + mIsBluetoothOnAfterApmToggle = + shouldSkipAirplaneModeChange(mIsMediaProfileConnectedBeforeApmToggle); if (mIsBluetoothOnAfterApmToggle) { Log.i(TAG, "Ignore airplane mode change"); // Airplane mode enabled when Bluetooth is being used for audio/hearing aid. @@ -244,14 +245,12 @@ class BluetoothAirplaneModeListener extends Handler { } @VisibleForTesting - boolean shouldSkipAirplaneModeChange() { + boolean shouldSkipAirplaneModeChange(boolean isMediaProfileConnected) { boolean apmEnhancementUsed = isApmEnhancementEnabled() && isBluetoothToggledOnApm(); // APM feature disabled or user has not used the feature yet by changing BT state in APM // BT will only remain on in APM when media profile is connected - if (!apmEnhancementUsed - && mAirplaneHelper.isBluetoothOn() - && mAirplaneHelper.isMediaProfileConnected()) { + if (!apmEnhancementUsed && mAirplaneHelper.isBluetoothOn() && isMediaProfileConnected) { return true; } // APM feature enabled and user has used the feature by changing BT state in APM diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index f95ff2ac3f..c70da373c7 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -24,9 +24,7 @@ import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF; import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; - import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_ENHANCEMENT; - import static java.util.Objects.requireNonNull; import android.annotation.NonNull; @@ -215,8 +213,6 @@ class BluetoothManagerService { private List<Integer> mSupportedProfileList = new ArrayList<>(); - private BluetoothModeChangeHelper mBluetoothModeChangeHelper; - private final BluetoothAirplaneModeListener mBluetoothAirplaneModeListener; private BluetoothNotificationManager mBluetoothNotificationManager; @@ -972,6 +968,13 @@ class BluetoothManagerService { return mIsHearingAidProfileSupported; } + boolean isMediaProfileConnected() { + if (mAdapter == null || !mState.oneOf(STATE_ON)) { + return false; + } + return mAdapter.isMediaProfileConnected(mContext.getAttributionSource()); + } + // Monitor change of BLE scan only mode settings. private void registerForBleScanModeChange() { ContentObserver contentObserver = @@ -1459,10 +1462,7 @@ class BluetoothManagerService { mHandler.sendEmptyMessage(MESSAGE_GET_NAME_AND_ADDRESS); } - mBluetoothModeChangeHelper = new BluetoothModeChangeHelper(mContext); - if (mBluetoothAirplaneModeListener != null) { - mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper); - } + mBluetoothAirplaneModeListener.start(new BluetoothModeChangeHelper(mContext)); setApmEnhancementState(); } diff --git a/service/src/com/android/server/bluetooth/BluetoothModeChangeHelper.java b/service/src/com/android/server/bluetooth/BluetoothModeChangeHelper.java index a7560be95a..0434a8c637 100644 --- a/service/src/com/android/server/bluetooth/BluetoothModeChangeHelper.java +++ b/service/src/com/android/server/bluetooth/BluetoothModeChangeHelper.java @@ -19,12 +19,7 @@ package com.android.server.bluetooth; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.BLUETOOTH_APM_STATE; import android.app.ActivityManager; -import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothHearingAid; -import android.bluetooth.BluetoothLeAudio; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothProfile.ServiceListener; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -41,11 +36,8 @@ import com.android.internal.annotations.VisibleForTesting; * complex logic. */ public class BluetoothModeChangeHelper { - private static final String TAG = "BluetoothModeChangeHelper"; + private static final String TAG = BluetoothModeChangeHelper.class.getSimpleName(); - private volatile BluetoothA2dp mA2dp; - private volatile BluetoothHearingAid mHearingAid; - private volatile BluetoothLeAudio mLeAudio; private final BluetoothAdapter mAdapter; private final Context mContext; @@ -54,54 +46,6 @@ public class BluetoothModeChangeHelper { BluetoothModeChangeHelper(Context context) { mAdapter = BluetoothAdapter.getDefaultAdapter(); mContext = context; - - mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP); - mAdapter.getProfileProxy(mContext, mProfileServiceListener, - BluetoothProfile.HEARING_AID); - mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.LE_AUDIO); - } - - private final ServiceListener mProfileServiceListener = new ServiceListener() { - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - // Setup Bluetooth profile proxies - switch (profile) { - case BluetoothProfile.A2DP: - mA2dp = (BluetoothA2dp) proxy; - break; - case BluetoothProfile.HEARING_AID: - mHearingAid = (BluetoothHearingAid) proxy; - break; - case BluetoothProfile.LE_AUDIO: - mLeAudio = (BluetoothLeAudio) proxy; - break; - default: - break; - } - } - - @Override - public void onServiceDisconnected(int profile) { - // Clear Bluetooth profile proxies - switch (profile) { - case BluetoothProfile.A2DP: - mA2dp = null; - break; - case BluetoothProfile.HEARING_AID: - mHearingAid = null; - break; - case BluetoothProfile.LE_AUDIO: - mLeAudio = null; - break; - default: - break; - } - } - }; - - @VisibleForTesting - public boolean isMediaProfileConnected() { - return isA2dpConnected() || isHearingAidConnected() || isLeAudioConnected(); } @VisibleForTesting @@ -151,30 +95,6 @@ public class BluetoothModeChangeHelper { Toast.makeText(mContext, text, Toast.LENGTH_LONG).show(); } - private boolean isA2dpConnected() { - final BluetoothA2dp a2dp = mA2dp; - if (a2dp == null) { - return false; - } - return a2dp.getConnectedDevices().size() > 0; - } - - private boolean isHearingAidConnected() { - final BluetoothHearingAid hearingAid = mHearingAid; - if (hearingAid == null) { - return false; - } - return hearingAid.getConnectedDevices().size() > 0; - } - - private boolean isLeAudioConnected() { - final BluetoothLeAudio leAudio = mLeAudio; - if (leAudio == null) { - return false; - } - return leAudio.getConnectedDevices().size() > 0; - } - /** * Helper method to check whether BT should be enabled on APM */ diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java index 7449aaaa52..654b90319c 100644 --- a/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java +++ b/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java @@ -25,7 +25,6 @@ import static com.android.server.bluetooth.BluetoothAirplaneModeListener.NOTIFIC import static com.android.server.bluetooth.BluetoothAirplaneModeListener.UNUSED; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.USED; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.WIFI_APM_STATE; - import static org.mockito.Mockito.*; import android.content.Context; @@ -74,13 +73,13 @@ public class BluetoothAirplaneModeListenerTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mContentResolver = new MockContentResolver(); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); + when(mHelper.getSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT)) .thenReturn(BluetoothAirplaneModeListener.MAX_TOAST_COUNT); - doNothing().when(mHelper).setSettingsInt(anyString(), anyInt()); - doNothing().when(mHelper).showToastMessage(); BluetoothServerProxy.setInstanceForTesting(mBluetoothServerProxy); @@ -92,13 +91,12 @@ public class BluetoothAirplaneModeListenerTest { @Test public void testIgnoreOnAirplanModeChange() { - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); when(mHelper.isBluetoothOn()).thenReturn(true); - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); - when(mHelper.isMediaProfileConnected()).thenReturn(true); - Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(true)); } @Test @@ -107,50 +105,45 @@ public class BluetoothAirplaneModeListenerTest { // When APM enhancement is disabled, BT remains on when connected to a media profile when(mHelper.getSettingsInt(APM_ENHANCEMENT)).thenReturn(0); - when(mHelper.isMediaProfileConnected()).thenReturn(true); - Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(true)); // When APM enhancement is disabled, BT turns off when not connected to a media profile - when(mHelper.isMediaProfileConnected()).thenReturn(false); - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); // When APM enhancement is enabled but not activated by toggling BT in APM, // BT remains on when connected to a media profile when(mHelper.getSettingsInt(APM_ENHANCEMENT)).thenReturn(1); when(mHelper.getSettingsSecureInt(APM_USER_TOGGLED_BLUETOOTH, UNUSED)).thenReturn(UNUSED); - when(mHelper.isMediaProfileConnected()).thenReturn(true); - Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(true)); // When APM enhancement is enabled but not activated by toggling BT in APM, // BT turns off when not connected to a media profile - when(mHelper.isMediaProfileConnected()).thenReturn(false); - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); // When APM enhancement is enabled but not activated by toggling BT in APM, // BT remains on when the default value for BT in APM is on when(mHelper.isBluetoothOnAPM()).thenReturn(true); - Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); // When APM enhancement is enabled but not activated by toggling BT in APM, // BT remains off when the default value for BT in APM is off when(mHelper.isBluetoothOnAPM()).thenReturn(false); - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); // When APM enhancement is enabled and activated by toggling BT in APM, // BT remains on if user's last choice in APM was on when(mHelper.getSettingsSecureInt(APM_USER_TOGGLED_BLUETOOTH, UNUSED)).thenReturn(USED); when(mHelper.isBluetoothOnAPM()).thenReturn(true); - Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); // When APM enhancement is enabled and activated by toggling BT in APM, // BT turns off if user's last choice in APM was off when(mHelper.isBluetoothOnAPM()).thenReturn(false); - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(false)); // When APM enhancement is enabled and activated by toggling BT in APM, // BT turns off if user's last choice in APM was off even when connected to a media profile - when(mHelper.isMediaProfileConnected()).thenReturn(true); - Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange()); + Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange(true)); } @Test @@ -163,7 +156,7 @@ public class BluetoothAirplaneModeListenerTest { public void testHandleAirplaneModeChange_NotInvokeAirplaneModeChanged_NotPopToast() { mBluetoothAirplaneModeListener.mToastCount = BluetoothAirplaneModeListener.MAX_TOAST_COUNT; when(mHelper.isBluetoothOn()).thenReturn(true); - when(mHelper.isMediaProfileConnected()).thenReturn(true); + when(mBluetoothManagerService.isMediaProfileConnected()).thenReturn(true); mBluetoothAirplaneModeListener.handleAirplaneModeChange(true); verify(mHelper).setSettingsInt(Settings.Global.BLUETOOTH_ON, @@ -176,7 +169,7 @@ public class BluetoothAirplaneModeListenerTest { public void testHandleAirplaneModeChange_NotInvokeAirplaneModeChanged_PopToast() { mBluetoothAirplaneModeListener.mToastCount = 0; when(mHelper.isBluetoothOn()).thenReturn(true); - when(mHelper.isMediaProfileConnected()).thenReturn(true); + when(mBluetoothManagerService.isMediaProfileConnected()).thenReturn(true); mBluetoothAirplaneModeListener.handleAirplaneModeChange(true); verify(mHelper).setSettingsInt(Settings.Global.BLUETOOTH_ON, diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothModeChangeHelperTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothModeChangeHelperTest.java index 78ad120476..3861896ac2 100644 --- a/service/tests/src/com/android/server/bluetooth/BluetoothModeChangeHelperTest.java +++ b/service/tests/src/com/android/server/bluetooth/BluetoothModeChangeHelperTest.java @@ -54,11 +54,6 @@ public class BluetoothModeChangeHelperTest { } @Test - public void isMediaProfileConnected() { - assertThat(mHelper.isMediaProfileConnected()).isFalse(); - } - - @Test public void isBluetoothOn_doesNotCrash() { // assertThat(mHelper.isBluetoothOn()).isFalse(); // TODO: Strangely, isBluetoothOn() does not call BluetoothAdapter.isEnabled(). diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl index 485262b6fa..0ab8874fc0 100644 --- a/system/binder/android/bluetooth/IBluetooth.aidl +++ b/system/binder/android/bluetooth/IBluetooth.aidl @@ -301,6 +301,9 @@ interface IBluetooth @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") oneway void getOffloadedTransportDiscoveryDataScanSupported(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + oneway void isMediaProfileConnected(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") IBluetoothGatt getBluetoothGatt(); diff --git a/system/bta/le_audio/devices.cc b/system/bta/le_audio/devices.cc index fbaa0f1938..5cf224c162 100644 --- a/system/bta/le_audio/devices.cc +++ b/system/bta/le_audio/devices.cc @@ -1413,6 +1413,18 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported( } } + // when disabling 32k dual mic, for later join case, we need to + // make sure the device is always choosing the config that its + // sampling rate matches with the sampling rate which is used + // when all devices in the group are connected. + bool dual_bidirection_swb_supported_ = osi_property_get_bool( + "bluetooth.leaudio.dual_bidirection_swb.supported", true); + if (Size() > 1 && !dual_bidirection_swb_supported_ && + AudioSetConfigurationProvider::Get()->CheckConfigurationIsBiDirSwb( + *audio_set_conf)) { + return false; + } + LOG_DEBUG("Chosen ASE Configuration for group: %d, configuration: %s", this->group_id_, audio_set_conf->name.c_str()); return true; diff --git a/system/bta/le_audio/le_audio_set_configuration_provider.h b/system/bta/le_audio/le_audio_set_configuration_provider.h index 8ece4f2179..8e013652e7 100644 --- a/system/bta/le_audio/le_audio_set_configuration_provider.h +++ b/system/bta/le_audio/le_audio_set_configuration_provider.h @@ -32,6 +32,8 @@ class AudioSetConfigurationProvider { static void Cleanup(); virtual const set_configurations::AudioSetConfigurations* GetConfigurations( ::le_audio::types::LeAudioContextType content_type) const; + virtual bool CheckConfigurationIsBiDirSwb( + const set_configurations::AudioSetConfiguration& set_configuration) const; private: struct impl; diff --git a/system/bta/le_audio/le_audio_set_configuration_provider_json.cc b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc index bfcfc6b5fb..cafe675663 100644 --- a/system/bta/le_audio/le_audio_set_configuration_provider_json.cc +++ b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc @@ -71,10 +71,8 @@ struct AudioSetConfigurationProviderJson { static constexpr auto kDefaultScenario = "Media"; AudioSetConfigurationProviderJson(types::CodecLocation location) { - dual_swb_bidirection_supported_ = osi_property_get_bool( - "persist.bluetooth.leaudio_dual_bidirection_swb." - "supported", - true); + dual_bidirection_swb_supported_ = osi_property_get_bool( + "bluetooth.leaudio.dual_bidirection_swb.supported", true); ASSERT_LOG(LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios, location), ": Unable to load le audio set configuration files."); } @@ -166,7 +164,7 @@ struct AudioSetConfigurationProviderJson { /* property to check if bidirectional sampling frequency >= 32k dual mic is * supported or not */ - bool dual_swb_bidirection_supported_; + bool dual_bidirection_swb_supported_; static const bluetooth::le_audio::CodecSpecificConfiguration* LookupCodecSpecificParam( @@ -435,7 +433,7 @@ struct AudioSetConfigurationProviderJson { } } - if (!dual_swb_bidirection_supported_) { + if (!dual_bidirection_swb_supported_) { if ((dual_dev_one_chan_stereo_sink_swb && dual_dev_one_chan_stereo_source_swb) || (single_dev_one_chan_stereo_sink_swb && @@ -525,9 +523,11 @@ struct AudioSetConfigurationProviderJson { LOG_DEBUG(": Updating %d config entries.", flat_configs->size()); for (auto const& flat_cfg : *flat_configs) { - configurations_.insert({flat_cfg->name()->str(), - AudioSetConfigurationFromFlat( - flat_cfg, &codec_cfgs, &qos_cfgs, location)}); + auto configuration = AudioSetConfigurationFromFlat(flat_cfg, &codec_cfgs, + &qos_cfgs, location); + if (!configuration.confs.empty()) { + configurations_.insert({flat_cfg->name()->str(), configuration}); + } } return true; @@ -740,4 +740,17 @@ AudioSetConfigurationProvider::GetConfigurations( return nullptr; } +bool AudioSetConfigurationProvider::CheckConfigurationIsBiDirSwb( + const set_configurations::AudioSetConfiguration& set_configuration) const { + uint8_t dir = 0; + + for (const auto& conf : set_configuration.confs) { + if (conf.codec.GetConfigSamplingFrequency() >= + le_audio::LeAudioCodecConfiguration::kSampleRate32000) { + dir |= conf.direction; + } + } + return dir == le_audio::types::kLeAudioDirectionBoth; +} + } // namespace le_audio diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h index c5ccdc836c..764fb17d9d 100644 --- a/system/btif/include/btif_common.h +++ b/system/btif/include/btif_common.h @@ -171,7 +171,7 @@ base::Callback<R(Args...)> jni_thread_wrapper(const base::Location& from_here, [](const base::Location& from_here, base::Callback<R(Args...)> cb, Args... args) { do_in_jni_thread(from_here, - base::Bind(cb, std::forward<Args>(args)...)); + base::BindOnce(cb, std::forward<Args>(args)...)); }, from_here, std::move(cb)); } diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index 176e886624..6b3ef639bf 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -980,16 +980,18 @@ static bt_os_callouts_t* wakelock_os_callouts_saved = nullptr; static int acquire_wake_lock_cb(const char* lock_name) { return do_in_jni_thread( - FROM_HERE, base::Bind(base::IgnoreResult( - wakelock_os_callouts_saved->acquire_wake_lock), - lock_name)); + FROM_HERE, + base::BindOnce( + base::IgnoreResult(wakelock_os_callouts_saved->acquire_wake_lock), + lock_name)); } static int release_wake_lock_cb(const char* lock_name) { return do_in_jni_thread( - FROM_HERE, base::Bind(base::IgnoreResult( - wakelock_os_callouts_saved->release_wake_lock), - lock_name)); + FROM_HERE, + base::BindOnce( + base::IgnoreResult(wakelock_os_callouts_saved->release_wake_lock), + lock_name)); } static bt_os_callouts_t wakelock_os_callouts_jni = { diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index 37e0f42ab2..0853964f53 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -2930,12 +2930,14 @@ static void btif_report_connection_state(const RawAddress& peer_address, if (peer->IsSink()) { do_in_jni_thread( - FROM_HERE, base::Bind(btif_av_source.Callbacks()->connection_state_cb, - peer_address, state, btav_error_t{})); + FROM_HERE, + base::BindOnce(btif_av_source.Callbacks()->connection_state_cb, + peer_address, state, btav_error_t{})); } else if (peer->IsSource()) { - do_in_jni_thread(FROM_HERE, - base::Bind(btif_av_sink.Callbacks()->connection_state_cb, - peer_address, state, btav_error_t{})); + do_in_jni_thread( + FROM_HERE, + base::BindOnce(btif_av_sink.Callbacks()->connection_state_cb, + peer_address, state, btav_error_t{})); } return; } @@ -2943,15 +2945,15 @@ static void btif_report_connection_state(const RawAddress& peer_address, if (btif_av_source.Enabled()) { do_in_jni_thread( FROM_HERE, - base::Bind(btif_av_source.Callbacks()->connection_state_cb, - peer_address, state, - btav_error_t{.status = status, .error_code = error_code})); + base::BindOnce( + btif_av_source.Callbacks()->connection_state_cb, peer_address, + state, btav_error_t{.status = status, .error_code = error_code})); } else if (btif_av_sink.Enabled()) { do_in_jni_thread( FROM_HERE, - base::Bind(btif_av_sink.Callbacks()->connection_state_cb, peer_address, - state, - btav_error_t{.status = status, .error_code = error_code})); + base::BindOnce( + btif_av_sink.Callbacks()->connection_state_cb, peer_address, state, + btav_error_t{.status = status, .error_code = error_code})); } } @@ -2972,24 +2974,24 @@ static void btif_report_audio_state(const RawAddress& peer_address, if (btif_av_both_enable()) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer->IsSink()) { - do_in_jni_thread(FROM_HERE, - base::Bind(btif_av_source.Callbacks()->audio_state_cb, - peer_address, state)); + do_in_jni_thread( + FROM_HERE, base::BindOnce(btif_av_source.Callbacks()->audio_state_cb, + peer_address, state)); } else if (peer->IsSource()) { do_in_jni_thread(FROM_HERE, - base::Bind(btif_av_sink.Callbacks()->audio_state_cb, - peer_address, state)); + base::BindOnce(btif_av_sink.Callbacks()->audio_state_cb, + peer_address, state)); } return; } if (btif_av_source.Enabled()) { do_in_jni_thread(FROM_HERE, - base::Bind(btif_av_source.Callbacks()->audio_state_cb, - peer_address, state)); + base::BindOnce(btif_av_source.Callbacks()->audio_state_cb, + peer_address, state)); } else if (btif_av_sink.Enabled()) { do_in_jni_thread(FROM_HERE, - base::Bind(btif_av_sink.Callbacks()->audio_state_cb, - peer_address, state)); + base::BindOnce(btif_av_sink.Callbacks()->audio_state_cb, + peer_address, state)); } using android::bluetooth::a2dp::AudioCodingModeEnum; @@ -3024,9 +3026,9 @@ void btif_av_report_source_codec_state( if (btif_av_source.Enabled()) { do_in_jni_thread( FROM_HERE, - base::Bind(btif_av_source.Callbacks()->audio_config_cb, peer_address, - codec_config, codecs_local_capabilities, - codecs_selectable_capabilities)); + base::BindOnce(btif_av_source.Callbacks()->audio_config_cb, + peer_address, codec_config, codecs_local_capabilities, + codecs_selectable_capabilities)); } } @@ -3043,8 +3045,8 @@ static void btif_av_report_sink_audio_config_state( ADDRESS_TO_LOGGABLE_CSTR(peer_address), sample_rate, channel_count); if (btif_av_sink.Enabled()) { do_in_jni_thread(FROM_HERE, - base::Bind(btif_av_sink.Callbacks()->audio_config_cb, - peer_address, sample_rate, channel_count)); + base::BindOnce(btif_av_sink.Callbacks()->audio_config_cb, + peer_address, sample_rate, channel_count)); } } @@ -3419,8 +3421,9 @@ static void bta_av_event_callback(tBTA_AV_EVT event, tBTA_AV* p_data) { if (btif_av_both_enable()) { BtifAvEvent btif_av_event(event, p_data, sizeof(tBTA_AV)); do_in_main_thread( - FROM_HERE, base::Bind(&btif_av_handle_bta_av_event, - AVDT_TSEP_INVALID /* peer_sep */, btif_av_event)); + FROM_HERE, + base::BindOnce(&btif_av_handle_bta_av_event, + AVDT_TSEP_INVALID /* peer_sep */, btif_av_event)); return; } diff --git a/system/btif/src/btif_bqr.cc b/system/btif/src/btif_bqr.cc index 29404968cf..66d109d370 100644 --- a/system/btif/src/btif_bqr.cc +++ b/system/btif/src/btif_bqr.cc @@ -808,10 +808,10 @@ class BluetoothQualityReportInterfaceImpl do_in_jni_thread( FROM_HERE, - base::Bind(&bluetooth::bqr::BluetoothQualityReportCallbacks:: - bqr_delivery_callback, - base::Unretained(callbacks), bd_addr, lmp_ver, lmp_subver, - manufacturer_id, std::move(raw_data))); + base::BindOnce(&bluetooth::bqr::BluetoothQualityReportCallbacks:: + bqr_delivery_callback, + base::Unretained(callbacks), bd_addr, lmp_ver, + lmp_subver, manufacturer_id, std::move(raw_data))); } private: diff --git a/system/btif/src/btif_core.cc b/system/btif/src/btif_core.cc index 54e1b734b1..55532bdc73 100644 --- a/system/btif/src/btif_core.cc +++ b/system/btif/src/btif_core.cc @@ -153,7 +153,7 @@ bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */ } - return do_in_jni_thread(base::Bind(&bt_jni_msg_ready, p_msg)); + return do_in_jni_thread(base::BindOnce(&bt_jni_msg_ready, p_msg)); } /** @@ -180,8 +180,8 @@ bool is_on_jni_thread() { static void do_post_on_bt_jni(BtJniClosure closure) { closure(); } void post_on_bt_jni(BtJniClosure closure) { - ASSERT(do_in_jni_thread(FROM_HERE, - base::Bind(do_post_on_bt_jni, std::move(closure))) == + ASSERT(do_in_jni_thread(FROM_HERE, base::BindOnce(do_post_on_bt_jni, + std::move(closure))) == BT_STATUS_SUCCESS); } diff --git a/system/btif/src/btif_hf.cc b/system/btif/src/btif_hf.cc index 02cd97a7f6..21a2bde5e2 100644 --- a/system/btif/src/btif_hf.cc +++ b/system/btif/src/btif_hf.cc @@ -931,11 +931,11 @@ bt_status_t HeadsetInterface::ConnectAudio(RawAddress* bd_addr, << ADDRESS_TO_LOGGABLE_STR(*bd_addr); return BT_STATUS_NOT_READY; } - do_in_jni_thread(base::Bind(&Callbacks::AudioStateCallback, - // Manual pointer management for now - base::Unretained(bt_hf_callbacks), - BTHF_AUDIO_STATE_CONNECTING, - &btif_hf_cb[idx].connected_bda)); + do_in_jni_thread(base::BindOnce(&Callbacks::AudioStateCallback, + // Manual pointer management for now + base::Unretained(bt_hf_callbacks), + BTHF_AUDIO_STATE_CONNECTING, + &btif_hf_cb[idx].connected_bda)); BTA_AgAudioOpen(btif_hf_cb[idx].handle, disabled_codecs); DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(*bd_addr, IOT_CONF_KEY_HFP_SCO_CONN_COUNT); @@ -1538,7 +1538,8 @@ void HeadsetInterface::Cleanup() { } } - do_in_jni_thread(FROM_HERE, base::Bind([]() { bt_hf_callbacks = nullptr; })); + do_in_jni_thread(FROM_HERE, + base::BindOnce([]() { bt_hf_callbacks = nullptr; })); } bt_status_t HeadsetInterface::SetScoOffloadEnabled(bool value) { diff --git a/system/btif/src/btif_keystore.cc b/system/btif/src/btif_keystore.cc index a0796e7f9c..022c78bdc1 100644 --- a/system/btif/src/btif_keystore.cc +++ b/system/btif/src/btif_keystore.cc @@ -62,7 +62,7 @@ class BluetoothKeystoreInterfaceImpl return; } do_in_jni_thread( - FROM_HERE, base::Bind([]() { + FROM_HERE, base::BindOnce([]() { shim::BtifConfigInterface::ConvertEncryptOrDecryptKeyIfNeeded(); })); } @@ -79,10 +79,10 @@ class BluetoothKeystoreInterfaceImpl // Save the value into a map. key_map[prefix] = decryptedString; - do_in_jni_thread( - base::Bind(&bluetooth::bluetooth_keystore::BluetoothKeystoreCallbacks:: - set_encrypt_key_or_remove_key, - base::Unretained(callbacks), prefix, decryptedString)); + do_in_jni_thread(base::BindOnce( + &bluetooth::bluetooth_keystore::BluetoothKeystoreCallbacks:: + set_encrypt_key_or_remove_key, + base::Unretained(callbacks), prefix, decryptedString)); return true; } diff --git a/system/btif/src/btif_profile_queue.cc b/system/btif/src/btif_profile_queue.cc index 16f74a3d0b..32417f783d 100644 --- a/system/btif/src/btif_profile_queue.cc +++ b/system/btif/src/btif_profile_queue.cc @@ -152,8 +152,8 @@ static void queue_int_release() { connect_queue.clear(); } ******************************************************************************/ bt_status_t btif_queue_connect(uint16_t uuid, const RawAddress* bda, btif_connect_cb_t connect_cb) { - return do_in_jni_thread(FROM_HERE, - base::Bind(&queue_int_add, uuid, *bda, connect_cb)); + return do_in_jni_thread( + FROM_HERE, base::BindOnce(&queue_int_add, uuid, *bda, connect_cb)); } /******************************************************************************* @@ -166,7 +166,7 @@ bt_status_t btif_queue_connect(uint16_t uuid, const RawAddress* bda, * ******************************************************************************/ void btif_queue_cleanup(uint16_t uuid) { - do_in_jni_thread(FROM_HERE, base::Bind(&queue_int_cleanup, uuid)); + do_in_jni_thread(FROM_HERE, base::BindOnce(&queue_int_cleanup, uuid)); } /******************************************************************************* @@ -180,7 +180,7 @@ void btif_queue_cleanup(uint16_t uuid) { * ******************************************************************************/ void btif_queue_advance() { - do_in_jni_thread(FROM_HERE, base::Bind(&queue_int_advance)); + do_in_jni_thread(FROM_HERE, base::BindOnce(&queue_int_advance)); } bt_status_t btif_queue_connect_next(void) { @@ -215,7 +215,7 @@ bt_status_t btif_queue_connect_next(void) { ******************************************************************************/ void btif_queue_release() { LOG_INFO("%s", __func__); - if (do_in_jni_thread(FROM_HERE, base::Bind(&queue_int_release)) != + if (do_in_jni_thread(FROM_HERE, base::BindOnce(&queue_int_release)) != BT_STATUS_SUCCESS) { LOG(FATAL) << __func__ << ": Failed to schedule on JNI thread"; } diff --git a/system/btif/src/btif_rc.cc b/system/btif/src/btif_rc.cc index a399a65344..5e3ed2c79b 100644 --- a/system/btif/src/btif_rc.cc +++ b/system/btif/src/btif_rc.cc @@ -620,8 +620,8 @@ void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) { BTIF_TRACE_DEBUG("%s: Update rc features to CTRL: %d", __func__, rc_features); do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->getrcfeatures_cb, - p_dev->rc_addr, rc_features)); + base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, + p_dev->rc_addr, rc_features)); } } @@ -671,8 +671,9 @@ void handle_rc_ctrl_features(btif_rc_device_cb_t* p_dev) { } BTIF_TRACE_DEBUG("%s: Update rc features to CTRL: %d", __func__, rc_features); - do_in_jni_thread(FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->getrcfeatures_cb, - p_dev->rc_addr, rc_features)); + do_in_jni_thread(FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, + p_dev->rc_addr, rc_features)); } void btif_rc_check_pending_cmd(const RawAddress& peer_address) { btif_rc_device_cb_t* p_dev = NULL; @@ -702,9 +703,9 @@ void btif_rc_check_pending_cmd(const RawAddress& peer_address) { if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_REPORT_CONN) && btif_av_peer_is_source(p_dev->rc_addr)) { if (bt_rc_ctrl_callbacks != NULL) { - do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, - true, false, p_dev->rc_addr)); + do_in_jni_thread( + FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, + true, false, p_dev->rc_addr)); } } } @@ -717,8 +718,8 @@ void handle_rc_ctrl_psm(btif_rc_device_cb_t* p_dev) { cover_art_psm); if (bt_rc_ctrl_callbacks != NULL) { do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->get_cover_art_psm_cb, - p_dev->rc_addr, cover_art_psm)); + base::BindOnce(bt_rc_ctrl_callbacks->get_cover_art_psm_cb, + p_dev->rc_addr, cover_art_psm)); } } @@ -803,18 +804,19 @@ void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) { if (btif_av_src_sink_coexist_enabled()) { if (btif_av_peer_is_connected_source(p_dev->rc_addr)) { if (bt_rc_ctrl_callbacks != NULL) { - do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, - true, true, p_dev->rc_addr)); + do_in_jni_thread( + FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, + true, p_dev->rc_addr)); } } else { p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN; BTIF_TRACE_API("%s: pending rc browse connection event", __func__); } } else { - do_in_jni_thread( - FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, true, - true, p_dev->rc_addr)); + do_in_jni_thread(FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, + true, true, p_dev->rc_addr)); } } } @@ -895,8 +897,8 @@ void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { } if (bt_rc_ctrl_callbacks != NULL) { do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, true, - false, p_dev->rc_addr)); + base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, + true, false, p_dev->rc_addr)); /* report connection state if remote device is AVRCP target */ handle_rc_ctrl_features(p_dev); @@ -931,9 +933,9 @@ void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) { /* Report connection state if device is AVRCP target */ if (bt_rc_ctrl_callbacks != NULL) { - do_in_jni_thread( - FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, false, - false, p_dev->rc_addr)); + do_in_jni_thread(FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, + false, false, p_dev->rc_addr)); } // We'll re-initialize the device state back to what it looked like before @@ -1035,8 +1037,8 @@ void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { if (bt_rc_ctrl_callbacks != NULL) { do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->passthrough_rsp_cb, p_dev->rc_addr, - p_remote_rsp->rc_id, p_remote_rsp->key_state)); + base::BindOnce(bt_rc_ctrl_callbacks->passthrough_rsp_cb, p_dev->rc_addr, + p_remote_rsp->rc_id, p_remote_rsp->key_state)); } } @@ -1079,9 +1081,9 @@ void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { status); release_transaction(p_dev, p_remote_rsp->label); - do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb, - vendor_id, key_state)); + do_in_jni_thread( + FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb, + vendor_id, key_state)); } else { BTIF_TRACE_ERROR("%s: Remote does not support AVRCP TG role", __func__); } @@ -1905,15 +1907,15 @@ static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, case AVRC_PDU_SET_ABSOLUTE_VOLUME: do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->setabsvol_cmd_cb, p_dev->rc_addr, - pavrc_cmd->volume.volume, label)); + base::BindOnce(bt_rc_ctrl_callbacks->setabsvol_cmd_cb, p_dev->rc_addr, + pavrc_cmd->volume.volume, label)); break; case AVRC_PDU_REGISTER_NOTIFICATION: if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE) { do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->registernotification_absvol_cb, - p_dev->rc_addr, label)); + base::BindOnce(bt_rc_ctrl_callbacks->registernotification_absvol_cb, + p_dev->rc_addr, label)); } break; } @@ -3319,9 +3321,9 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, get_play_status_cmd(p_dev); do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb, - p_dev->rc_addr, - (btrc_play_status_t)p_rsp->param.play_status)); + base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb, + p_dev->rc_addr, + (btrc_play_status_t)p_rsp->param.play_status)); break; case AVRC_EVT_TRACK_CHANGE: @@ -3342,28 +3344,31 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, case AVRC_EVT_NOW_PLAYING_CHANGE: do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->now_playing_contents_changed_cb, - p_dev->rc_addr)); + base::BindOnce( + bt_rc_ctrl_callbacks->now_playing_contents_changed_cb, + p_dev->rc_addr)); break; case AVRC_EVT_AVAL_PLAYERS_CHANGE: BTIF_TRACE_DEBUG("%s: AVRC_EVT_AVAL_PLAYERS_CHANGE", __func__); do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->available_player_changed_cb, - p_dev->rc_addr)); + base::BindOnce(bt_rc_ctrl_callbacks->available_player_changed_cb, + p_dev->rc_addr)); break; case AVRC_EVT_ADDR_PLAYER_CHANGE: do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->addressed_player_changed_cb, - p_dev->rc_addr, p_rsp->param.addr_player.player_id)); + base::BindOnce(bt_rc_ctrl_callbacks->addressed_player_changed_cb, + p_dev->rc_addr, p_rsp->param.addr_player.player_id)); break; case AVRC_EVT_PLAY_POS_CHANGED: - do_in_jni_thread(FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->play_position_changed_cb, p_dev->rc_addr, 0, - p_rsp->param.play_pos)); + do_in_jni_thread( + FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb, + p_dev->rc_addr, 0, p_rsp->param.play_pos)); break; case AVRC_EVT_UIDS_CHANGE: @@ -3434,9 +3439,9 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, */ do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb, - p_dev->rc_addr, - (btrc_play_status_t)p_rsp->param.play_status)); + base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb, + p_dev->rc_addr, + (btrc_play_status_t)p_rsp->param.play_status)); break; @@ -3459,7 +3464,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, } do_in_jni_thread( FROM_HERE, - base::Bind( + base::BindOnce( bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb, p_dev->rc_addr, app_settings)); } break; @@ -3592,9 +3597,9 @@ static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, get_player_app_setting_cmd(p_app_settings->num_attrs, attrs, p_dev); do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, - p_dev->rc_addr, p_app_settings->num_attrs, - p_app_settings->attrs, 0, nullptr)); + base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, + p_dev->rc_addr, p_app_settings->num_attrs, + p_app_settings->attrs, 0, nullptr)); } } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) { attr_index = p_app_settings->ext_attr_index; @@ -3663,8 +3668,8 @@ static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg, do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb, - p_dev->rc_addr, app_settings)); + base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb, + p_dev->rc_addr, app_settings)); /* Application settings are fetched only once for initial values * initiate anything that follows after RC procedure. * Defer it if browsing is supported till players query @@ -3723,9 +3728,10 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg, } do_in_jni_thread( - FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, - p_dev->rc_addr, p_app_settings->num_attrs, - p_app_settings->attrs, 0, nullptr)); + FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, + p_dev->rc_addr, p_app_settings->num_attrs, + p_app_settings->attrs, 0, nullptr)); get_player_app_setting_cmd(xx, attrs, p_dev); return; @@ -3807,9 +3813,10 @@ static void handle_app_attr_val_txt_response( attrs[xx] = p_app_settings->attrs[xx].attr_id; } do_in_jni_thread( - FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, - p_dev->rc_addr, p_app_settings->num_attrs, - p_app_settings->attrs, 0, nullptr)); + FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, + p_dev->rc_addr, p_app_settings->num_attrs, + p_app_settings->attrs, 0, nullptr)); get_player_app_setting_cmd(xx, attrs, p_dev); return; @@ -3853,17 +3860,18 @@ static void handle_app_attr_val_txt_response( } do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, - p_dev->rc_addr, p_app_settings->num_attrs, - p_app_settings->attrs, p_app_settings->num_ext_attrs, - p_app_settings->ext_attrs)); + base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, + p_dev->rc_addr, p_app_settings->num_attrs, + p_app_settings->attrs, p_app_settings->num_ext_attrs, + p_app_settings->ext_attrs)); get_player_app_setting_cmd(xx + x, attrs, p_dev); /* Free the application settings information after sending to * application. */ - do_in_jni_thread(FROM_HERE, base::Bind(cleanup_app_attr_val_txt_response, - p_app_settings)); + do_in_jni_thread( + FROM_HERE, + base::BindOnce(cleanup_app_attr_val_txt_response, p_app_settings)); p_app_settings->num_attrs = 0; } } @@ -3918,9 +3926,10 @@ static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT)) { accepted = 1; } - do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->setplayerappsetting_rsp_cb, - p_dev->rc_addr, accepted)); + do_in_jni_thread( + FROM_HERE, + base::BindOnce(bt_rc_ctrl_callbacks->setplayerappsetting_rsp_cb, + p_dev->rc_addr, accepted)); } /*************************************************************************** @@ -3961,9 +3970,9 @@ static void handle_get_metadata_attr_response(tBTA_AV_META_MSG* pmeta_msg, osi_free_and_reset((void**)&p_rsp->p_attrs); do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->track_changed_cb, - p_dev->rc_addr, p_rsp->num_attrs, p_attr)); - do_in_jni_thread(FROM_HERE, base::Bind(osi_free, p_attr)); + base::BindOnce(bt_rc_ctrl_callbacks->track_changed_cb, + p_dev->rc_addr, p_rsp->num_attrs, p_attr)); + do_in_jni_thread(FROM_HERE, base::BindOnce(osi_free, p_attr)); } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) { /* Retry for timeout case, this covers error handling * for continuation failure also. @@ -4001,12 +4010,12 @@ static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, if (p_rsp->status == AVRC_STS_NO_ERROR) { do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb, p_dev->rc_addr, - (btrc_play_status_t)p_rsp->play_status)); + base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb, + p_dev->rc_addr, (btrc_play_status_t)p_rsp->play_status)); do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->play_position_changed_cb, - p_dev->rc_addr, p_rsp->song_len, p_rsp->song_pos)); + base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb, + p_dev->rc_addr, p_rsp->song_len, p_rsp->song_pos)); } else { BTIF_TRACE_ERROR("%s: Error in get play status procedure: %d", __func__, p_rsp->status); @@ -4035,9 +4044,9 @@ static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, if (p_rsp->status == AVRC_STS_NO_ERROR) { - do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->set_addressed_player_cb, - p_dev->rc_addr, p_rsp->status)); + do_in_jni_thread( + FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->set_addressed_player_cb, + p_dev->rc_addr, p_rsp->status)); } else { BTIF_TRACE_ERROR("%s: Error in get play status procedure %d", __func__, p_rsp->status); @@ -4098,10 +4107,10 @@ static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg, do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr, - BTRC_STS_NO_ERROR, - /* We want to make the ownership explicit in native */ - btrc_items, item_count)); + base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, + p_dev->rc_addr, BTRC_STS_NO_ERROR, + /* We want to make the ownership explicit in native */ + btrc_items, item_count)); if (item_count > 0) { if (btrc_items[0].item_type == AVRC_ITEM_PLAYER && @@ -4112,16 +4121,16 @@ static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg, /* Release the memory block for items and attributes allocated here. * Since the executor for do_in_jni_thread is a Single Thread Task Runner it * is okay to queue up the cleanup of btrc_items */ - do_in_jni_thread(FROM_HERE, base::Bind(cleanup_btrc_folder_items, - btrc_items, item_count)); + do_in_jni_thread(FROM_HERE, base::BindOnce(cleanup_btrc_folder_items, + btrc_items, item_count)); BTIF_TRACE_DEBUG("%s get_folder_items_cb sent to JNI thread", __func__); } else { BTIF_TRACE_ERROR("%s: Error %d", __func__, p_rsp->status); do_in_jni_thread( - FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr, - (btrc_status_t)p_rsp->status, nullptr, 0)); + FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, + p_dev->rc_addr, (btrc_status_t)p_rsp->status, + nullptr, 0)); } } /*************************************************************************** @@ -4345,8 +4354,8 @@ static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg, if (p_rsp->status == AVRC_STS_NO_ERROR) { do_in_jni_thread(FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->change_folder_path_cb, - p_dev->rc_addr, p_rsp->num_items)); + base::BindOnce(bt_rc_ctrl_callbacks->change_folder_path_cb, + p_dev->rc_addr, p_rsp->num_items)); } else { BTIF_TRACE_ERROR("%s error in handle_change_path_response %d", __func__, p_rsp->status); @@ -4375,8 +4384,8 @@ static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg, if (p_rsp->status == AVRC_STS_NO_ERROR) { do_in_jni_thread( FROM_HERE, - base::Bind(bt_rc_ctrl_callbacks->set_browsed_player_cb, p_dev->rc_addr, - p_rsp->num_items, p_rsp->folder_depth)); + base::BindOnce(bt_rc_ctrl_callbacks->set_browsed_player_cb, + p_dev->rc_addr, p_rsp->num_items, p_rsp->folder_depth)); } else { BTIF_TRACE_ERROR("%s error %d", __func__, p_rsp->status); } diff --git a/system/btif/src/stack_manager.cc b/system/btif/src/stack_manager.cc index 657d34ef07..69a8c85993 100644 --- a/system/btif/src/stack_manager.cc +++ b/system/btif/src/stack_manager.cc @@ -351,7 +351,7 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, stack_is_running = true; LOG_INFO("%s finished", __func__); - do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_up, nullptr)); + do_in_jni_thread(FROM_HERE, base::BindOnce(event_signal_stack_up, nullptr)); } // Synchronous function to shut down the stack @@ -398,7 +398,7 @@ static void event_shut_down_stack(ProfileStopCallback stopProfiles) { get_btm_client_interface().lifecycle.btm_free(); hack_future = future_new(); - do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_down, nullptr)); + do_in_jni_thread(FROM_HERE, base::BindOnce(event_signal_stack_down, nullptr)); future_await(hack_future); LOG_INFO("%s finished", __func__); } diff --git a/system/build/Android.bp b/system/build/Android.bp index 08e5f411c3..8999d96d1d 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -14,8 +14,6 @@ cc_defaults { "-DEXPORT_SYMBOL=__attribute__((visibility(\"default\")))", "-DLOG_NDEBUG=1", "-fvisibility=hidden", - // struct BT_HDR is defined as a variable-size header in a struct. - "-Wno-gnu-variable-sized-type-not-at-end", ], target: { android: { diff --git a/system/gd/hal/hci_hal_android_hidl.cc b/system/gd/hal/hci_hal_android_hidl.cc index 300f294658..98a3855611 100644 --- a/system/gd/hal/hci_hal_android_hidl.cc +++ b/system/gd/hal/hci_hal_android_hidl.cc @@ -61,9 +61,11 @@ namespace { class HciDeathRecipient : public ::android::hardware::hidl_death_recipient { public: virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) { - LOG_ERROR("Bluetooth HAL service died. Calling exit(0);"); + LOG_ERROR("The Bluetooth HAL service died. Dumping logs and crashing in 1 second."); common::StopWatch::DumpStopWatchLog(); - exit(0); + // At shutdown, sometimes the HAL service gets killed before Bluetooth. + std::this_thread::sleep_for(std::chrono::seconds(1)); + LOG_ALWAYS_FATAL("The Bluetooth HAL died."); } }; diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h index c77e0e961b..5d21278021 100644 --- a/system/gd/hci/acl_manager/le_impl.h +++ b/system/gd/hci/acl_manager/le_impl.h @@ -355,16 +355,6 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { AddressWithType remote_address(address, peer_address_type); AddressWithType local_address = le_address_manager_->GetInitiatorAddress(); const bool in_filter_accept_list = is_device_in_connect_list(remote_address); - auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); - argument_list.push_back( - std::make_pair(os::ArgumentType::ACL_STATUS_CODE, static_cast<int>(status))); - - bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( - address, - android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, - android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, - android::bluetooth::le::LeConnectionState::STATE_LE_ACL_END, - argument_list); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -501,16 +491,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } AddressWithType remote_address(address, remote_address_type); const bool in_filter_accept_list = is_device_in_connect_list(remote_address); - auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); - argument_list.push_back( - std::make_pair(os::ArgumentType::ACL_STATUS_CODE, static_cast<int>(status))); - bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( - address, - android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, - android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, - android::bluetooth::le::LeConnectionState::STATE_LE_ACL_END, - argument_list); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -1015,14 +996,6 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { void disarm_connectability() { - auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); - bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( - Address::kEmpty, - os::LeConnectionOriginType::ORIGIN_UNSPECIFIED, - os::LeConnectionType::CONNECTION_TYPE_LE_ACL, - os::LeConnectionState::STATE_LE_ACL_CANCEL, - argument_list); - switch (connectability_state_) { case ConnectabilityState::ARMED: LOG_INFO("Disarming LE connection state machine with create connection cancel"); @@ -1119,16 +1092,6 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { create_connection_timeout_alarms_.at(address_with_type).Cancel(); create_connection_timeout_alarms_.erase(address_with_type); - auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); - argument_list.push_back(std::make_pair( - os::ArgumentType::ACL_STATUS_CODE, - static_cast<int>(android::bluetooth::hci::StatusEnum::STATUS_CONNECTION_TOUT))); - bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( - address_with_type.GetAddress(), - android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, - android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, - android::bluetooth::le::LeConnectionState::STATE_LE_ACL_TIMEOUT, - argument_list); if (background_connections_.find(address_with_type) != background_connections_.end()) { direct_connections_.erase(address_with_type); diff --git a/system/main/shim/le_advertising_manager.cc b/system/main/shim/le_advertising_manager.cc index d36915cd3c..668b7b28c6 100644 --- a/system/main/shim/le_advertising_manager.cc +++ b/system/main/shim/le_advertising_manager.cc @@ -249,9 +249,10 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, return; } do_in_jni_thread( - FROM_HERE, base::Bind(&AdvertisingCallbacks::OnAdvertisingSetStarted, - base::Unretained(advertising_callbacks_), reg_id, - advertiser_id, tx_power, status)); + FROM_HERE, + base::BindOnce(&AdvertisingCallbacks::OnAdvertisingSetStarted, + base::Unretained(advertising_callbacks_), reg_id, + advertiser_id, tx_power, status)); } void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, @@ -269,38 +270,38 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, return; } do_in_jni_thread(FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnAdvertisingEnabled, - base::Unretained(advertising_callbacks_), - advertiser_id, enable, status)); + base::BindOnce(&AdvertisingCallbacks::OnAdvertisingEnabled, + base::Unretained(advertising_callbacks_), + advertiser_id, enable, status)); } void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) { do_in_jni_thread(FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnAdvertisingDataSet, - base::Unretained(advertising_callbacks_), - advertiser_id, status)); + base::BindOnce(&AdvertisingCallbacks::OnAdvertisingDataSet, + base::Unretained(advertising_callbacks_), + advertiser_id, status)); } void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) { - do_in_jni_thread(FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnScanResponseDataSet, - base::Unretained(advertising_callbacks_), - advertiser_id, status)); + do_in_jni_thread( + FROM_HERE, base::BindOnce(&AdvertisingCallbacks::OnScanResponseDataSet, + base::Unretained(advertising_callbacks_), + advertiser_id, status)); } void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power, uint8_t status) { do_in_jni_thread( FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnAdvertisingParametersUpdated, - base::Unretained(advertising_callbacks_), advertiser_id, - tx_power, status)); + base::BindOnce(&AdvertisingCallbacks::OnAdvertisingParametersUpdated, + base::Unretained(advertising_callbacks_), advertiser_id, + tx_power, status)); } void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t status) { do_in_jni_thread( FROM_HERE, - base::Bind( + base::BindOnce( &AdvertisingCallbacks::OnPeriodicAdvertisingParametersUpdated, base::Unretained(advertising_callbacks_), advertiser_id, status)); } @@ -308,18 +309,18 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) { do_in_jni_thread( FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnPeriodicAdvertisingDataSet, - base::Unretained(advertising_callbacks_), advertiser_id, - status)); + base::BindOnce(&AdvertisingCallbacks::OnPeriodicAdvertisingDataSet, + base::Unretained(advertising_callbacks_), advertiser_id, + status)); } void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) { do_in_jni_thread( FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnPeriodicAdvertisingEnabled, - base::Unretained(advertising_callbacks_), advertiser_id, - enable, status)); + base::BindOnce(&AdvertisingCallbacks::OnPeriodicAdvertisingEnabled, + base::Unretained(advertising_callbacks_), advertiser_id, + enable, status)); } void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, @@ -331,9 +332,9 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, return; } do_in_jni_thread(FROM_HERE, - base::Bind(&AdvertisingCallbacks::OnOwnAddressRead, - base::Unretained(advertising_callbacks_), - advertiser_id, address_type, raw_address)); + base::BindOnce(&AdvertisingCallbacks::OnOwnAddressRead, + base::Unretained(advertising_callbacks_), + advertiser_id, address_type, raw_address)); } AdvertisingCallbacks* advertising_callbacks_; diff --git a/system/main/shim/le_scanning_manager.cc b/system/main/shim/le_scanning_manager.cc index f1c9c91731..9cc2e5190e 100644 --- a/system/main/shim/le_scanning_manager.cc +++ b/system/main/shim/le_scanning_manager.cc @@ -192,8 +192,8 @@ void BleScannerInterfaceImpl::Scan(bool start) { } do_in_jni_thread(FROM_HERE, - base::Bind(&BleScannerInterfaceImpl::AddressCache::init, - base::Unretained(&address_cache_))); + base::BindOnce(&BleScannerInterfaceImpl::AddressCache::init, + base::Unretained(&address_cache_))); } /** Setup scan filter params */ @@ -233,7 +233,7 @@ void BleScannerInterfaceImpl::ScanFilterParamSetup( apcf_action, filter_index, advertising_filter_parameter); // TODO refactor callback mechanism do_in_jni_thread(FROM_HERE, - base::Bind(cb, 0, 0, btm_status_value(BTM_SUCCESS))); + base::BindOnce(cb, 0, 0, btm_status_value(BTM_SUCCESS))); } /** Configure a scan filter condition */ @@ -253,7 +253,7 @@ void BleScannerInterfaceImpl::ScanFilterAdd(int filter_index, } bluetooth::shim::GetScanning()->ScanFilterAdd(filter_index, new_filters); do_in_jni_thread(FROM_HERE, - base::Bind(cb, 0, 0, 0, btm_status_value(BTM_SUCCESS))); + base::BindOnce(cb, 0, 0, 0, btm_status_value(BTM_SUCCESS))); } /** Clear all scan filter conditions for specific filter index*/ @@ -270,7 +270,7 @@ void BleScannerInterfaceImpl::ScanFilterEnable(bool enable, EnableCallback cb) { uint8_t action = enable ? 1 : 0; do_in_jni_thread(FROM_HERE, - base::Bind(cb, action, btm_status_value(BTM_SUCCESS))); + base::BindOnce(cb, action, btm_status_value(BTM_SUCCESS))); } /** Is MSFT Extension supported? */ @@ -368,7 +368,8 @@ void BleScannerInterfaceImpl::BatchscanConfigStorage( bluetooth::shim::GetScanning()->BatchScanConifgStorage( batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold, client_if); - do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); + do_in_jni_thread(FROM_HERE, + base::BindOnce(cb, btm_status_value(BTM_SUCCESS))); } /* Enable batchscan */ @@ -381,14 +382,16 @@ void BleScannerInterfaceImpl::BatchscanEnable(int scan_mode, int scan_interval, static_cast<bluetooth::hci::BatchScanDiscardRule>(discard_rule); bluetooth::shim::GetScanning()->BatchScanEnable( batch_scan_mode, scan_window, scan_interval, batch_scan_discard_rule); - do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); + do_in_jni_thread(FROM_HERE, + base::BindOnce(cb, btm_status_value(BTM_SUCCESS))); } /* Disable batchscan */ void BleScannerInterfaceImpl::BatchscanDisable(Callback cb) { LOG(INFO) << __func__ << " in shim layer"; bluetooth::shim::GetScanning()->BatchScanDisable(); - do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); + do_in_jni_thread(FROM_HERE, + base::BindOnce(cb, btm_status_value(BTM_SUCCESS))); } /* Read out batchscan reports */ @@ -489,17 +492,18 @@ void BleScannerInterfaceImpl::OnScannerRegistered( ScanningStatus status) { auto uuid = bluetooth::Uuid::From128BitBE(app_uuid.To128BitBE()); do_in_jni_thread(FROM_HERE, - base::Bind(&ScanningCallbacks::OnScannerRegistered, - base::Unretained(scanning_callbacks_), uuid, - scanner_id, status)); + base::BindOnce(&ScanningCallbacks::OnScannerRegistered, + base::Unretained(scanning_callbacks_), uuid, + scanner_id, status)); } void BleScannerInterfaceImpl::OnSetScannerParameterComplete( bluetooth::hci::ScannerId scanner_id, ScanningStatus status) { do_in_jni_thread( FROM_HERE, - base::Bind(&ScanningCallbacks::OnSetScannerParameterComplete, - base::Unretained(scanning_callbacks_), scanner_id, status)); + base::BindOnce(&ScanningCallbacks::OnSetScannerParameterComplete, + base::Unretained(scanning_callbacks_), scanner_id, + status)); } void BleScannerInterfaceImpl::OnScanResult( diff --git a/system/rust/src/gatt/ffi/gatt_shim.cc b/system/rust/src/gatt/ffi/gatt_shim.cc index 42415c8bcc..c85ca58b24 100644 --- a/system/rust/src/gatt/ffi/gatt_shim.cc +++ b/system/rust/src/gatt/ffi/gatt_shim.cc @@ -66,14 +66,14 @@ void GattServerCallbacks::OnServerRead(uint16_t conn_id, uint32_t trans_id, case AttributeBackingType::CHARACTERISTIC: do_in_jni_thread( FROM_HERE, - base::Bind(callbacks.request_read_characteristic_cb, conn_id, - trans_id, addr.value(), attr_handle, offset, is_long)); + base::BindOnce(callbacks.request_read_characteristic_cb, conn_id, + trans_id, addr.value(), attr_handle, offset, is_long)); break; case AttributeBackingType::DESCRIPTOR: do_in_jni_thread( FROM_HERE, - base::Bind(callbacks.request_read_descriptor_cb, conn_id, trans_id, - addr.value(), attr_handle, offset, is_long)); + base::BindOnce(callbacks.request_read_descriptor_cb, conn_id, + trans_id, addr.value(), attr_handle, offset, is_long)); break; default: LOG_ALWAYS_FATAL("Unexpected backing type %d", attr_type); @@ -99,16 +99,18 @@ void GattServerCallbacks::OnServerWrite( case AttributeBackingType::CHARACTERISTIC: do_in_jni_thread( FROM_HERE, - base::Bind(callbacks.request_write_characteristic_cb, conn_id, - trans_id, addr.value(), attr_handle, offset, need_response, - is_prepare, base::Owned(buf), value.size())); + base::BindOnce(callbacks.request_write_characteristic_cb, conn_id, + trans_id, addr.value(), attr_handle, offset, + need_response, is_prepare, base::Owned(buf), + value.size())); break; case AttributeBackingType::DESCRIPTOR: do_in_jni_thread( FROM_HERE, - base::Bind(callbacks.request_write_descriptor_cb, conn_id, trans_id, - addr.value(), attr_handle, offset, need_response, - is_prepare, base::Owned(buf), value.size())); + base::BindOnce(callbacks.request_write_descriptor_cb, conn_id, + trans_id, addr.value(), attr_handle, offset, + need_response, is_prepare, base::Owned(buf), + value.size())); break; default: LOG_ALWAYS_FATAL("Unexpected backing type %hhu", attr_type); @@ -117,8 +119,8 @@ void GattServerCallbacks::OnServerWrite( void GattServerCallbacks::OnIndicationSentConfirmation(uint16_t conn_id, int status) const { - do_in_jni_thread(FROM_HERE, - base::Bind(callbacks.indication_sent_cb, conn_id, status)); + do_in_jni_thread( + FROM_HERE, base::BindOnce(callbacks.indication_sent_cb, conn_id, status)); } void GattServerCallbacks::OnExecute(uint16_t conn_id, uint32_t trans_id, @@ -130,9 +132,9 @@ void GattServerCallbacks::OnExecute(uint16_t conn_id, uint32_t trans_id, return; } - do_in_jni_thread( - FROM_HERE, base::Bind(callbacks.request_exec_write_cb, conn_id, trans_id, - addr.value(), execute)); + do_in_jni_thread(FROM_HERE, + base::BindOnce(callbacks.request_exec_write_cb, conn_id, + trans_id, addr.value(), execute)); } } // namespace gatt diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc index 7c3e95eb7d..ccb61b978a 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -2828,15 +2828,6 @@ bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr, return false; } - // argument list - auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); - - bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( - bd_addr, android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, - android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, - android::bluetooth::le::LeConnectionState::STATE_LE_ACL_START, - argument_list); - if (bluetooth::common::init_flags:: use_unified_connection_manager_is_enabled()) { bluetooth::connection::GetConnectionManager().start_direct_connection( diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc index 308c38ab66..6d3c13377e 100644 --- a/system/stack/l2cap/l2c_api.cc +++ b/system/stack/l2cap/l2c_api.cc @@ -1357,16 +1357,6 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { } if (transport == BT_TRANSPORT_LE) { - auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); - argument_list.push_back(std::make_pair(bluetooth::os::ArgumentType::L2CAP_CID, fixed_cid)); - - bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( - rem_bda, - android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, - android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, - android::bluetooth::le::LeConnectionState::STATE_LE_ACL_START, - argument_list); - bool ret = l2cu_create_conn_le(p_lcb); if (!ret) { LOG_WARN("Unable to create fixed channel le connection fixed_cid:0x%04x", diff --git a/system/stack/mmc/codec_server/BUILD.gn b/system/stack/mmc/codec_server/BUILD.gn index 4e5c354418..ea87d29074 100644 --- a/system/stack/mmc/codec_server/BUILD.gn +++ b/system/stack/mmc/codec_server/BUILD.gn @@ -22,9 +22,12 @@ source_set("libcodec_server_hfp_lc3"){ "//bt/system/stack", "//bt/system/stack/include", ] + libs = [ + "lc3", + ] + deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", - "//bt/system/embdrv/lc3:liblc3", "//bt/system/osi", ] sources = [ diff --git a/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.cc b/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.cc index 414f3fde67..9523c753ae 100644 --- a/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.cc +++ b/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.cc @@ -18,8 +18,8 @@ #include <base/logging.h> #include <errno.h> +#include <lc3.h> -#include "embdrv/lc3/include/lc3.h" #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "osi/include/allocator.h" diff --git a/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.h b/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.h index cabe34be45..27b83e95b5 100644 --- a/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.h +++ b/system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.h @@ -17,7 +17,8 @@ #ifndef MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ #define MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ -#include "embdrv/lc3/include/lc3.h" +#include <lc3.h> + #include "mmc/mmc_interface/mmc_interface.h" #include "mmc/proto/mmc_config.pb.h" diff --git a/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.cc b/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.cc index 676c0fbae8..36c8b64523 100644 --- a/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.cc +++ b/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.cc @@ -18,10 +18,10 @@ #include <base/logging.h> #include <errno.h> +#include <lc3.h> #include <algorithm> -#include "embdrv/lc3/include/lc3.h" #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "osi/include/allocator.h" diff --git a/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.h b/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.h index a578c9ffc4..b9e66da70e 100644 --- a/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.h +++ b/system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.h @@ -17,7 +17,8 @@ #ifndef MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ #define MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ -#include "embdrv/lc3/include/lc3.h" +#include <lc3.h> + #include "mmc/mmc_interface/mmc_interface.h" #include "mmc/proto/mmc_config.pb.h" diff --git a/system/stack/mmc/codec_server/lc3_utils.h b/system/stack/mmc/codec_server/lc3_utils.h index d3eed60bab..563ecab909 100644 --- a/system/stack/mmc/codec_server/lc3_utils.h +++ b/system/stack/mmc/codec_server/lc3_utils.h @@ -18,8 +18,8 @@ #define MMC_CODEC_SERVER_LC3_UTILS_H_ #include <base/logging.h> +#include <lc3.h> -#include "embdrv/lc3/include/lc3.h" #include "mmc/proto/mmc_config.pb.h" namespace mmc { |