MediaRouter: Enable volume group expansion
Bug: 23115937
Change-Id: I97f14d0d74b20723406068caa652d6afe1fcaf74
diff --git a/v7/mediarouter/res/drawable-hdpi/ic_audiotrack.png b/v7/mediarouter/res/drawable-hdpi/ic_audiotrack.png
new file mode 100644
index 0000000..71db6b4
--- /dev/null
+++ b/v7/mediarouter/res/drawable-hdpi/ic_audiotrack.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-hdpi/ic_audiotrack_light.png b/v7/mediarouter/res/drawable-hdpi/ic_audiotrack_light.png
new file mode 100644
index 0000000..d7c8252
--- /dev/null
+++ b/v7/mediarouter/res/drawable-hdpi/ic_audiotrack_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-mdpi/ic_audiotrack.png b/v7/mediarouter/res/drawable-mdpi/ic_audiotrack.png
new file mode 100644
index 0000000..dc1200e
--- /dev/null
+++ b/v7/mediarouter/res/drawable-mdpi/ic_audiotrack.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-mdpi/ic_audiotrack_light.png b/v7/mediarouter/res/drawable-mdpi/ic_audiotrack_light.png
new file mode 100644
index 0000000..2cf7e0c
--- /dev/null
+++ b/v7/mediarouter/res/drawable-mdpi/ic_audiotrack_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xhdpi/ic_audiotrack.png b/v7/mediarouter/res/drawable-xhdpi/ic_audiotrack.png
new file mode 100644
index 0000000..b5c899f
--- /dev/null
+++ b/v7/mediarouter/res/drawable-xhdpi/ic_audiotrack.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xhdpi/ic_audiotrack_light.png b/v7/mediarouter/res/drawable-xhdpi/ic_audiotrack_light.png
new file mode 100644
index 0000000..4778e00
--- /dev/null
+++ b/v7/mediarouter/res/drawable-xhdpi/ic_audiotrack_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xxhdpi/ic_audiotrack.png b/v7/mediarouter/res/drawable-xxhdpi/ic_audiotrack.png
new file mode 100644
index 0000000..0546539
--- /dev/null
+++ b/v7/mediarouter/res/drawable-xxhdpi/ic_audiotrack.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xxhdpi/ic_audiotrack_light.png b/v7/mediarouter/res/drawable-xxhdpi/ic_audiotrack_light.png
new file mode 100644
index 0000000..8e38265
--- /dev/null
+++ b/v7/mediarouter/res/drawable-xxhdpi/ic_audiotrack_light.png
Binary files differ
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 f53cc7a..66544ec 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
@@ -123,6 +123,11 @@
android:background="?attr/selectableItemBackgroundBorderless"
android:visibility="gone"/>
</LinearLayout>
+ <ListView android:id="@+id/media_route_volume_group_list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone">
+ </ListView>
<LinearLayout android:id="@+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/v7/mediarouter/res/layout/mr_media_route_controller_volume_item.xml b/v7/mediarouter/res/layout/mr_media_route_controller_volume_item.xml
new file mode 100644
index 0000000..d07d94b
--- /dev/null
+++ b/v7/mediarouter/res/layout/mr_media_route_controller_volume_item.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="64dp"
+ android:padding="8dp">
+ <TextView android:id="@+id/media_route_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true" />
+ <ImageView android:id="@+id/media_route_volume_item_icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_below="@id/media_route_name"
+ android:layout_alignParentLeft="true"
+ android:src="?attr/mediaRouteAudioTrackDrawable"
+ android:gravity="center"
+ android:scaleType="center" />
+ <SeekBar android:id="@+id/media_route_volume_slider"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/media_route_name"
+ android:layout_toRightOf="@id/media_route_volume_item_icon"
+ android:layout_gravity="center_vertical"
+ android:layout_marginTop="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp" />
+</RelativeLayout>
diff --git a/v7/mediarouter/res/values/attrs.xml b/v7/mediarouter/res/values/attrs.xml
index 73f589f..56381c7 100644
--- a/v7/mediarouter/res/values/attrs.xml
+++ b/v7/mediarouter/res/values/attrs.xml
@@ -34,6 +34,7 @@
<attr name="mediaRoutePlayDrawable" format="reference" />
<attr name="mediaRoutePauseDrawable" format="reference" />
<attr name="mediaRouteCastDrawable" format="reference" />
+ <attr name="mediaRouteAudioTrackDrawable" format="reference" />
<attr name="mediaRouteDefaultIconDrawable" format="reference" />
<attr name="mediaRouteSpeakerIconDrawable" format="reference" />
<attr name="mediaRouteSpeakerGroupIconDrawable" format="reference" />
diff --git a/v7/mediarouter/res/values/themes.xml b/v7/mediarouter/res/values/themes.xml
index eb2d8ac..8c5a072 100644
--- a/v7/mediarouter/res/values/themes.xml
+++ b/v7/mediarouter/res/values/themes.xml
@@ -27,6 +27,7 @@
<item name="mediaRoutePlayDrawable">@drawable/mr_ic_play_dark</item>
<item name="mediaRoutePauseDrawable">@drawable/mr_ic_pause_dark</item>
<item name="mediaRouteCastDrawable">@drawable/mr_ic_cast_dark</item>
+ <item name="mediaRouteAudioTrackDrawable">@drawable/ic_audiotrack</item>
<item name="mediaRouteDefaultIconDrawable">@drawable/ic_tv_dark</item>
<item name="mediaRouteSpeakerIconDrawable">@drawable/ic_speaker_dark</item>
<item name="mediaRouteSpeakerGroupIconDrawable">@drawable/ic_speaker_group_dark</item>
@@ -36,8 +37,7 @@
<item name="mediaRouteCollapseGroupDrawable">@drawable/ic_keyboard_arrow_up_white</item>
</style>
- <style name="Theme.MediaRouter.Light" parent="">
- <item name="android:windowNoTitle">false</item>
+ <style name="Theme.MediaRouter.Light">
<item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.Light.MediaRouteButton</item>
<item name="mediaRouteOffDrawable">@drawable/ic_cast_off_light</item>
@@ -47,6 +47,7 @@
<item name="mediaRoutePlayDrawable">@drawable/mr_ic_play_light</item>
<item name="mediaRoutePauseDrawable">@drawable/mr_ic_pause_light</item>
<item name="mediaRouteCastDrawable">@drawable/mr_ic_cast_light</item>
+ <item name="mediaRouteAudioTrackDrawable">@drawable/ic_audiotrack_light</item>
<item name="mediaRouteDefaultIconDrawable">@drawable/ic_tv_light</item>
<item name="mediaRouteSpeakerIconDrawable">@drawable/ic_speaker_light</item>
<item name="mediaRouteSpeakerGroupIconDrawable">@drawable/ic_speaker_group_light</item>
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java
index 569c736..8b5d6fc 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java
@@ -207,14 +207,14 @@
public RouteAdapter(Context context, List<MediaRouter.RouteInfo> routes) {
super(context, 0, routes);
mInflater = LayoutInflater.from(context);
- int[] attrs = new int[] {
+ TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] {
R.attr.mediaRouteDefaultIconDrawable,
R.attr.mediaRouteSpeakerIconDrawable,
- R.attr.mediaRouteSpeakerGroupIconDrawable };
- TypedArray styledAttributes = getContext().obtainStyledAttributes(attrs);
+ R.attr.mediaRouteSpeakerGroupIconDrawable });
mDefaultIcon = styledAttributes.getDrawable(0);
mSpeakerIcon = styledAttributes.getDrawable(1);
mSpeakerGroupIcon = styledAttributes.getDrawable(2);
+ styledAttributes.recycle();
}
@Override
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
index 3fa67d2..6f69388 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
@@ -16,9 +16,12 @@
package android.support.v7.app;
+import static android.widget.SeekBar.OnSeekBarChangeListener;
+
import android.content.ContentResolver;
import android.content.Context;
import android.content.IntentSender;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
@@ -38,19 +41,22 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.BufferedInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
+import java.util.List;
/**
* This class implements the route controller dialog for {@link MediaRouter}.
@@ -96,6 +102,7 @@
private boolean mVolumeControlEnabled = true;
private LinearLayout mVolumeLayout;
+ private ListView mVolumeGroupList;
private SeekBar mVolumeSlider;
private boolean mVolumeSliderTouched;
@@ -128,6 +135,13 @@
return mRoute;
}
+ private MediaRouter.RouteGroup getGroup() {
+ if (mRoute instanceof MediaRouter.RouteGroup) {
+ return (MediaRouter.RouteGroup) mRoute;
+ }
+ return null;
+ }
+
/**
* Provides the subclass an opportunity to create a view that will
* be included within the body of the dialog to offer additional media controls
@@ -239,8 +253,34 @@
mPlayPauseButton.setOnClickListener(listener);
mRouteNameView = (TextView) findViewById(R.id.route_name);
mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
+ mVolumeGroupList = (ListView)findViewById(R.id.media_route_volume_group_list);
+
+ TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] {
+ R.attr.mediaRouteExpandGroupDrawable,
+ R.attr.mediaRouteCollapseGroupDrawable });
+ final Drawable expandGroupDrawable = styledAttributes.getDrawable(0);
+ final Drawable collapseGroupDrawable = styledAttributes.getDrawable(1);
+ styledAttributes.recycle();
+
mGroupExpandCollapseButton = (ImageButton)findViewById(
R.id.media_route_group_expand_collapse);
+ mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() {
+ private boolean mIsExpanded;
+
+ @Override
+ public void onClick(View v) {
+ mIsExpanded = !mIsExpanded;
+ if (mIsExpanded) {
+ mGroupExpandCollapseButton.setImageDrawable(collapseGroupDrawable);
+ mVolumeGroupList.setVisibility(View.VISIBLE);
+ mVolumeGroupList.setAdapter(
+ new VolumeGroupAdapter(getContext(), getGroup().getRoutes()));
+ } else {
+ mGroupExpandCollapseButton.setImageDrawable(expandGroupDrawable);
+ mVolumeGroupList.setVisibility(View.GONE);
+ }
+ }
+ });
mVolumeSlider = (SeekBar)findViewById(R.id.media_route_volume_slider);
mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
private final Runnable mStopTrackingTouch = new Runnable() {
@@ -431,7 +471,7 @@
mVolumeSlider.setProgress(mRoute.getVolume());
if (USE_GROUP) {
mGroupExpandCollapseButton.setVisibility(
- mRoute instanceof MediaRouter.RouteGroup ? View.VISIBLE : View.GONE);
+ getGroup() != null ? View.VISIBLE : View.GONE);
}
} else {
mVolumeLayout.setVisibility(View.GONE);
@@ -518,6 +558,51 @@
}
}
+ private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> {
+ final OnSeekBarChangeListener mOnSeekBarChangeListener = new OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ int position = (int) seekBar.getTag();
+ getGroup().getRouteAt(position).requestSetVolume(progress);
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // TODO: Implement
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // TODO: Implement
+ }
+ };
+
+ public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) {
+ super(context, 0, objects);
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ v = LayoutInflater.from(getContext()).inflate(
+ R.layout.mr_media_route_controller_volume_item, null);
+ }
+ MediaRouter.RouteInfo route = getItem(position);
+ if (route != null) {
+ TextView textView = (TextView) v.findViewById(R.id.media_route_name);
+ textView.setText(route.getName());
+
+ SeekBar volumeSlider = (SeekBar) v.findViewById(R.id.media_route_volume_slider);
+ volumeSlider.setTag(position);
+ volumeSlider.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
+ }
+ return v;
+ }
+ }
+
private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> {
private int mBackgroundColor;
@@ -621,4 +706,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index a09879d..5f1b1ec 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -1458,6 +1458,15 @@
return mRoutes.get(index);
}
+ /**
+ * Returns the routes in this group
+ *
+ * @return The list of the routes in this group
+ */
+ public List<RouteInfo> getRoutes() {
+ return mRoutes;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder(super.toString());