170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell/* 270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * Copyright (C) 2012 The Android Open Source Project 370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * 470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * you may not use this file except in compliance with the License. 670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * You may obtain a copy of the License at 770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * 870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * 1070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * Unless required by applicable law or agreed to in writing, software 1170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 1270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * See the License for the specific language governing permissions and 1470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * limitations under the License. 1570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell */ 1670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 1770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellpackage com.android.internal.app; 1870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 1970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport com.android.internal.R; 2070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 2170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.app.Activity; 22d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powellimport android.app.Dialog; 2370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.app.DialogFragment; 2470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.app.MediaRouteActionProvider; 2570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.app.MediaRouteButton; 2670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.content.Context; 27d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powellimport android.graphics.drawable.Drawable; 28705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powellimport android.hardware.display.DisplayManager; 2970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.media.MediaRouter; 3070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.media.MediaRouter.RouteCategory; 3170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.media.MediaRouter.RouteGroup; 3270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.media.MediaRouter.RouteInfo; 3370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.os.Bundle; 3470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.text.TextUtils; 354599696591f745b3a546197d2ba7e5cfc5562484Adam Powellimport android.view.KeyEvent; 3670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.view.LayoutInflater; 3770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.view.View; 3870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.view.ViewGroup; 3970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.widget.AdapterView; 4070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.widget.BaseAdapter; 41b5e2af5919351486a385effe77409d2a91ae9c19Adam Powellimport android.widget.CheckBox; 42b5e2af5919351486a385effe77409d2a91ae9c19Adam Powellimport android.widget.Checkable; 43d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powellimport android.widget.ImageButton; 44d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powellimport android.widget.ImageView; 4570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.widget.ListView; 464599696591f745b3a546197d2ba7e5cfc5562484Adam Powellimport android.widget.SeekBar; 4770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.widget.TextView; 4870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 4970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport java.util.ArrayList; 50d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powellimport java.util.Collections; 51d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powellimport java.util.Comparator; 52b5e2af5919351486a385effe77409d2a91ae9c19Adam Powellimport java.util.List; 5370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 5470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell/** 5570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * This class implements the route chooser dialog for {@link MediaRouter}. 5670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * 5770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * @see MediaRouteButton 5870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * @see MediaRouteActionProvider 5970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell */ 6070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellpublic class MediaRouteChooserDialogFragment extends DialogFragment { 6170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private static final String TAG = "MediaRouteChooserDialogFragment"; 6270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public static final String FRAGMENT_TAG = "android:MediaRouteChooserDialogFragment"; 6370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 64d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell private static final int[] ITEM_LAYOUTS = new int[] { 65d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell R.layout.media_route_list_item_top_header, 66d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell R.layout.media_route_list_item_section_header, 67b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell R.layout.media_route_list_item, 68d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell R.layout.media_route_list_item_checkable, 69d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell R.layout.media_route_list_item_collapse_group 70d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell }; 71d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 7270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell MediaRouter mRouter; 73705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell DisplayManager mDisplayService; 7470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private int mRouteTypes; 7570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 76d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell private LayoutInflater mInflater; 7770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private LauncherListener mLauncherListener; 7870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private View.OnClickListener mExtendedSettingsListener; 7970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private RouteAdapter mAdapter; 8070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private ListView mListView; 814599696591f745b3a546197d2ba7e5cfc5562484Adam Powell private SeekBar mVolumeSlider; 824599696591f745b3a546197d2ba7e5cfc5562484Adam Powell private ImageView mVolumeIcon; 8370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 840d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell final RouteComparator mComparator = new RouteComparator(); 854599696591f745b3a546197d2ba7e5cfc5562484Adam Powell final MediaRouterCallback mCallback = new MediaRouterCallback(); 868e37a85bf3dc39519942698dc90a3951306b934bAdam Powell private boolean mIgnoreSliderVolumeChanges; 878e37a85bf3dc39519942698dc90a3951306b934bAdam Powell private boolean mIgnoreCallbackVolumeChanges; 88d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 8970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public MediaRouteChooserDialogFragment() { 9070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell setStyle(STYLE_NO_TITLE, R.style.Theme_DeviceDefault_Dialog); 9170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 9270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 9370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void setLauncherListener(LauncherListener listener) { 9470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mLauncherListener = listener; 9570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 9670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 9770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 9870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void onAttach(Activity activity) { 9970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell super.onAttach(activity); 10070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE); 101705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell mDisplayService = (DisplayManager) activity.getSystemService(Context.DISPLAY_SERVICE); 10270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 10370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 10470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 10570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void onDetach() { 10670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell super.onDetach(); 10770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (mLauncherListener != null) { 10870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mLauncherListener.onDetached(this); 10970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 11070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (mAdapter != null) { 11170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mAdapter = null; 11270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 113d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell mInflater = null; 1144599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mRouter.removeCallback(mCallback); 11570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mRouter = null; 11670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 11770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 11870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void setExtendedSettingsClickListener(View.OnClickListener listener) { 11970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mExtendedSettingsListener = listener; 12070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 12170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 12270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void setRouteTypes(int types) { 12370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mRouteTypes = types; 124705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell if ((mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_VIDEO) != 0 && mDisplayService == null) { 125705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell final Context activity = getActivity(); 126705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell if (activity != null) { 127705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell mDisplayService = (DisplayManager) activity.getSystemService( 128705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell Context.DISPLAY_SERVICE); 129705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell } 130705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell } else { 131705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell mDisplayService = null; 132705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell } 13370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 13470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 1354599696591f745b3a546197d2ba7e5cfc5562484Adam Powell void updateVolume() { 1361b4ea7eff50545f4673ca01b664e5edccc784688Adam Powell if (mRouter == null) return; 1371b4ea7eff50545f4673ca01b664e5edccc784688Adam Powell 1384599696591f745b3a546197d2ba7e5cfc5562484Adam Powell final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes); 1391cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell mVolumeIcon.setImageResource(selectedRoute == null || 1408e37a85bf3dc39519942698dc90a3951306b934bAdam Powell selectedRoute.getPlaybackType() == RouteInfo.PLAYBACK_TYPE_LOCAL ? 1414599696591f745b3a546197d2ba7e5cfc5562484Adam Powell R.drawable.ic_audio_vol : R.drawable.ic_media_route_on_holo_dark); 1424599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 1438e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mIgnoreSliderVolumeChanges = true; 1444599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 1451cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell if (selectedRoute == null || 1461cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell selectedRoute.getVolumeHandling() == RouteInfo.PLAYBACK_VOLUME_FIXED) { 1478e37a85bf3dc39519942698dc90a3951306b934bAdam Powell // Disable the slider and show it at max volume. 1488e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mVolumeSlider.setMax(1); 1498e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mVolumeSlider.setProgress(1); 1508e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mVolumeSlider.setEnabled(false); 1518e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } else { 1528e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mVolumeSlider.setEnabled(true); 1538e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mVolumeSlider.setMax(selectedRoute.getVolumeMax()); 1548e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mVolumeSlider.setProgress(selectedRoute.getVolume()); 1554599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 1568e37a85bf3dc39519942698dc90a3951306b934bAdam Powell 1578e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mIgnoreSliderVolumeChanges = false; 1584599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 1594599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 1604599696591f745b3a546197d2ba7e5cfc5562484Adam Powell void changeVolume(int newValue) { 1618e37a85bf3dc39519942698dc90a3951306b934bAdam Powell if (mIgnoreSliderVolumeChanges) return; 1624599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 1638e37a85bf3dc39519942698dc90a3951306b934bAdam Powell final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes); 1641cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell if (selectedRoute != null && 1651cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell selectedRoute.getVolumeHandling() == RouteInfo.PLAYBACK_VOLUME_VARIABLE) { 1664dd21c8e77c0d369ee835f50cba1701e76aa18c4Adam Powell final int maxVolume = selectedRoute.getVolumeMax(); 1674599696591f745b3a546197d2ba7e5cfc5562484Adam Powell newValue = Math.max(0, Math.min(newValue, maxVolume)); 1688e37a85bf3dc39519942698dc90a3951306b934bAdam Powell selectedRoute.requestSetVolume(newValue); 1694599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 1704599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 1714599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 17270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 17370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public View onCreateView(LayoutInflater inflater, ViewGroup container, 17470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell Bundle savedInstanceState) { 175d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell mInflater = inflater; 17670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final View layout = inflater.inflate(R.layout.media_route_chooser_layout, container, false); 1774599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 1784599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mVolumeIcon = (ImageView) layout.findViewById(R.id.volume_icon); 1794599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mVolumeSlider = (SeekBar) layout.findViewById(R.id.volume_slider); 1804599696591f745b3a546197d2ba7e5cfc5562484Adam Powell updateVolume(); 1814599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mVolumeSlider.setOnSeekBarChangeListener(new VolumeSliderChangeListener()); 18270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 18370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (mExtendedSettingsListener != null) { 1844599696591f745b3a546197d2ba7e5cfc5562484Adam Powell final View extendedSettingsButton = layout.findViewById(R.id.extended_settings); 18570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell extendedSettingsButton.setVisibility(View.VISIBLE); 18670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell extendedSettingsButton.setOnClickListener(mExtendedSettingsListener); 18770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 18870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 18970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final ListView list = (ListView) layout.findViewById(R.id.list); 190d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell list.setItemsCanFocus(true); 191d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell list.setAdapter(mAdapter = new RouteAdapter()); 19270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell list.setOnItemClickListener(mAdapter); 19370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 19470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mListView = list; 1954599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mRouter.addCallback(mRouteTypes, mCallback); 19670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 197b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mAdapter.scrollToSelectedItem(); 198d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 199b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return layout; 200d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 201d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 202d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 203d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public Dialog onCreateDialog(Bundle savedInstanceState) { 204d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell return new RouteChooserDialog(getActivity(), getTheme()); 205d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 206d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 207d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 208d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public void onResume() { 209d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell super.onResume(); 210705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell if (mDisplayService != null) { 211705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell mDisplayService.scanWifiDisplays(); 212705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell } 213d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 214d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 215d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell private static class ViewHolder { 216d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public TextView text1; 217d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public TextView text2; 218d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public ImageView icon; 219d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public ImageButton expandGroupButton; 220d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public RouteAdapter.ExpandGroupListener expandGroupListener; 221d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public int position; 222b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell public CheckBox check; 223d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 22470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 2250d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell private class RouteAdapter extends BaseAdapter implements ListView.OnItemClickListener { 22670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private static final int VIEW_TOP_HEADER = 0; 22770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private static final int VIEW_SECTION_HEADER = 1; 22870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private static final int VIEW_ROUTE = 2; 229b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private static final int VIEW_GROUPING_ROUTE = 3; 230b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private static final int VIEW_GROUPING_DONE = 4; 23170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 232b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private int mSelectedItemPosition = -1; 23370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private final ArrayList<Object> mItems = new ArrayList<Object>(); 23470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 235b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private RouteCategory mCategoryEditingGroups; 236b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private RouteGroup mEditingGroup; 237b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 238b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Temporary lists for manipulation 239b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private final ArrayList<RouteInfo> mCatRouteList = new ArrayList<RouteInfo>(); 240b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private final ArrayList<RouteInfo> mSortRouteList = new ArrayList<RouteInfo>(); 241b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 242b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private boolean mIgnoreUpdates; 243b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 244d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell RouteAdapter() { 24570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell update(); 24670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 24770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 24870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell void update() { 249b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell /* 250b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * This is kind of wacky, but our data sets are going to be 251b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * fairly small on average. Ideally we should be able to do some of this stuff 252b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * in-place instead. 253b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * 254b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * Basic idea: each entry in mItems represents an item in the list for quick access. 255b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * Entries can be a RouteCategory (section header), a RouteInfo with a category of 256b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * mCategoryEditingGroups (a flattened RouteInfo pulled out of its group, allowing 257b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * the user to change the group), 258b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell */ 259b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (mIgnoreUpdates) return; 260b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 26170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mItems.clear(); 26270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 26370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes); 264b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mSelectedItemPosition = -1; 26570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 266b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell List<RouteInfo> routes; 26770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final int catCount = mRouter.getCategoryCount(); 26870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell for (int i = 0; i < catCount; i++) { 26970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final RouteCategory cat = mRouter.getCategoryAt(i); 270b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell routes = cat.getRoutes(mCatRouteList); 27170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 272705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell if (!cat.isSystem()) { 273705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell mItems.add(cat); 274705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell } 27570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 276b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (cat == mCategoryEditingGroups) { 277b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell addGroupEditingCategoryRoutes(routes); 278b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else { 279b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell addSelectableRoutes(selectedRoute, routes); 28070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 281b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 282b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell routes.clear(); 28370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 28470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 28570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell notifyDataSetChanged(); 286b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (mListView != null && mSelectedItemPosition >= 0) { 28770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mListView.setItemChecked(mSelectedItemPosition, true); 28870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 28970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 29070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 291b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell void scrollToEditingGroup() { 292b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (mCategoryEditingGroups == null || mListView == null) return; 293b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 294b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell int pos = 0; 295b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell int bound = 0; 296b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final int itemCount = mItems.size(); 297b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell for (int i = 0; i < itemCount; i++) { 298b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final Object item = mItems.get(i); 299b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (item != null && item == mCategoryEditingGroups) { 300b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell bound = i; 301b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 302b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (item == null) { 303b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell pos = i; 304b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell break; // this is always below the category header; we can stop here. 305b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 306b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 307b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 308b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mListView.smoothScrollToPosition(pos, bound); 309b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 310b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 311b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell void scrollToSelectedItem() { 312b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (mListView == null || mSelectedItemPosition < 0) return; 313b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 314b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mListView.smoothScrollToPosition(mSelectedItemPosition); 315b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 316b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 317b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell void addSelectableRoutes(RouteInfo selectedRoute, List<RouteInfo> from) { 318b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final int routeCount = from.size(); 319b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell for (int j = 0; j < routeCount; j++) { 320b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteInfo info = from.get(j); 321b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (info == selectedRoute) { 322b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mSelectedItemPosition = mItems.size(); 323b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 324b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mItems.add(info); 325b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 326b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 327b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 328b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell void addGroupEditingCategoryRoutes(List<RouteInfo> from) { 329b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Unpack groups and flatten for presentation 330b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // mSortRouteList will always be empty here. 331b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final int topCount = from.size(); 332b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell for (int i = 0; i < topCount; i++) { 333b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteInfo route = from.get(i); 334b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteGroup group = route.getGroup(); 335b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (group == route) { 336b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // This is a group, unpack it. 337b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final int groupCount = group.getRouteCount(); 338b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell for (int j = 0; j < groupCount; j++) { 339b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteInfo innerRoute = group.getRouteAt(j); 340b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mSortRouteList.add(innerRoute); 341b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 342b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else { 343b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mSortRouteList.add(route); 344b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 345b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 346b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Sort by name. This will keep the route positions relatively stable even though they 347b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // will be repeatedly added and removed. 348b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell Collections.sort(mSortRouteList, mComparator); 349b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 350b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mItems.addAll(mSortRouteList); 351b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mSortRouteList.clear(); 352b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 353b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mItems.add(null); // Sentinel reserving space for the "done" button. 354b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 355b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 35670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 35770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public int getCount() { 35870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return mItems.size(); 35970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 36070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 36170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 36270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public int getViewTypeCount() { 363b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return 5; 36470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 36570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 36670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 36770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public int getItemViewType(int position) { 36870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final Object item = getItem(position); 36970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (item instanceof RouteCategory) { 37070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return position == 0 ? VIEW_TOP_HEADER : VIEW_SECTION_HEADER; 371b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else if (item == null) { 372b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return VIEW_GROUPING_DONE; 37370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } else { 374b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteInfo info = (RouteInfo) item; 375b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (info.getCategory() == mCategoryEditingGroups) { 376b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return VIEW_GROUPING_ROUTE; 377b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 37870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return VIEW_ROUTE; 37970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 38070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 38170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 38270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 38370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public boolean areAllItemsEnabled() { 38470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return false; 38570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 38670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 38770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 38870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public boolean isEnabled(int position) { 389b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell switch (getItemViewType(position)) { 390b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_ROUTE: 391705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell return ((RouteInfo) mItems.get(position)).isEnabled(); 392b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_GROUPING_ROUTE: 393b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_GROUPING_DONE: 394b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return true; 395b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell default: 396b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return false; 397b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 39870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 39970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 40070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 40170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public Object getItem(int position) { 40270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return mItems.get(position); 40370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 40470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 40570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 40670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public long getItemId(int position) { 40770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return position; 40870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 40970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 41070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 41170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public View getView(int position, View convertView, ViewGroup parent) { 41270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final int viewType = getItemViewType(position); 41370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 41470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell ViewHolder holder; 41570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (convertView == null) { 41670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell convertView = mInflater.inflate(ITEM_LAYOUTS[viewType], parent, false); 41770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder = new ViewHolder(); 418d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.position = position; 41970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder.text1 = (TextView) convertView.findViewById(R.id.text1); 42070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder.text2 = (TextView) convertView.findViewById(R.id.text2); 421d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.icon = (ImageView) convertView.findViewById(R.id.icon); 422b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell holder.check = (CheckBox) convertView.findViewById(R.id.check); 423d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.expandGroupButton = (ImageButton) convertView.findViewById( 424d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell R.id.expand_button); 425d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell if (holder.expandGroupButton != null) { 426d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.expandGroupListener = new ExpandGroupListener(); 427d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.expandGroupButton.setOnClickListener(holder.expandGroupListener); 428d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 429d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 430d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell final View fview = convertView; 431d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell final ListView list = (ListView) parent; 432d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell final ViewHolder fholder = holder; 433d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell convertView.setOnClickListener(new View.OnClickListener() { 434d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override public void onClick(View v) { 435d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell list.performItemClick(fview, fholder.position, 0); 436d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 437d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell }); 43870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell convertView.setTag(holder); 43970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } else { 44070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder = (ViewHolder) convertView.getTag(); 441d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.position = position; 44270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 44370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 444b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell switch (viewType) { 445b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_ROUTE: 446b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_GROUPING_ROUTE: 447b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell bindItemView(position, holder); 448b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell break; 449b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_SECTION_HEADER: 450b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell case VIEW_TOP_HEADER: 451b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell bindHeaderView(position, holder); 452b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell break; 45370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 45470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 455b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell convertView.setActivated(position == mSelectedItemPosition); 456705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell convertView.setEnabled(isEnabled(position)); 457b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 45870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return convertView; 45970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 46070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 46170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell void bindItemView(int position, ViewHolder holder) { 46270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell RouteInfo info = (RouteInfo) mItems.get(position); 4630d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell holder.text1.setText(info.getName(getActivity())); 46470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final CharSequence status = info.getStatus(); 46570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (TextUtils.isEmpty(status)) { 46670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder.text2.setVisibility(View.GONE); 46770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } else { 46870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder.text2.setVisibility(View.VISIBLE); 46970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell holder.text2.setText(status); 47070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 471d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell Drawable icon = info.getIconDrawable(); 472d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell if (icon != null) { 473d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // Make sure we have a fresh drawable where it doesn't matter if we mutate it 474d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell icon = icon.getConstantState().newDrawable(getResources()); 475d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 476d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.icon.setImageDrawable(icon); 477d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell holder.icon.setVisibility(icon != null ? View.VISIBLE : View.GONE); 478d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 479d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell RouteCategory cat = info.getCategory(); 480d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell boolean canGroup = false; 481b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (cat == mCategoryEditingGroups) { 482b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell RouteGroup group = info.getGroup(); 483b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell holder.check.setEnabled(group.getRouteCount() > 1); 484b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell holder.check.setChecked(group == mEditingGroup); 485b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else { 486b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (cat.isGroupable()) { 487b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteGroup group = (RouteGroup) info; 488b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell canGroup = group.getRouteCount() > 1 || 489b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell getItemViewType(position - 1) == VIEW_ROUTE || 490b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell (position < getCount() - 1 && 491b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell getItemViewType(position + 1) == VIEW_ROUTE); 492b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 493b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 494b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 495b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (holder.expandGroupButton != null) { 496b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell holder.expandGroupButton.setVisibility(canGroup ? View.VISIBLE : View.GONE); 497b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell holder.expandGroupListener.position = position; 498d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 49970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 50070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 50170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell void bindHeaderView(int position, ViewHolder holder) { 50270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell RouteCategory cat = (RouteCategory) mItems.get(position); 5030d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell holder.text1.setText(cat.getName(getActivity())); 50470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 50570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 50670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 50770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 508b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final int type = getItemViewType(position); 509b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (type == VIEW_SECTION_HEADER || type == VIEW_TOP_HEADER) { 51070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return; 511b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else if (type == VIEW_GROUPING_DONE) { 512b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell finishGrouping(); 513b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return; 514b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else { 515b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final Object item = getItem(position); 516b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (!(item instanceof RouteInfo)) { 517b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Oops. Stale event running around? Skip it. 518b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return; 519b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 520b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 521b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteInfo route = (RouteInfo) item; 522b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (type == VIEW_ROUTE) { 523b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mRouter.selectRouteInt(mRouteTypes, route); 524b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell dismiss(); 525b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else if (type == VIEW_GROUPING_ROUTE) { 526b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final Checkable c = (Checkable) view; 527b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final boolean wasChecked = c.isChecked(); 528b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 529b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mIgnoreUpdates = true; 530b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell RouteGroup oldGroup = route.getGroup(); 531b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (!wasChecked && oldGroup != mEditingGroup) { 532b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Assumption: in a groupable category oldGroup will never be null. 533b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (mRouter.getSelectedRoute(mRouteTypes) == oldGroup) { 534b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Old group was selected but is now empty. Select the group 535b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // we're manipulating since that's where the last route went. 536b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mRouter.selectRouteInt(mRouteTypes, mEditingGroup); 537b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 538b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell oldGroup.removeRoute(route); 539b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mEditingGroup.addRoute(route); 540b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell c.setChecked(true); 541b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } else if (wasChecked && mEditingGroup.getRouteCount() > 1) { 542b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mEditingGroup.removeRoute(route); 543b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 544b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // In a groupable category this will add 545b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // the route into its own new group. 546b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mRouter.addRouteInt(route); 547b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 548b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mIgnoreUpdates = false; 549b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell update(); 550b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 55170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 552b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 553b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 554b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell boolean isGrouping() { 555b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return mCategoryEditingGroups != null; 556b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 557b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 558b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell void finishGrouping() { 559b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mCategoryEditingGroups = null; 560b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mEditingGroup = null; 561b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell getDialog().setCanceledOnTouchOutside(true); 562b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell update(); 563b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell scrollToSelectedItem(); 56470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 56570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 566d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell class ExpandGroupListener implements View.OnClickListener { 567d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell int position; 568d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 569d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 570d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public void onClick(View v) { 571d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // Assumption: this is only available for the user to click if we're presenting 572d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // a groupable category, where every top-level route in the category is a group. 573b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell final RouteGroup group = (RouteGroup) getItem(position); 574b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mEditingGroup = group; 575b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mCategoryEditingGroups = group.getCategory(); 576b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell getDialog().setCanceledOnTouchOutside(false); 577b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mRouter.selectRouteInt(mRouteTypes, mEditingGroup); 578b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell update(); 579b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell scrollToEditingGroup(); 580d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 581d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 5824599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 5830d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 5844599696591f745b3a546197d2ba7e5cfc5562484Adam Powell class MediaRouterCallback extends MediaRouter.Callback { 5854599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 5864599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { 5874599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.update(); 5884599696591f745b3a546197d2ba7e5cfc5562484Adam Powell updateVolume(); 5894599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 5900d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 5914599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 5924599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { 5934599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.update(); 5944599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 5950d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 5964599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 5974599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteAdded(MediaRouter router, RouteInfo info) { 5984599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.update(); 5994599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6000d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 6014599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 6024599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteRemoved(MediaRouter router, RouteInfo info) { 6034599696591f745b3a546197d2ba7e5cfc5562484Adam Powell if (info == mAdapter.mEditingGroup) { 6044599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.finishGrouping(); 6050d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 6064599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.update(); 6074599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6080d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 6094599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 6104599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteChanged(MediaRouter router, RouteInfo info) { 6114599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.notifyDataSetChanged(); 6124599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6130d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 6144599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 6154599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteGrouped(MediaRouter router, RouteInfo info, 6164599696591f745b3a546197d2ba7e5cfc5562484Adam Powell RouteGroup group, int index) { 6174599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.update(); 6184599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6190d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 6204599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 6214599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) { 6224599696591f745b3a546197d2ba7e5cfc5562484Adam Powell mAdapter.update(); 6230d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 6248e37a85bf3dc39519942698dc90a3951306b934bAdam Powell 6258e37a85bf3dc39519942698dc90a3951306b934bAdam Powell @Override 6268e37a85bf3dc39519942698dc90a3951306b934bAdam Powell public void onRouteVolumeChanged(MediaRouter router, RouteInfo info) { 6278e37a85bf3dc39519942698dc90a3951306b934bAdam Powell if (!mIgnoreCallbackVolumeChanges) { 6288e37a85bf3dc39519942698dc90a3951306b934bAdam Powell updateVolume(); 6298e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } 6308e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } 63170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 63270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 6330d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell class RouteComparator implements Comparator<RouteInfo> { 634d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 635d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public int compare(RouteInfo lhs, RouteInfo rhs) { 6360d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return lhs.getName(getActivity()).toString() 6370d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell .compareTo(rhs.getName(getActivity()).toString()); 638d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 639d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 640d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 641d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell class RouteChooserDialog extends Dialog { 642d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public RouteChooserDialog(Context context, int theme) { 643d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell super(context, theme); 644d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 645d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 646d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 647d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public void onBackPressed() { 648b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (mAdapter != null && mAdapter.isGrouping()) { 649b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mAdapter.finishGrouping(); 650d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } else { 651d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell super.onBackPressed(); 652d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 65370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 6544599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 6554599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public boolean onKeyDown(int keyCode, KeyEvent event) { 6564599696591f745b3a546197d2ba7e5cfc5562484Adam Powell if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mVolumeSlider.isEnabled()) { 6571cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes); 6581cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell if (selectedRoute != null) { 6591cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell selectedRoute.requestUpdateVolume(-1); 6601cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell return true; 6611cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell } 6624599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mVolumeSlider.isEnabled()) { 6631cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes); 6641cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell if (selectedRoute != null) { 6651cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell mRouter.getSelectedRoute(mRouteTypes).requestUpdateVolume(1); 6661cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell return true; 6671cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell } 6684599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6691cf2ca83584a4cf0aa3ded787bd191b9a60e3521Adam Powell return super.onKeyDown(keyCode, event); 6704599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6718e37a85bf3dc39519942698dc90a3951306b934bAdam Powell 6728e37a85bf3dc39519942698dc90a3951306b934bAdam Powell public boolean onKeyUp(int keyCode, KeyEvent event) { 6738e37a85bf3dc39519942698dc90a3951306b934bAdam Powell if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mVolumeSlider.isEnabled()) { 6748e37a85bf3dc39519942698dc90a3951306b934bAdam Powell return true; 6758e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mVolumeSlider.isEnabled()) { 6768e37a85bf3dc39519942698dc90a3951306b934bAdam Powell return true; 6778e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } else { 6788e37a85bf3dc39519942698dc90a3951306b934bAdam Powell return super.onKeyUp(keyCode, event); 6798e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } 6808e37a85bf3dc39519942698dc90a3951306b934bAdam Powell } 6814599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6824599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 6834599696591f745b3a546197d2ba7e5cfc5562484Adam Powell /** 6844599696591f745b3a546197d2ba7e5cfc5562484Adam Powell * Implemented by the MediaRouteButton that launched this dialog 6854599696591f745b3a546197d2ba7e5cfc5562484Adam Powell */ 6864599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public interface LauncherListener { 6874599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onDetached(MediaRouteChooserDialogFragment detachedFragment); 6884599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6894599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 6904599696591f745b3a546197d2ba7e5cfc5562484Adam Powell class VolumeSliderChangeListener implements SeekBar.OnSeekBarChangeListener { 6914599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 6924599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 6934599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 6944599696591f745b3a546197d2ba7e5cfc5562484Adam Powell changeVolume(progress); 6954599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 6964599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 6974599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 6984599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onStartTrackingTouch(SeekBar seekBar) { 6998e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mIgnoreCallbackVolumeChanges = true; 7004599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 7014599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 7024599696591f745b3a546197d2ba7e5cfc5562484Adam Powell @Override 7034599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public void onStopTrackingTouch(SeekBar seekBar) { 7048e37a85bf3dc39519942698dc90a3951306b934bAdam Powell mIgnoreCallbackVolumeChanges = false; 7058e37a85bf3dc39519942698dc90a3951306b934bAdam Powell updateVolume(); 7064599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 7074599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 70870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 70970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell} 710