[Output Switcher] Add support for device disabled reason
Implement support in MediaDevice for device status, which used for showing under subtext. When dsiabled reason exist, Output Switcher should disable the device and show corresponded reason in subtext. Test: atest MediaOutputAdapterTest MediaOutputControllerTest MediaOutputBaseDialogTest MediaOutputDialogTest Bug:260021954 Change-Id: Ia6e8fd4f7ca066e85c4afcc688ff1875c9e60964
This commit is contained in:
@@ -30,6 +30,7 @@ import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
|
||||
import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
|
||||
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
|
||||
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
|
||||
import static android.media.RouteListingPreference.Item.DISABLE_REASON_NONE;
|
||||
import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED_ROUTE;
|
||||
|
||||
import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_SELECTED;
|
||||
@@ -192,6 +193,27 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
|
||||
*/
|
||||
public abstract String getId();
|
||||
|
||||
/**
|
||||
* Get disabled reason of device
|
||||
*
|
||||
* @return disabled reason of device
|
||||
*/
|
||||
@RouteListingPreference.Item.DisableReason
|
||||
public int getDisableReason() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && mItem != null
|
||||
? mItem.getDisableReason() : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if device is has disabled reason
|
||||
*
|
||||
* @return true if device has disabled reason
|
||||
*/
|
||||
public boolean hasDisabledReason() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && mItem != null
|
||||
&& mItem.getDisableReason() != DISABLE_REASON_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if device is suggested device from application
|
||||
*
|
||||
|
||||
@@ -2522,6 +2522,8 @@
|
||||
<string name="media_output_group_title_speakers_and_displays">Speakers & Displays</string>
|
||||
<!-- Title for Suggested Devices group. [CHAR LIMIT=NONE] -->
|
||||
<string name="media_output_group_title_suggested_device">Suggested Devices</string>
|
||||
<!-- Sub status indicates device need premium account. [CHAR LIMIT=NONE] -->
|
||||
<string name="media_output_status_require_premium">Requires premium account</string>
|
||||
|
||||
<!-- Media Output Broadcast Dialog -->
|
||||
<!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
|
||||
|
||||
@@ -16,17 +16,24 @@
|
||||
|
||||
package com.android.systemui.media.dialog;
|
||||
|
||||
import static android.media.RouteListingPreference.Item.DISABLE_REASON_SUBSCRIPTION_REQUIRED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.RouteListingPreference;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DoNotInline;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.widget.CompoundButtonCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@@ -186,6 +193,17 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
||||
mCurrentActivePosition = position;
|
||||
updateFullItemClickListener(v -> onItemClick(v, device));
|
||||
setSingleLineLayout(getItemTitle(device));
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||
&& mController.isSubStatusSupported() && device.hasDisabledReason()) {
|
||||
//update to subtext with device status
|
||||
setUpDeviceIcon(device);
|
||||
mSubTitleText.setText(
|
||||
Api34Impl.composeDisabledReason(device.getDisableReason(), mContext));
|
||||
updateConnectionFailedStatusIcon();
|
||||
updateFullItemClickListener(null);
|
||||
setTwoLineLayout(device, false /* bFocused */, false /* showSeekBar */,
|
||||
false /* showProgressBar */, true /* showSubtitle */,
|
||||
true /* showStatus */);
|
||||
} else if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
|
||||
setUpDeviceIcon(device);
|
||||
updateConnectionFailedStatusIcon();
|
||||
@@ -389,4 +407,17 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
||||
mTitleText.setText(groupDividerTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(34)
|
||||
private static class Api34Impl {
|
||||
@DoNotInline
|
||||
static String composeDisabledReason(@RouteListingPreference.Item.DisableReason int reason,
|
||||
Context context) {
|
||||
switch(reason) {
|
||||
case DISABLE_REASON_SUBSCRIPTION_REQUIRED:
|
||||
return context.getString(R.string.media_output_status_require_premium);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,6 +748,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING);
|
||||
}
|
||||
|
||||
public boolean isSubStatusSupported() {
|
||||
return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_DEVICE_STATUS);
|
||||
}
|
||||
|
||||
List<MediaDevice> getGroupMediaDevices() {
|
||||
final List<MediaDevice> selectedDevices = getSelectedMediaDevice();
|
||||
final List<MediaDevice> selectableDevices = getSelectableMediaDevice();
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.media.dialog;
|
||||
|
||||
import static android.media.RouteListingPreference.Item.DISABLE_REASON_SUBSCRIPTION_REQUIRED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -57,6 +59,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
||||
private static final String TEST_DEVICE_ID_1 = "test_device_id_1";
|
||||
private static final String TEST_DEVICE_ID_2 = "test_device_id_2";
|
||||
private static final String TEST_SESSION_NAME = "test_session_name";
|
||||
|
||||
private static final int TEST_MAX_VOLUME = 20;
|
||||
private static final int TEST_CURRENT_VOLUME = 10;
|
||||
|
||||
@@ -78,6 +81,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(false);
|
||||
when(mMediaOutputController.isSubStatusSupported()).thenReturn(false);
|
||||
when(mMediaOutputController.getMediaItemList()).thenReturn(mMediaItems);
|
||||
when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
|
||||
when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
|
||||
@@ -403,6 +407,25 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
||||
assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subStatusSupported_onBindViewHolder_bindFailedStateDevice_verifyView() {
|
||||
String deviceStatus = (String) mContext.getText(
|
||||
R.string.media_output_status_require_premium);
|
||||
when(mMediaOutputController.isSubStatusSupported()).thenReturn(true);
|
||||
when(mMediaDevice2.hasDisabledReason()).thenReturn(true);
|
||||
when(mMediaDevice2.getDisableReason()).thenReturn(DISABLE_REASON_SUBSCRIPTION_REQUIRED);
|
||||
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
|
||||
|
||||
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mSubTitleText.getText()).isEqualTo(deviceStatus);
|
||||
assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_inTransferring_bindTransferringDevice_verifyView() {
|
||||
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(true);
|
||||
|
||||
Reference in New Issue
Block a user