diff options
author | Adam Powell <adamp@google.com> | 2012-06-16 14:58:39 -0700 |
---|---|---|
committer | Adam Powell <adamp@google.com> | 2012-06-16 17:21:57 -0700 |
commit | 4599696591f745b3a546197d2ba7e5cfc5562484 (patch) | |
tree | deb99136c03e9100fa6727fe8b7b23dcf7f21c8c /core | |
parent | 39d5c6172503620ac3761148adac5fd7fa20d02d (diff) | |
download | frameworks_base-4599696591f745b3a546197d2ba7e5cfc5562484.zip frameworks_base-4599696591f745b3a546197d2ba7e5cfc5562484.tar.gz frameworks_base-4599696591f745b3a546197d2ba7e5cfc5562484.tar.bz2 |
Volume control in MediaRouter dialogs
MediaRouter dialogs now intercept the volume keys for altering the
current volume. The status icon indicates if the slider/buttons are
currently controlling the local device volume or a remote device's
volume.
Group volume for user routes is handled by using the
RemoteControlClient supplied by the first route in the group.
Change-Id: I40a0d054847ed5acce7a4c3b669487841b4dca15
Diffstat (limited to 'core')
-rw-r--r-- | core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java | 188 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 3 |
2 files changed, 144 insertions, 47 deletions
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java index e1a48be..b615b9c 100644 --- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java +++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java @@ -25,12 +25,16 @@ import android.app.MediaRouteActionProvider; import android.app.MediaRouteButton; import android.content.Context; import android.graphics.drawable.Drawable; +import android.media.AudioManager; import android.media.MediaRouter; import android.media.MediaRouter.RouteCategory; import android.media.MediaRouter.RouteGroup; import android.media.MediaRouter.RouteInfo; +import android.media.MediaRouter.UserRouteInfo; +import android.media.RemoteControlClient; import android.os.Bundle; import android.text.TextUtils; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -41,6 +45,7 @@ import android.widget.Checkable; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; +import android.widget.SeekBar; import android.widget.TextView; import java.util.ArrayList; @@ -67,6 +72,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { }; MediaRouter mRouter; + AudioManager mAudio; private int mRouteTypes; private LayoutInflater mInflater; @@ -74,8 +80,12 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { private View.OnClickListener mExtendedSettingsListener; private RouteAdapter mAdapter; private ListView mListView; + private SeekBar mVolumeSlider; + private ImageView mVolumeIcon; final RouteComparator mComparator = new RouteComparator(); + final MediaRouterCallback mCallback = new MediaRouterCallback(); + private boolean mIgnoreVolumeChanges; public MediaRouteChooserDialogFragment() { setStyle(STYLE_NO_TITLE, R.style.Theme_DeviceDefault_Dialog); @@ -89,6 +99,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { public void onAttach(Activity activity) { super.onAttach(activity); mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE); + mAudio = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE); } @Override @@ -98,20 +109,13 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { mLauncherListener.onDetached(this); } if (mAdapter != null) { - mRouter.removeCallback(mAdapter.mCallback); mAdapter = null; } mInflater = null; + mRouter.removeCallback(mCallback); mRouter = null; } - /** - * Implemented by the MediaRouteButton that launched this dialog - */ - public interface LauncherListener { - public void onDetached(MediaRouteChooserDialogFragment detachedFragment); - } - public void setExtendedSettingsClickListener(View.OnClickListener listener) { mExtendedSettingsListener = listener; } @@ -120,14 +124,70 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { mRouteTypes = types; } + void updateVolume() { + final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes); + final boolean defaultAudioSelected = selectedRoute == mRouter.getSystemAudioRoute(); + final boolean selectedSystemRoute = + selectedRoute.getCategory() == mRouter.getSystemAudioCategory(); + mVolumeIcon.setImageResource(defaultAudioSelected ? + R.drawable.ic_audio_vol : R.drawable.ic_media_route_on_holo_dark); + + mIgnoreVolumeChanges = true; + mVolumeSlider.setEnabled(true); + if (selectedSystemRoute) { + // Use the standard media audio stream + mVolumeSlider.setMax(mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC)); + mVolumeSlider.setProgress(mAudio.getStreamVolume(AudioManager.STREAM_MUSIC)); + } else { + final RouteInfo firstSelected; + if (selectedRoute instanceof RouteGroup) { + firstSelected = ((RouteGroup) selectedRoute).getRouteAt(0); + } else { + firstSelected = selectedRoute; + } + + RemoteControlClient rcc = null; + if (firstSelected instanceof UserRouteInfo) { + rcc = ((UserRouteInfo) firstSelected).getRemoteControlClient(); + } + + if (rcc == null) { + // No RemoteControlClient? Assume volume can't be controlled. + // Disable the slider and show it at max volume. + mVolumeSlider.setMax(1); + mVolumeSlider.setProgress(1); + mVolumeSlider.setEnabled(false); + } else { + // TODO: Connect this to the remote control volume + } + } + mIgnoreVolumeChanges = false; + } + + void changeVolume(int newValue) { + if (mIgnoreVolumeChanges) return; + + RouteCategory selectedCategory = mRouter.getSelectedRoute(mRouteTypes).getCategory(); + if (selectedCategory == mRouter.getSystemAudioCategory()) { + final int maxVolume = mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + newValue = Math.max(0, Math.min(newValue, maxVolume)); + mAudio.setStreamVolume(AudioManager.STREAM_MUSIC, newValue, 0); + } + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mInflater = inflater; final View layout = inflater.inflate(R.layout.media_route_chooser_layout, container, false); - final View extendedSettingsButton = layout.findViewById(R.id.extended_settings); + + mVolumeIcon = (ImageView) layout.findViewById(R.id.volume_icon); + mVolumeSlider = (SeekBar) layout.findViewById(R.id.volume_slider); + updateVolume(); + mVolumeSlider.setOnSeekBarChangeListener(new VolumeSliderChangeListener()); if (mExtendedSettingsListener != null) { + final View extendedSettingsButton = layout.findViewById(R.id.extended_settings); extendedSettingsButton.setVisibility(View.VISIBLE); extendedSettingsButton.setOnClickListener(mExtendedSettingsListener); } @@ -138,7 +198,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { list.setOnItemClickListener(mAdapter); mListView = list; - mRouter.addCallback(mRouteTypes, mAdapter.mCallback); + mRouter.addCallback(mRouteTypes, mCallback); mAdapter.scrollToSelectedItem(); @@ -174,7 +234,6 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { private int mSelectedItemPosition = -1; private final ArrayList<Object> mItems = new ArrayList<Object>(); - final MediaRouterCallback mCallback = new MediaRouterCallback(); private RouteCategory mCategoryEditingGroups; private RouteGroup mEditingGroup; @@ -443,10 +502,6 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { holder.text1.setText(cat.getName(getActivity())); } - public int getSelectedRoutePosition() { - return mSelectedItemPosition; - } - @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final int type = getItemViewType(position); @@ -523,46 +578,49 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { scrollToEditingGroup(); } } + } - class MediaRouterCallback extends MediaRouter.Callback { - @Override - public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { - update(); - } + class MediaRouterCallback extends MediaRouter.Callback { + @Override + public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { + mAdapter.update(); + updateVolume(); + } - @Override - public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { - update(); - } + @Override + public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { + mAdapter.update(); + } - @Override - public void onRouteAdded(MediaRouter router, RouteInfo info) { - update(); - } + @Override + public void onRouteAdded(MediaRouter router, RouteInfo info) { + mAdapter.update(); + updateVolume(); + } - @Override - public void onRouteRemoved(MediaRouter router, RouteInfo info) { - if (info == mEditingGroup) { - finishGrouping(); - } - update(); + @Override + public void onRouteRemoved(MediaRouter router, RouteInfo info) { + if (info == mAdapter.mEditingGroup) { + mAdapter.finishGrouping(); } + mAdapter.update(); + updateVolume(); + } - @Override - public void onRouteChanged(MediaRouter router, RouteInfo info) { - notifyDataSetChanged(); - } + @Override + public void onRouteChanged(MediaRouter router, RouteInfo info) { + mAdapter.notifyDataSetChanged(); + } - @Override - public void onRouteGrouped(MediaRouter router, RouteInfo info, - RouteGroup group, int index) { - update(); - } + @Override + public void onRouteGrouped(MediaRouter router, RouteInfo info, + RouteGroup group, int index) { + mAdapter.update(); + } - @Override - public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) { - update(); - } + @Override + public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) { + mAdapter.update(); } } @@ -587,5 +645,41 @@ public class MediaRouteChooserDialogFragment extends DialogFragment { super.onBackPressed(); } } + + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mVolumeSlider.isEnabled()) { + mVolumeSlider.incrementProgressBy(-1); + return true; + } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mVolumeSlider.isEnabled()) { + mVolumeSlider.incrementProgressBy(1); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + } + + /** + * Implemented by the MediaRouteButton that launched this dialog + */ + public interface LauncherListener { + public void onDetached(MediaRouteChooserDialogFragment detachedFragment); + } + + class VolumeSliderChangeListener implements SeekBar.OnSeekBarChangeListener { + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + changeVolume(progress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + } } diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index a6f2f49..82ce655 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1168,6 +1168,9 @@ <java-symbol type="attr" name="externalRouteEnabledDrawable" /> <java-symbol type="id" name="extended_settings" /> <java-symbol type="id" name="check" /> + <java-symbol type="id" name="volume_slider" /> + <java-symbol type="id" name="volume_icon" /> + <java-symbol type="drawable" name="ic_media_route_on_holo_dark" /> <java-symbol type="layout" name="media_route_chooser_layout" /> <java-symbol type="layout" name="media_route_list_item_top_header" /> <java-symbol type="layout" name="media_route_list_item_section_header" /> |