Show turn off talkback dialog if needed in AudioStreamConfirmDialog
.
Test: atest Bug: b/362151254 Flag: com.android.settingslib.flags.enable_le_audio_sharing Change-Id: I29a20394193eca46ad8f42ffa0bceaad6f08da86
This commit is contained in:
@@ -34,6 +34,7 @@ import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
@@ -46,6 +47,7 @@ import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
@@ -74,12 +76,15 @@ import java.util.List;
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(
|
||||
shadows = {
|
||||
ShadowBluetoothAdapter.class,
|
||||
ShadowBluetoothUtils.class,
|
||||
ShadowBluetoothAdapter.class,
|
||||
ShadowBluetoothUtils.class,
|
||||
ShadowAudioStreamsHelper.class,
|
||||
})
|
||||
public class AudioStreamConfirmDialogTest {
|
||||
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
private static final String VALID_METADATA =
|
||||
"BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;"
|
||||
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||
@@ -88,12 +93,18 @@ public class AudioStreamConfirmDialogTest {
|
||||
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||
private static final String DEVICE_NAME = "device_name";
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||
@Mock private LocalBluetoothLeBroadcast mBroadcast;
|
||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock private VolumeControlProfile mVolumeControl;
|
||||
@Mock private BluetoothDevice mBluetoothDevice;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||
@Mock
|
||||
private LocalBluetoothLeBroadcast mBroadcast;
|
||||
@Mock
|
||||
private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock
|
||||
private VolumeControlProfile mVolumeControl;
|
||||
@Mock
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
private AudioStreamConfirmDialog mDialogFragment;
|
||||
|
||||
@Before
|
||||
@@ -376,6 +387,66 @@ public class AudioStreamConfirmDialogTest {
|
||||
verify(mDialogFragment.mActivity, times(2)).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showDialog_turnOffTalkback() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mBluetoothDevice);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
|
||||
when(mBluetoothDevice.getAlias()).thenReturn("");
|
||||
ShadowAudioStreamsHelper.setEnabledScreenReaderService(new ComponentName("pkg", "class"));
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(KEY_BROADCAST_METADATA, VALID_METADATA);
|
||||
FragmentController.of(mDialogFragment, intent)
|
||||
.create(/* containerViewId= */ 0, /* bundle= */ null)
|
||||
.start()
|
||||
.resume()
|
||||
.visible()
|
||||
.get();
|
||||
shadowMainLooper().idle();
|
||||
|
||||
assertThat(mDialogFragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_TURN_OFF_TALKBACK);
|
||||
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||
|
||||
var dialog = mDialogFragment.getDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
|
||||
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||
assertThat(title).isNotNull();
|
||||
assertThat(title.getText())
|
||||
.isEqualTo(
|
||||
mContext.getString(R.string.audio_streams_dialog_turn_off_talkback_title));
|
||||
TextView subtitle1 = dialog.findViewById(R.id.dialog_subtitle);
|
||||
assertThat(subtitle1).isNotNull();
|
||||
assertThat(subtitle1.getVisibility()).isEqualTo(View.GONE);
|
||||
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||
assertThat(subtitle2).isNotNull();
|
||||
assertThat(subtitle2.getText())
|
||||
.isEqualTo(mContext.getString(
|
||||
R.string.audio_streams_dialog_turn_off_talkback_subtitle));
|
||||
View leftButton = dialog.findViewById(R.id.left_button);
|
||||
assertThat(leftButton).isNotNull();
|
||||
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(leftButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
leftButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
|
||||
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||
assertThat(rightButton).isNotNull();
|
||||
assertThat(rightButton.getText())
|
||||
.isEqualTo(
|
||||
mContext.getString(R.string.audio_streams_dialog_turn_off_talkback_button));
|
||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
rightButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
verify(mDialogFragment.mActivity, times(2)).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showDialog_getDataStringFromIntent_confirmListen() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
|
@@ -36,22 +36,28 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||
import com.android.settingslib.accessibility.AccessibilityUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
@@ -75,11 +81,14 @@ import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(
|
||||
shadows = {
|
||||
ShadowAccessibilityManager.class,
|
||||
ShadowThreadUtils.class,
|
||||
ShadowBluetoothAdapter.class,
|
||||
})
|
||||
@@ -100,11 +109,17 @@ public class AudioStreamsHelperTest {
|
||||
@Mock private CachedBluetoothDevice mCachedDevice;
|
||||
@Mock private BluetoothDevice mDevice;
|
||||
@Mock private BluetoothDevice mSourceDevice;
|
||||
@Mock
|
||||
private AccessibilityServiceInfo mTalkbackServiceInfo;
|
||||
private ShadowAccessibilityManager mShadowAccessibilityManager;
|
||||
private AudioStreamsHelper mHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mSetFlagsRule.disableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
mShadowAccessibilityManager = Shadow.extract(
|
||||
mContext.getSystemService(AccessibilityManager.class));
|
||||
mShadowAccessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
|
||||
ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract(
|
||||
BluetoothAdapter.getDefaultAdapter());
|
||||
shadowBluetoothAdapter.setEnabled(true);
|
||||
@@ -348,6 +363,54 @@ public class AudioStreamsHelperTest {
|
||||
verify(appBarLayout).setExpanded(eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEnabledScreenReaderServices_noAccessibilityManager_returnEmpty() {
|
||||
mShadowAccessibilityManager = null;
|
||||
Set<ComponentName> result = AudioStreamsHelper.getEnabledScreenReaderServices(mContext);
|
||||
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEnabledScreenReaderServices_notEnabled_returnEmpty() {
|
||||
Resources resources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(resources);
|
||||
when(resources.getStringArray(R.array.config_preinstalled_screen_reader_services))
|
||||
.thenReturn(new String[]{"pkg/serviceClassName"});
|
||||
mShadowAccessibilityManager.setEnabledAccessibilityServiceList(
|
||||
new ArrayList<>());
|
||||
Set<ComponentName> result = AudioStreamsHelper.getEnabledScreenReaderServices(mContext);
|
||||
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEnabledScreenReaderServices_enabled_returnService() {
|
||||
Resources resources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(resources);
|
||||
when(resources.getStringArray(R.array.config_preinstalled_screen_reader_services))
|
||||
.thenReturn(new String[]{"pkg/serviceClassName"});
|
||||
ComponentName expected = new ComponentName("pkg", "serviceClassName");
|
||||
when(mTalkbackServiceInfo.getComponentName()).thenReturn(expected);
|
||||
mShadowAccessibilityManager.setEnabledAccessibilityServiceList(
|
||||
new ArrayList<>(List.of(mTalkbackServiceInfo)));
|
||||
Set<ComponentName> result = AudioStreamsHelper.getEnabledScreenReaderServices(mContext);
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
assertThat(result.iterator().next()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAccessibilityServiceOff_valueOff() {
|
||||
ComponentName componentName = new ComponentName("pkg", "serviceClassName");
|
||||
var target = new HashSet<ComponentName>();
|
||||
target.add(componentName);
|
||||
AudioStreamsHelper.setAccessibilityServiceOff(mContext, target);
|
||||
|
||||
assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext,
|
||||
UserHandle.myUserId())).isEmpty();
|
||||
}
|
||||
|
||||
private void setUpFragment(
|
||||
FragmentActivity fragmentActivity, AppBarLayout appBarLayout, int orientationPortrait) {
|
||||
Resources resources = mock(Resources.class);
|
||||
|
@@ -21,6 +21,8 @@ import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssista
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -33,14 +35,17 @@ import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Implements(value = AudioStreamsHelper.class, callThroughByDefault = true)
|
||||
public class ShadowAudioStreamsHelper {
|
||||
private static AudioStreamsHelper sMockHelper;
|
||||
@Nullable private static CachedBluetoothDevice sCachedBluetoothDevice;
|
||||
@Nullable private static ComponentName sEnabledScreenReaderService;
|
||||
|
||||
public static void setUseMock(AudioStreamsHelper mockAudioStreamsHelper) {
|
||||
sMockHelper = mockAudioStreamsHelper;
|
||||
@@ -51,6 +56,7 @@ public class ShadowAudioStreamsHelper {
|
||||
public static void reset() {
|
||||
sMockHelper = null;
|
||||
sCachedBluetoothDevice = null;
|
||||
sEnabledScreenReaderService = null;
|
||||
}
|
||||
|
||||
public static void setCachedBluetoothDeviceInSharingOrLeConnected(
|
||||
@@ -58,6 +64,10 @@ public class ShadowAudioStreamsHelper {
|
||||
sCachedBluetoothDevice = cachedBluetoothDevice;
|
||||
}
|
||||
|
||||
public static void setEnabledScreenReaderService(ComponentName componentName) {
|
||||
sEnabledScreenReaderService = componentName;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public Map<Integer, LocalBluetoothLeBroadcastSourceState> getConnectedBroadcastIdAndState(
|
||||
boolean hysteresisModeFixAvailable) {
|
||||
@@ -76,6 +86,15 @@ public class ShadowAudioStreamsHelper {
|
||||
return Optional.ofNullable(sCachedBluetoothDevice);
|
||||
}
|
||||
|
||||
/** Retrieves a set of enabled screen reader services that are pre-installed. */
|
||||
@Implementation
|
||||
public static Set<ComponentName> getEnabledScreenReaderServices(Context context) {
|
||||
if (sEnabledScreenReaderService != null) {
|
||||
return Set.of(sEnabledScreenReaderService);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
||||
return sMockHelper.getLeBroadcastAssistant();
|
||||
|
Reference in New Issue
Block a user