Merge "Re-add volume slider to the MediaRouteControllerDialog" into lmp-mr1-ub-dev
diff --git a/v7/mediarouter/api/current.txt b/v7/mediarouter/api/current.txt
index 1c68702..a382a89 100644
--- a/v7/mediarouter/api/current.txt
+++ b/v7/mediarouter/api/current.txt
@@ -47,7 +47,9 @@
method public android.view.View getMediaControlView();
method public android.support.v4.media.session.MediaSessionCompat.Token getMediaSession();
method public android.support.v7.media.MediaRouter.RouteInfo getRoute();
+ method public boolean isVolumeControlEnabled();
method public android.view.View onCreateMediaControlView(android.os.Bundle);
+ method public void setVolumeControlEnabled(boolean);
}
public class MediaRouteControllerDialogFragment extends android.support.v4.app.DialogFragment {
diff --git a/v7/mediarouter/res/layout/mr_media_route_controller_material_dialog_b.xml b/v7/mediarouter/res/layout/mr_media_route_controller_material_dialog_b.xml
index 3b12b24..9482642 100644
--- a/v7/mediarouter/res/layout/mr_media_route_controller_material_dialog_b.xml
+++ b/v7/mediarouter/res/layout/mr_media_route_controller_material_dialog_b.xml
@@ -96,6 +96,25 @@
</LinearLayout>
</RelativeLayout>
</FrameLayout>
+ <!-- Optional volume slider section. -->
+ <LinearLayout android:id="@+id/media_route_volume_layout"
+ android:layout_width="fill_parent"
+ android:layout_height="64dp"
+ android:gravity="center_vertical"
+ android:padding="8dp"
+ android:visibility="gone">
+ <ImageView android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:src="@drawable/mr_ic_audio_vol"
+ android:gravity="center"
+ android:scaleType="center" />
+ <SeekBar android:id="@+id/media_route_volume_slider"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp" />
+ </LinearLayout>
<LinearLayout android:id="@+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
index b43af77..3312f7f 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
@@ -19,7 +19,6 @@
import android.app.Dialog;
import android.content.Context;
import android.content.IntentSender;
-import android.content.IntentSender.SendIntentException;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.RemoteException;
@@ -40,6 +39,8 @@
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
import android.widget.TextView;
/**
@@ -54,6 +55,11 @@
public class MediaRouteControllerDialog extends Dialog {
private static final String TAG = "MediaRouteControllerDialog";
+ // Time to wait before updating the volume when the user lets go of the seek bar
+ // to allow the route provider time to propagate the change and publish a new
+ // route descriptor.
+ private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
+
private final MediaRouter mRouter;
private final MediaRouterCallback mCallback;
private final MediaRouter.RouteInfo mRoute;
@@ -62,8 +68,6 @@
private boolean mAttachedToWindow;
private Drawable mMediaRouteConnectingDrawable;
private Drawable mMediaRouteOnDrawable;
- private Drawable mCurrentIconDrawable;
- private Drawable mSettingsDrawable;
private View mControlView;
@@ -78,6 +82,11 @@
private TextView mRouteNameView;
private View mTitlesWrapper;
+ private boolean mVolumeControlEnabled = true;
+ private LinearLayout mVolumeLayout;
+ private SeekBar mVolumeSlider;
+ private boolean mVolumeSliderTouched;
+
private MediaControllerCompat mMediaController;
private MediaControllerCallback mControllerCallback;
private PlaybackStateCompat mState;
@@ -128,6 +137,30 @@
}
/**
+ * Sets whether to enable the volume slider and volume control using the volume keys
+ * when the route supports it.
+ * <p>
+ * The default value is true.
+ * </p>
+ */
+ public void setVolumeControlEnabled(boolean enable) {
+ if (mVolumeControlEnabled != enable) {
+ mVolumeControlEnabled = enable;
+ if (mCreated) {
+ updateVolume();
+ }
+ }
+ }
+
+ /**
+ * Returns whether to enable the volume slider and volume control using the volume keys
+ * when the route supports it.
+ */
+ public boolean isVolumeControlEnabled() {
+ return mVolumeControlEnabled;
+ }
+
+ /**
* Set the session to use for metadata and transport controls. The dialog
* will listen to changes on this session and update the UI automatically in
* response to changes.
@@ -195,6 +228,43 @@
mPlayPauseButton = (ImageButton) findViewById(R.id.play_pause);
mPlayPauseButton.setOnClickListener(listener);
mRouteNameView = (TextView) findViewById(R.id.route_name);
+ mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
+ mVolumeSlider = (SeekBar)findViewById(R.id.media_route_volume_slider);
+ mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ private final Runnable mStopTrackingTouch = new Runnable() {
+ @Override
+ public void run() {
+ if (mVolumeSliderTouched) {
+ mVolumeSliderTouched = false;
+ updateVolume();
+ }
+ }
+ };
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ if (mVolumeSliderTouched) {
+ mVolumeSlider.removeCallbacks(mStopTrackingTouch);
+ } else {
+ mVolumeSliderTouched = true;
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // Defer resetting mVolumeSliderTouched to allow the media route provider
+ // a little time to settle into its new state and publish the final
+ // volume update.
+ mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ mRoute.requestSetVolume(progress);
+ }
+ }
+ });
mCreated = true;
if (update()) {
@@ -254,6 +324,8 @@
return false;
}
+ updateVolume();
+
mRouteNameView.setText(mRoute.getName());
if (mRoute.canDisconnect()) {
@@ -353,6 +425,23 @@
}
}
+ private void updateVolume() {
+ if (!mVolumeSliderTouched) {
+ if (isVolumeControlAvailable()) {
+ mVolumeLayout.setVisibility(View.VISIBLE);
+ mVolumeSlider.setMax(mRoute.getVolumeMax());
+ mVolumeSlider.setProgress(mRoute.getVolume());
+ } else {
+ mVolumeLayout.setVisibility(View.GONE);
+ }
+ }
+ }
+
+ private boolean isVolumeControlAvailable() {
+ return mVolumeControlEnabled && mRoute.getVolumeHandling() ==
+ MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
+ }
+
private final class MediaRouterCallback extends MediaRouter.Callback {
@Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
@@ -367,6 +456,7 @@
@Override
public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
if (route == mRoute) {
+ updateVolume();
}
}
}