Merge "[Output Switcher] Add support for device disabled reason"
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