Loading android/app/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ android_app { "bluetooth-protos-lite", "bluetooth.change-ids", "bluetooth.mapsapi", "bluetooth_flags_java_lib", "com.android.obex", "com.android.vcard", "guava", Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +3 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static com.android.bluetooth.Utils.getBytesFromAddress; import static com.android.bluetooth.Utils.hasBluetoothPrivilegedPermission; import static com.android.bluetooth.Utils.isDualModeAudioEnabled; import static com.android.bluetooth.Utils.isPackageNameAccurate; import static java.util.Objects.requireNonNull; import android.annotation.NonNull; Loading Loading @@ -122,6 +123,7 @@ import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreServic import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; import com.android.bluetooth.csip.CsipSetCoordinatorService; import com.android.bluetooth.flags.FeatureFlagsImpl; import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.gatt.ScanManager; import com.android.bluetooth.hap.HapClientService; Loading Loading @@ -689,7 +691,7 @@ public class AdapterService extends Service { */ if (!isAutomotiveDevice && getResources().getBoolean(R.bool.enable_phone_policy)) { Log.i(TAG, "Phone policy enabled"); mPhonePolicy = new PhonePolicy(this, new ServiceFactory()); mPhonePolicy = new PhonePolicy(this, new ServiceFactory(), new FeatureFlagsImpl()); mPhonePolicy.start(); } else { Log.i(TAG, "Phone policy disabled"); Loading android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +7 −10 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; import com.android.bluetooth.flags.FeatureFlags; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; Loading Loading @@ -77,12 +78,6 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { private static boolean sLeAudioEnabledByDefault = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_BLUETOOTH, CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false); private static final String HFP_AUTO_CONNECT = "HFP_AUTO_CONNECT"; @VisibleForTesting static boolean sIsHfpAutoConnectEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, HFP_AUTO_CONNECT, false); /** flag for multi auto connect */ public static boolean sIsHfpMultiAutoConnectEnabled = DeviceConfig.getBoolean( Loading @@ -94,6 +89,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { @VisibleForTesting static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s private DatabaseManager mDatabaseManager; private final FeatureFlags mFeatureFlags; private final AdapterService mAdapterService; private final ServiceFactory mFactory; private final Handler mHandler; Loading Loading @@ -179,14 +175,15 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { resetStates(); } PhonePolicy(AdapterService service, ServiceFactory factory) { PhonePolicy(AdapterService service, ServiceFactory factory, FeatureFlags featureFlags) { mAdapterService = service; mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), "DatabaseManager cannot be null when PhonePolicy starts"); mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null"); mFactory = factory; mHandler = new PhonePolicyHandler(service.getMainLooper()); mAutoConnectProfilesSupported = SystemProperties.getBoolean( AUTO_CONNECT_PROFILES_PROPERTY, false); mAutoConnectProfilesSupported = SystemProperties.getBoolean(AUTO_CONNECT_PROFILES_PROPERTY, false); } // Policy implementation, all functions MUST be private Loading Loading @@ -625,7 +622,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { return; } if (!sIsHfpAutoConnectEnabled) { if (!mFeatureFlags.autoConnectOnHfpWhenNoA2dpDevice()) { debugLog("HFP auto connect is not enabled"); return; } Loading android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +41 −40 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.bluetooth.btservice; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.waitForLooperToFinishScheduledTask; import static com.android.bluetooth.btservice.PhonePolicy.sIsHfpAutoConnectEnabled; import static com.android.bluetooth.btservice.PhonePolicy.sIsHfpMultiAutoConnectEnabled; import static org.mockito.Mockito.*; Loading @@ -40,6 +39,8 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; import com.android.bluetooth.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; Loading Loading @@ -67,6 +68,7 @@ public class PhonePolicyTest { private BluetoothAdapter mAdapter; private PhonePolicy mPhonePolicy; private boolean mOriginalDualModeState; private FakeFeatureFlagsImpl mFakeFlagsImpl; @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; Loading Loading @@ -101,7 +103,10 @@ public class PhonePolicyTest { // Must be called to initialize services mAdapter = BluetoothAdapter.getDefaultAdapter(); PhonePolicy.sConnectOtherProfilesTimeoutMillis = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS; mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); mFakeFlagsImpl = new FakeFeatureFlagsImpl(); mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); mOriginalDualModeState = Utils.isDualModeAudioEnabled(); } Loading Loading @@ -622,9 +627,8 @@ public class PhonePolicyTest { */ @Test public void testAutoConnectHfpOnly() { sIsHfpAutoConnectEnabled = true; mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); try { // Return desired values from the mocked object(s) doReturn(BluetoothAdapter.STATE_ON).when(mAdapterService).getState(); doReturn(false).when(mAdapterService).isQuietModeEnabled(); Loading @@ -636,7 +640,7 @@ public class PhonePolicyTest { .build(); DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); Loading @@ -656,14 +660,11 @@ public class PhonePolicyTest { // Check that we got a request to connect over HFP for each device verify(mHeadsetService).connect(eq(bondedDevice)); } finally { sIsHfpAutoConnectEnabled = false; } } @Test public void autoConnect_whenMultiHfp_startConnection() { sIsHfpAutoConnectEnabled = true; mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); sIsHfpMultiAutoConnectEnabled = true; try { Loading @@ -678,7 +679,8 @@ public class PhonePolicyTest { .build(); DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); Loading Loading @@ -706,13 +708,12 @@ public class PhonePolicyTest { } } finally { sIsHfpMultiAutoConnectEnabled = false; sIsHfpAutoConnectEnabled = false; } } @Test public void autoConnect_whenMultiHfpAndDeconnection_startConnection() { sIsHfpAutoConnectEnabled = true; mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); sIsHfpMultiAutoConnectEnabled = true; try { Loading @@ -727,7 +728,8 @@ public class PhonePolicyTest { .build(); DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); Loading Loading @@ -766,7 +768,6 @@ public class PhonePolicyTest { verify(mHeadsetService, times(0)).connect(eq(deviceToDeconnect)); } finally { sIsHfpMultiAutoConnectEnabled = false; sIsHfpAutoConnectEnabled = false; } } Loading flags/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ aconfig_declarations { name: "bluetooth_aconfig_flags", package: "com.android.bluetooth.flags", srcs: [ "hfp.aconfig", "system_service.aconfig", ], } Loading @@ -15,6 +16,7 @@ java_aconfig_library { name: "bluetooth_flags_java_lib", aconfig_declarations: "bluetooth_aconfig_flags", visibility: [ "//packages/modules/Bluetooth/android/app", "//packages/modules/Bluetooth/service:__subpackages__", ], apex_available: [ Loading Loading
android/app/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ android_app { "bluetooth-protos-lite", "bluetooth.change-ids", "bluetooth.mapsapi", "bluetooth_flags_java_lib", "com.android.obex", "com.android.vcard", "guava", Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +3 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static com.android.bluetooth.Utils.getBytesFromAddress; import static com.android.bluetooth.Utils.hasBluetoothPrivilegedPermission; import static com.android.bluetooth.Utils.isDualModeAudioEnabled; import static com.android.bluetooth.Utils.isPackageNameAccurate; import static java.util.Objects.requireNonNull; import android.annotation.NonNull; Loading Loading @@ -122,6 +123,7 @@ import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreServic import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; import com.android.bluetooth.csip.CsipSetCoordinatorService; import com.android.bluetooth.flags.FeatureFlagsImpl; import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.gatt.ScanManager; import com.android.bluetooth.hap.HapClientService; Loading Loading @@ -689,7 +691,7 @@ public class AdapterService extends Service { */ if (!isAutomotiveDevice && getResources().getBoolean(R.bool.enable_phone_policy)) { Log.i(TAG, "Phone policy enabled"); mPhonePolicy = new PhonePolicy(this, new ServiceFactory()); mPhonePolicy = new PhonePolicy(this, new ServiceFactory(), new FeatureFlagsImpl()); mPhonePolicy.start(); } else { Log.i(TAG, "Phone policy disabled"); Loading
android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +7 −10 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; import com.android.bluetooth.flags.FeatureFlags; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; Loading Loading @@ -77,12 +78,6 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { private static boolean sLeAudioEnabledByDefault = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_BLUETOOTH, CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false); private static final String HFP_AUTO_CONNECT = "HFP_AUTO_CONNECT"; @VisibleForTesting static boolean sIsHfpAutoConnectEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, HFP_AUTO_CONNECT, false); /** flag for multi auto connect */ public static boolean sIsHfpMultiAutoConnectEnabled = DeviceConfig.getBoolean( Loading @@ -94,6 +89,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { @VisibleForTesting static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s private DatabaseManager mDatabaseManager; private final FeatureFlags mFeatureFlags; private final AdapterService mAdapterService; private final ServiceFactory mFactory; private final Handler mHandler; Loading Loading @@ -179,14 +175,15 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { resetStates(); } PhonePolicy(AdapterService service, ServiceFactory factory) { PhonePolicy(AdapterService service, ServiceFactory factory, FeatureFlags featureFlags) { mAdapterService = service; mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), "DatabaseManager cannot be null when PhonePolicy starts"); mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null"); mFactory = factory; mHandler = new PhonePolicyHandler(service.getMainLooper()); mAutoConnectProfilesSupported = SystemProperties.getBoolean( AUTO_CONNECT_PROFILES_PROPERTY, false); mAutoConnectProfilesSupported = SystemProperties.getBoolean(AUTO_CONNECT_PROFILES_PROPERTY, false); } // Policy implementation, all functions MUST be private Loading Loading @@ -625,7 +622,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { return; } if (!sIsHfpAutoConnectEnabled) { if (!mFeatureFlags.autoConnectOnHfpWhenNoA2dpDevice()) { debugLog("HFP auto connect is not enabled"); return; } Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +41 −40 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.bluetooth.btservice; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.waitForLooperToFinishScheduledTask; import static com.android.bluetooth.btservice.PhonePolicy.sIsHfpAutoConnectEnabled; import static com.android.bluetooth.btservice.PhonePolicy.sIsHfpMultiAutoConnectEnabled; import static org.mockito.Mockito.*; Loading @@ -40,6 +39,8 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; import com.android.bluetooth.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; Loading Loading @@ -67,6 +68,7 @@ public class PhonePolicyTest { private BluetoothAdapter mAdapter; private PhonePolicy mPhonePolicy; private boolean mOriginalDualModeState; private FakeFeatureFlagsImpl mFakeFlagsImpl; @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; Loading Loading @@ -101,7 +103,10 @@ public class PhonePolicyTest { // Must be called to initialize services mAdapter = BluetoothAdapter.getDefaultAdapter(); PhonePolicy.sConnectOtherProfilesTimeoutMillis = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS; mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); mFakeFlagsImpl = new FakeFeatureFlagsImpl(); mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); mOriginalDualModeState = Utils.isDualModeAudioEnabled(); } Loading Loading @@ -622,9 +627,8 @@ public class PhonePolicyTest { */ @Test public void testAutoConnectHfpOnly() { sIsHfpAutoConnectEnabled = true; mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); try { // Return desired values from the mocked object(s) doReturn(BluetoothAdapter.STATE_ON).when(mAdapterService).getState(); doReturn(false).when(mAdapterService).isQuietModeEnabled(); Loading @@ -636,7 +640,7 @@ public class PhonePolicyTest { .build(); DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); Loading @@ -656,14 +660,11 @@ public class PhonePolicyTest { // Check that we got a request to connect over HFP for each device verify(mHeadsetService).connect(eq(bondedDevice)); } finally { sIsHfpAutoConnectEnabled = false; } } @Test public void autoConnect_whenMultiHfp_startConnection() { sIsHfpAutoConnectEnabled = true; mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); sIsHfpMultiAutoConnectEnabled = true; try { Loading @@ -678,7 +679,8 @@ public class PhonePolicyTest { .build(); DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); Loading Loading @@ -706,13 +708,12 @@ public class PhonePolicyTest { } } finally { sIsHfpMultiAutoConnectEnabled = false; sIsHfpAutoConnectEnabled = false; } } @Test public void autoConnect_whenMultiHfpAndDeconnection_startConnection() { sIsHfpAutoConnectEnabled = true; mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); sIsHfpMultiAutoConnectEnabled = true; try { Loading @@ -727,7 +728,8 @@ public class PhonePolicyTest { .build(); DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); Loading Loading @@ -766,7 +768,6 @@ public class PhonePolicyTest { verify(mHeadsetService, times(0)).connect(eq(deviceToDeconnect)); } finally { sIsHfpMultiAutoConnectEnabled = false; sIsHfpAutoConnectEnabled = false; } } Loading
flags/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ aconfig_declarations { name: "bluetooth_aconfig_flags", package: "com.android.bluetooth.flags", srcs: [ "hfp.aconfig", "system_service.aconfig", ], } Loading @@ -15,6 +16,7 @@ java_aconfig_library { name: "bluetooth_flags_java_lib", aconfig_declarations: "bluetooth_aconfig_flags", visibility: [ "//packages/modules/Bluetooth/android/app", "//packages/modules/Bluetooth/service:__subpackages__", ], apex_available: [ Loading