Add remote volume slider conditionally.

Issue before this CL:
RemoteVolumePreferenceController only return available when
it is casting, otherwise return CONDITIONALLY_UNAVAILABLE.
However slice database only index available controllers and keep
this cache. So remote slider won't be indexed if it is not casting
at that time.

As a tmp fix, this CL make controller always return available
unsearchable to make it indexed by database. However only add
that slice if it is casting.

Bug: 130124950
Test: RunSettingsRoboTests
Change-Id: I191144844d6ba7ccbe3dc1c9d19801adb978abc6
This commit is contained in:
Lei Yu
2019-04-12 14:23:33 -07:00
parent fd3cf32ad8
commit c1dbd34b9d
3 changed files with 36 additions and 13 deletions

View File

@@ -43,7 +43,6 @@ public class RemoteVolumePreferenceController extends VolumeSeekBarPreferenceCon
@VisibleForTesting @VisibleForTesting
static final int REMOTE_VOLUME = 100; static final int REMOTE_VOLUME = 100;
private MediaSessionManager mMediaSessionManager;
private MediaSessions mMediaSessions; private MediaSessions mMediaSessions;
@VisibleForTesting @VisibleForTesting
MediaSession.Token mActiveToken; MediaSession.Token mActiveToken;
@@ -86,28 +85,39 @@ public class RemoteVolumePreferenceController extends VolumeSeekBarPreferenceCon
public RemoteVolumePreferenceController(Context context) { public RemoteVolumePreferenceController(Context context) {
super(context, KEY_REMOTE_VOLUME); super(context, KEY_REMOTE_VOLUME);
mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
mMediaSessions = new MediaSessions(context, Looper.getMainLooper(), mCallbacks); mMediaSessions = new MediaSessions(context, Looper.getMainLooper(), mCallbacks);
updateToken(getActiveRemoteToken(mContext));
} }
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
final List<MediaController> controllers = mMediaSessionManager.getActiveSessions(null); // Always return true to make it indexed in database
return AVAILABLE_UNSEARCHABLE;
}
/**
* Return {@link android.media.session.MediaSession.Token} for active remote token, or
* {@code null} if there is no active remote token.
*/
public static MediaSession.Token getActiveRemoteToken(Context context) {
final MediaSessionManager sessionManager = context.getSystemService(
MediaSessionManager.class);
final List<MediaController> controllers = sessionManager.getActiveSessions(null);
for (MediaController mediaController : controllers) { for (MediaController mediaController : controllers) {
final MediaController.PlaybackInfo pi = mediaController.getPlaybackInfo(); final MediaController.PlaybackInfo pi = mediaController.getPlaybackInfo();
if (isRemote(pi)) { if (isRemote(pi)) {
updateToken(mediaController.getSessionToken()); return mediaController.getSessionToken();
return AVAILABLE;
} }
} }
// No active remote media at this point // No active remote media at this point
return CONDITIONALLY_UNAVAILABLE; return null;
} }
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mPreference.setVisible(mActiveToken != null);
if (mMediaController != null) { if (mMediaController != null) {
updatePreference(mPreference, mActiveToken, mMediaController.getPlaybackInfo()); updatePreference(mPreference, mActiveToken, mMediaController.getPlaybackInfo());
} }

View File

@@ -30,6 +30,7 @@ import android.net.Uri;
import android.provider.Settings; import android.provider.Settings;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.notification.RemoteVolumePreferenceController;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -54,7 +55,9 @@ public class VolumePanel implements PanelContent {
@Override @Override
public List<Uri> getSlices() { public List<Uri> getSlices() {
final List<Uri> uris = new ArrayList<>(); final List<Uri> uris = new ArrayList<>();
uris.add(VOLUME_REMOTE_MEDIA_URI); if (RemoteVolumePreferenceController.getActiveRemoteToken(mContext) != null) {
uris.add(VOLUME_REMOTE_MEDIA_URI);
}
uris.add(VOLUME_MEDIA_URI); uris.add(VOLUME_MEDIA_URI);
uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI); uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
uris.add(VOLUME_CALL_URI); uris.add(VOLUME_CALL_URI);

View File

@@ -29,10 +29,12 @@ import android.media.session.MediaSession;
import android.media.session.MediaSessionManager; import android.media.session.MediaSessionManager;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
@@ -50,9 +52,9 @@ public class RemoteVolumePreferenceControllerTest {
private MediaSessionManager mMediaSessionManager; private MediaSessionManager mMediaSessionManager;
@Mock @Mock
private MediaController mMediaController; private MediaController mMediaController;
@Mock @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private ISessionController mStub; private ISessionController mStub;
@Mock @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private ISessionController mStub2; private ISessionController mStub2;
private MediaSession.Token mToken; private MediaSession.Token mToken;
private MediaSession.Token mToken2; private MediaSession.Token mToken2;
@@ -78,22 +80,30 @@ public class RemoteVolumePreferenceControllerTest {
mPlaybackInfo = new MediaController.PlaybackInfo( mPlaybackInfo = new MediaController.PlaybackInfo(
MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, 0, MAX_POS, CURRENT_POS, null); MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, 0, MAX_POS, CURRENT_POS, null);
when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
when(mMediaController.getSessionToken()).thenReturn(mToken);
} }
@Test @Test
public void isAvailable_containRemoteMedia_returnTrue() { public void getActiveRemoteToken_containRemoteMedia_returnToken() {
when(mMediaController.getPlaybackInfo()).thenReturn( when(mMediaController.getPlaybackInfo()).thenReturn(
new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
0, 0, 0, null)); 0, 0, 0, null));
assertThat(mController.isAvailable()).isTrue(); assertThat(mController.getActiveRemoteToken(mContext)).isEqualTo(mToken);
} }
@Test @Test
public void isAvailable_noRemoteMedia_returnFalse() { public void getActiveRemoteToken_noRemoteMedia_returnNull() {
when(mMediaController.getPlaybackInfo()).thenReturn( when(mMediaController.getPlaybackInfo()).thenReturn(
new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL, new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
0, 0, 0, null)); 0, 0, 0, null));
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.getActiveRemoteToken(mContext)).isNull();
}
@Test
public void isAvailable_returnAvailableUnsearchable() {
assertThat(mController.isAvailable()).isTrue();
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE_UNSEARCHABLE);
} }
@Test @Test