diff --git a/res/values/strings.xml b/res/values/strings.xml
index 97a7e232304..c6d44c180db 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5639,7 +5639,7 @@
Language
- Text size
+ Caption size
Caption style
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
index 468ac3d5652..11a337fb616 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
@@ -219,7 +219,7 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
if (lead != null) {
String addr = lead.getDevice().getAnonymizedAddress();
Log.d(TAG, "Set call audio device: " + addr);
- lead.setActive();
+ AudioSharingUtils.setPrimary(mContext, lead);
logCallAudioDeviceChange(currentGroupId, lead);
} else {
Log.d(TAG, "Skip set call audio device: no lead");
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index db2c7b21b1b..47623e4f197 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -390,7 +390,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
Log.d(TAG, "onDeviceClick, set active in call mode");
CachedBluetoothDevice cachedDevice =
((BluetoothDevicePreference) preference).getBluetoothDevice();
- cachedDevice.setActive();
+ AudioSharingUtils.setPrimary(mContext, cachedDevice);
}
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK,
isCallMode);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
index 396144ab16c..0c3448729b8 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
@@ -192,7 +192,7 @@ public class AudioSharingDialogHandler {
// If this method is called with user triggered, e.g. manual click on the
// "Connected devices" page, we need call setActive for the device, since user
// intend to switch active device for the call.
- cachedDevice.setActive();
+ AudioSharingUtils.setPrimary(mContext, cachedDevice);
}
return;
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index a662809fb78..592c8eb84c5 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -21,6 +21,7 @@ import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtil
import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID;
import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID;
import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED;
+import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID;
import static java.util.stream.Collectors.toList;
@@ -28,6 +29,7 @@ import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.content.Context;
+import android.provider.Settings;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;
@@ -44,6 +46,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.bluetooth.VolumeControlProfile;
+import com.android.settingslib.flags.Flags;
import java.util.ArrayList;
import java.util.Comparator;
@@ -344,6 +347,27 @@ public class AudioSharingUtils {
return vc != null && vc.isProfileReady();
}
+ /** Set {@link CachedBluetoothDevice} as primary device for call audio */
+ public static void setPrimary(@NonNull Context context,
+ @Nullable CachedBluetoothDevice cachedDevice) {
+ if (cachedDevice == null) return;
+ cachedDevice.setActive();
+ if (Flags.audioSharingHysteresisModeFix()) {
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
+ // TODO: use real key name in SettingsProvider
+ int userPreferredId = Settings.Secure.getInt(
+ context.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ if (groupId != userPreferredId) {
+ Settings.Secure.putInt(
+ context.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ groupId);
+ }
+ }
+ }
+
/**
* Build audio sharing dialog log event data
*
diff --git a/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt b/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt
index 2c0955b42b0..b94f52c8d40 100644
--- a/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt
+++ b/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt
@@ -38,9 +38,17 @@ class SpaSearchLandingActivity : Activity() {
finish()
}
- private fun isValidCall() =
- PasswordUtils.getCallingAppPackageName(activityToken) ==
+ private fun isValidCall(): Boolean {
+ val callingAppPackageName = PasswordUtils.getCallingAppPackageName(activityToken)
+ if (callingAppPackageName == packageName) {
+ // SettingsIntelligence sometimes starts SearchResultTrampoline first, in this case,
+ // SearchResultTrampoline checks if the call is valid, then SearchResultTrampoline will
+ // start this activity, allow this use case.
+ return true
+ }
+ return callingAppPackageName ==
featureFactory.searchFeatureProvider.getSettingsIntelligencePkgName(this)
+ }
companion object {
@VisibleForTesting
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
index 61bc8aaa055..0bc0b949193 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
@@ -18,6 +18,7 @@ package com.android.settings.connecteddevice.audiosharing;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_BLUETOOTH_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -37,6 +38,7 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata;
@@ -50,6 +52,7 @@ import android.media.AudioManager;
import android.os.Bundle;
import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
import android.util.Pair;
import androidx.annotation.NonNull;
@@ -587,6 +590,10 @@ public class AudioSharingDevicePreferenceControllerTest {
@Test
public void testInCallState_showCallStateTitleAndSetActiveOnDeviceClick() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+ mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
mController.displayPreference(mScreen);
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
@@ -599,6 +606,32 @@ public class AudioSharingDevicePreferenceControllerTest {
BluetoothDevicePreference preference = createBluetoothDevicePreference();
mController.onDeviceClick(preference);
verify(mCachedDevice).setActive();
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID)).isEqualTo(
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ }
+
+ @Test
+ public void testInCallState_enableHysteresisFix_setAndSaveActiveOnDeviceClick() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+ mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ mController.displayPreference(mScreen);
+
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ mController.onAudioModeChanged();
+ shadowOf(Looper.getMainLooper()).idle();
+
+ BluetoothDevicePreference preference = createBluetoothDevicePreference();
+ when(mCachedDevice.getGroupId()).thenReturn(1);
+ mController.onDeviceClick(preference);
+ verify(mCachedDevice).setActive();
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID)).isEqualTo(1);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
index ad6dd7f0754..c96a08623f8 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.connecteddevice.audiosharing;
+import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -32,6 +34,7 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
@@ -43,6 +46,7 @@ import android.media.AudioManager;
import android.os.Bundle;
import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
import android.util.Pair;
import androidx.fragment.app.DialogFragment;
@@ -193,6 +197,10 @@ public class AudioSharingDialogHandlerTest {
@Test
public void handleUserTriggeredDeviceConnected_inCall_setActive() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
setUpBroadcast(true);
ImmutableList deviceList = ImmutableList.of(mDevice1);
@@ -201,6 +209,29 @@ public class AudioSharingDialogHandlerTest {
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
verify(mCachedDevice1).setActive();
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID)).isEqualTo(
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ }
+
+ @Test
+ public void handleUserTriggeredDeviceConnected_inCall_enableHysteresisFix_setAndSaveActive() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
+ setUpBroadcast(true);
+ ImmutableList deviceList = ImmutableList.of(mDevice1);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
+ when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
+ mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
+ shadowOf(Looper.getMainLooper()).idle();
+ verify(mCachedDevice1).setActive();
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID)).isEqualTo(1);
}
@Test